Python3+Selenium2完整的自动化测试实现之旅(六):Python单元测试模块Unittest运用

news2025/1/10 22:15:23

目录

 引言

一、Unittest单元测试框架简介

 二、首次使用Unittest模块

三、Unittest模块批量加载和管理用例

写在最后


引言

这篇文章讲述的是Python3+Selenium2自动化测试实现之旅的第六篇,主要是介绍如何运用Python单元测试模块Unittest进行测试。

我个人觉得这篇文章非常有用,因为它为我们提供了一个简单而强大的工具来确保我们编写的代码能够正常运行。

如果你还没尝试过使用Unittest,那么这篇文章一定会给你带来不少帮助和启发。

一、Unittest单元测试框架简介

     Unitest是Python下的一个单元测试模块,是Python标准库模块之一,安装完Python后就可以直接import该模块,能在单元测试下编写具体的测试用例脚本,并调用模块封装好的方法,实现测试用例的执行、测试场景的恢复,甚至能批量采集测试用例脚本、批量运行测试脚本用例、控制执行顺序等,依托于Unittest模块,可以高效的组织测试用例编写、测试用例脚本的采集管理以及脚本运行的执行控制等。Unitest单元测试框架主要包含如下几个重要的逻辑单元:

1.测试固件(test fixture)


      一个测试固件包括两部分,执行测试代码的前置条件和测试结束之后的场景恢复,这两部分一般用函数setUp()和tearDown()表示。简单说,就是平时手工测试一条具体的测试用例时,测试的前置环境和测试结束后的环境恢复。

2.测试用例(test case)


       unittest中管理的最小单元是测试用例,就是一个测试用例,包括具体测试业务的函数或者方法,只是该test case 必须是以test开头的函数。unittest会自动化识别test开头的函数是测试代码,如果你写的函数不是test开头,unittest是不会执行这个函数里面的脚本,这个千万要记住,所有的测试函数都要test开头,记住是小写的哦。

3.测试套件 (test suite)


       就是很多测试用例的集合,一个测试套件可以随意管理多个测试用例,该部分用来实现诸多测试用例的采集,形成一套测试用例集。

4.测试执行器 (test runner)


       test runner是一个用来执行加载测试用例,并执行用例,且提供测试输出的一个逻辑单元。test runner可以加载test case或者test suite进行执行测试任务,并能控制用例集的执行顺序等。

从Unitest单元测试框架的基本逻辑单元设计来看,很明显可以看到它包含了用例的整个生命周期:用例的前置条件、用例的编写、用例的采集、用例的执行以及测试执行后的场景恢复。

 二、首次使用Unittest模块

下面以打开百度,进行搜索,创建一个名为baidu_search.py的脚本文件,编写百度搜索分别python2和python3的测试用例,代码如下:

'''
  Code description:
  Create time:
  Developer:
'''
# -*- coding: utf-8 -*-
import time
import unittest
from selenium import webdriver
class Search(unittest.TestCase):
    def setUp(self):
        """
        测试前置条件,这里要搜索的话就是先得打开百度网站啦
        """
        self.driver = webdriver.Ie()
        self.driver.maximize_window()
        self.driver.implicitly_wait(5)
        self.driver.get("https://www.baidu.com")
    def tearDown():
        """
        测试结束后环境复原,这里就是浏览器关闭退出
        """
        self.driver.quit()
    def test_search1(self):
        """
        这里一定要test开头,把测试逻辑代码封装到一个test开头的方法里。
        """
        self.driver.find_element_by_id('kw').send_keys('python2')
        self.driver.find_element_by_id('su').click()
        time.sleep(1)
        try:
            assert 'python2' in self.driver.title
            print('检索python2完成')
        except Exception as e:
            print('检索失败', format(e))
    def test_search2(self):
        """
        这里一定要test开头,把测试逻辑代码封装到一个test开头的方法里。
        """
        self.driver.find_element_by_id('kw').send_keys('python3')
        self.driver.find_element_by_id('su').click()
        time.sleep(1)
        try:
            assert 'python3' in self.driver.title
            print('检索python3完成')
        except Exception as e:
            print('检索失败', format(e))
if __name__ == '__main__':
    unittest.main()

 在PyCharm中运行上面代码,我们会发现浏览器打开关闭了两次,分别检索了python2关闭浏览器,然后检索python3关闭浏览器。

这个效果显然不是我们希望的,我们希望检索完python2后,不用关闭浏览器继续检索python3,Unittest有相关的设置吗?答案是肯定的,我们对以上代码做下调整修改,注意对比不同的地方,然后运行就达到我们想要的效果

'''
  Code description:
  Create time:
  Developer:
'''
# -*- coding: utf-8 -*-
import time
import unittest
from selenium import webdriver
class Search(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        """
        测试前置条件,这里要搜索的话就是先得打开百度网站啦
        """
        cls.driver = webdriver.Ie()
        cls.driver.maximize_window()
        cls.driver.implicitly_wait(5)
        cls.driver.get("https://www.baidu.com")
    @classmethod
    def tearDownClass(cls):
        """
        测试结束后环境复原,这里就是浏览器关闭退出
        """
        cls.driver.quit()
    def test_search1(self):
        """
        这里一定要test开头,把测试逻辑代码封装到一个test开头的方法里。
        """
        self.driver.find_element_by_id('kw').send_keys('python2')
        self.driver.find_element_by_id('su').click()
        time.sleep(1)
        try:
            assert 'python2' in self.driver.title
            print('检索python2完成')
        except Exception as e:
            print('检索失败', format(e))
    def test_search2(self):
        """
        这里一定要test开头,把测试逻辑代码封装到一个test开头的方法里。
        """
        self.driver.find_element_by_id('kw').clear()              # 清空之前输入的python2
        self.driver.find_element_by_id('kw').send_keys('python3')
        self.driver.find_element_by_id('su').click()
        time.sleep(1)
        try:
            assert 'python3' in self.driver.title
            print('检索python3完成')
        except Exception as e:
            print('检索失败', format(e))
if __name__ == '__main__':
    unittest.main()

、Unittest模块批量加载和管理用例

      以上对于Unittest框架,我们好像只用到了测试固件、测试用例两个逻辑单元的使用,接下来问题又来了:我们日常项目中的测试案例肯定不止一个,当案例越来越多时我们如何管理这些批量案例?如何保证案例不重复?如果案例非常多(成百上千,甚至更多)时如何保证案例执行的效率?

来看一下在unittest框架中如何管理批量用例:

手动添加采集指定的测试用例集用法:先在PyCharm中新建如下项目层级:

其中baidu_search1还是上面调整修改过的代码,然后编辑run_case.py文件,代码如下:

'''
  Code description: 执行add 的测试用例集
  Create time:
  Developer:
'''
# -*- coding: utf-8 -*-
from testcase.sreach.baidu_sreach1 import Search    # 将baidu_sreach.py模块导入进来
import unittest
 
suite = unittest.TestSuite()        # 构造测试用例集
# suite.addTest(Search("test_search1"))
suite.addTest(Search("test_search2"))     # 分别添加baidu_sreach1.py中的两个检索的测试用例
 
if __name__ == '__main__':
    runner = unittest.TextTestRunner()   # 实例化runner
    runner.run(suite)                   #执行测试

 这样运行run_case.py,就只执行了在百度中搜索python3这条用例,手动添加指定用例到测试套件的方法是addTest(),但是很多时候我们写了很多测试脚本文件,每个脚本中有多个test,,如果还是使用addTest()方法就不行了,我们希望能获取所有的测试集,并全部执行。然后编辑run_all_case.py文件,编写如下代码:

'''
  Code description: TestLoader所有测试case
  Create time:
  Developer:
'''
# -*- coding: utf-8 -*-
import time
import os.path
import unittest
from selenium import webdriver
class Search(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        """
        测试前置条件,这里要搜索的话就是先得打开百度网站啦
        """
        cls.driver = webdriver.Ie()
        cls.driver.maximize_window()
        cls.driver.implicitly_wait(5)
        cls.driver.get("https://www.baidu.com")
    @classmethod
    def tearDownClass(cls):
        """
        测试结束后环境复原,这里就是浏览器关闭退出
        """
        cls.driver.quit()
    def test_search1(self):
        """
        这里一定要test开头,把测试逻辑代码封装到一个test开头的方法里。
        """
        self.driver.find_element_by_id('kw').send_keys('python2')
        self.driver.find_element_by_id('su').click()
        time.sleep(1)
        try:
            assert 'python2' in self.driver.title
            print('检索python2完成')
        except Exception as e:
            print('检索失败', format(e))
    def test_search2(self):
        """
        这里一定要test开头,把测试逻辑代码封装到一个test开头的方法里。
        """
        self.driver.find_element_by_id('kw').clear()              # 清空之前输入的python2
        self.driver.find_element_by_id('kw').send_keys('python3')
        self.driver.find_element_by_id('su').click()
        time.sleep(1)
        try:
            assert 'python3' in self.driver.title
            print('检索python3完成')
        except Exception as e:
            print('检索失败', format(e))
    def test_search3(self):
        """
        这里一定要test开头,把测试逻辑代码封装到一个test开头的方法里。
        """
        self.driver.find_element_by_id('kw').clear()  # 清空之前输入的python3
        self.driver.find_element_by_id('kw').send_keys('hello world')
        self.driver.find_element_by_id('su').click()
        time.sleep(1)
        try:
            assert 'hello world' in self.driver.title
            print('检索hello world完成')
        except Exception as e:
            print('检索失败', format(e))
 
case_path = os.path.join(os.getcwd())              #  在当前目录中采集测试用例
print(case_path)
all_case = unittest.defaultTestLoader.discover(case_path, pattern="test*.py", top_level_dir=None)  # 采集所有test开头的测试用例
print(all_case)
 
if __name__ == '__main__':
 
    runner = unittest.TextTestRunner()  # 实例化runner
    runner.run(all_case)  # 执行测试

获取所有的测试用例集使用的是discover()方法,在PyCharm中运行该脚本就如下:

 以上就完成了在Python Unittest单元测试框架下编写测试用例脚本,并使用其提供的多种方法来批量管理测试用例集并并执行。

 感谢您的阅读,若有不足之处,欢迎指教,共同学习、共同进步。 如您喜欢,麻烦推荐一下;如您有新想法,欢迎提出。

写在最后

这篇贴子到这里就结束了,最后,希望看这篇帖子的朋友能够有所收获。

都到这了记得三连支持一下吧。

 完整版文档下载方式:

这些资料,对于从事【软件测试】等相关工作的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享。

在评论区和我互动交流或者私❤我【软件测试学习】领取即可,拿走不谢。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/627749.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【新版】系统架构设计师 - 数学与经济管理

个人总结,仅供参考,欢迎加好友一起讨论 文章目录 架构 - 数学与经济管理考点摘要最小生成树最短路径网络与最大流量线性规划动态规划预测 - 博弈论预测 - 状态转移矩阵决策 - 不确定型决策决策 - 决策树排队论数学建模数学建模 - 模型分析数学建模 - 模型…

什么是 tokens,ChatGPT里面的Tokens如何计数?

什么是 tokens,ChatGPT里面的Tokens如何计数? 什么是 tokens? Tokens 可以被认为是词语的片段。在 API 处理提示之前,输入会被分解成 tokens。这些 tokens 并不会精确地在单词的开始或结束处切分 - tokens 可以包含尾随的空格甚…

【PCIE体系结构十三】LTSSM

👉个人主页:highman110 👉作者简介:一名硬件工程师,持续学习,不断记录,保持思考,输出干货内容 参考书籍:《PCI.EXPRESS系统体系结构标准教材 Mindshare》 目录 概览…

恭喜!电影《觅渡》入围上海电影节第20届传媒单元大奖

生生不息,念廿不忘; 传媒荣誉,开启在即! 第20届电影频道传媒关注单元 即将迎来20周年 一共有18部影片 入围竞逐年度传媒荣誉 6月16日晚 CCTV-6电影频道、 电影频道融媒体 将现场直播 揭晓传媒荣誉名单 电影《觅渡》入围上…

为你的项目配置日志(AOP+logback)

文章目录 1、导入依赖2、配置文件logback-spring.xml3、使用AOP做日志3.1、自定义注解3.2、自定义aop切面 4、在controller方法上添加注解5、使用Slf4j6、最终参考效果 之前看过logback的配置方法,今天整理spring的知识的时候,又看到了aop,想…

Linux之系统信息和性能监测

一、前言 安装完一套linux操作系统我们首先得知道系统都有哪些信息,比如安装内存多少、磁盘多大、什么版本、多少核CPU等等,因此熟悉常用的查看系统信息的指令还是很有必要的。 此文档主要对已安装的linux系统的属性有个初步的认识,介绍系统…

一起从根上学习Swoole

一起从根上学习Swoole Swoole,这个名字已经不再是一个简单的扩展库,而是一种让PHP开发者们心驰神往的技术。它是一个基于事件驱动的异步网络通信框架,能够让PHP应用程序在高并发环境下实现卓越的性能表现。现在,你也可以像一名高…

ROS:DWA算法解析、move_base导航包DWA源码解析

一.整体思路 1.基于速度控制运动模型 假设没有噪声,控制时间间隔为内机器人速度v和角速度w保持不变,则机器人围绕半径为r的圆周运动。 其中,。 根据v 和w即可预测出下一次机器人位姿(x、y、),根据此也可以…

毕业4年,克服三次瓶颈,最终成功从字节跳动成功跳到阿里!经验分享

介绍下自己的测试历程吧,普通本科,毕业4年, 去年成功转型测试开发,总结一下测试心得。 平凡的大学生活 我大学期间属于并没有什么出众的,按部就班,老实办事的那种学生,我导师对我们那届的学生…

iOS 17(SwiftUI 5.0)带来的图表(Charts)新类型:“大饼”与“甜甜圈”

概览 WWDC 2023 为我们带来了 iOS 17,也为我们带来了 SwiftUI 5.0。 在 SwiftUI 新版中,Apple 增加了很多重磅功能,也对原有功能做了大幅度升级。 对于 Charts 框架, 新增了饼图(Pie)类型并且加入了图…

容器镜像差异分析工具 container-diff

概述 container-diff 是google出的一个容器差异比较工具,通过这个工具可以比较两个镜像之间存在的文件差异、RPM包差异、apt包差异、pip包差异和node包差异。 container-diff 也包括了对单个镜像分析能力,像文件分析啊、apt包、rpm包分析等功能。 在日常…

Python爬虫——怎么搭建和维护一个本地IP池

目录 背景 一、什么是本地代理IP池 二、代理IP池功能架构图 三、各个组件功能说明及示例代码 1. IP池管理器 2. 代理IP获取器 3. IP质量检测器 4、数据存储器 5、API接口层 6、应用程序 总结 背景 在我们进行爬虫工作时,经常需要使用代理IP。大多数代理…

unity2d粒子特效

文章目录 前言先看效果一、2d平台雨1. 配置2. 图片素材3. 最终效果 二、脚步灰尘效果1. 配置2. 代码调用3. 效果 三、受伤血液四溅效果1. 配置2. 效果 待续四、工程源码五、参考六、完毕 前言 我只是我抽空写了一些简单的2d粒子特效,后面如果接触新的不错的2d特效&a…

Maven 安装

一. 下载 apache官网下载 Maven:Maven – Download Apache Maven ,根据需要下载不同压缩包。 将压缩包进行解压,最好放在无中文目录下解压。 二. 安装 三. 配置 1. 配置maven本地仓库 打开解压后的文件夹,找到conf文件夹&#…

银行vr元宇宙全景虚拟展馆提供更加真实、立体、高效的数字资产交易场景

为了贯彻国家普惠金融政策,使金融如无惠及广大群体,宇宙技术在金融行业中的应用将进一步提升金融消费体验感觉和金融管理水平。打造元宇宙金融服务平台,构建虚实结构的金融服务世界,培育和管理好数字机器人员工队伍,提升金融业务各…

postman登录鉴权之接口测试

一.背景 在做接口测试的时候,有些接口向后台请求数据的时候,是需要用户在登录情况下才有数据返回。 以电商平台为例,用户的个人中心,用户的订单列表,用户的支付信息等等,所有用户维度的数据都是需要登录态…

Django - 页面静态化和crontab定时任务(二)

一. 前言 一个网页会有很多数据是不需要经常变动的,比如说首页,变动频率低而访问量大,我们可以把它静态化,这样就不需要每次有请求都要查询数据库再返回,可以减少服务器压力 我们可以使用Django的模板渲染功能完成页面…

app反编译查看是否被混淆或者混淆是否成功

同时打 debug包和release包,生成的目录在build->output文件夹下面 一般直接运行的apk 包是在build/intermediates/apk/debug 目录下 方法1:Android studio 安装插件jadx build成apk 后 直接选中 右键 在Jadx GUI中反编译 就可以查看代码 方法2&…

距离保护的影响因素

1、汲出电流和助增电流的影响 当保护安装处与故障点之间有分支电源时,如图所示,分支电源将向故障点K送短路电流ICB,使流过故障线路的电流IBKIAB ICB,大于实际流过保护1的电流IAB,所以ICB称作助增电流。 由于助增电流的…

第一章操作系统引论

目录 一、熟悉的操作系统 二、计算机系统的层次结构 三、操作系统的概念 四、操作系统的功能 4.1 系统资源的管理者 4.2 向上层提供方便易用的服务 4.2.1 GUI:图形化用户接口(Graphical UserInterface) 4.2.2 命令接口 4.2.3 程序接…