当前位置: 首页 > news >正文

Python学习3.0使用Unittest框架运行测试用例

使用Unittest框架运行测试用例

  • Unittest 框架
    • 1.Unittest 单元测试框架的组成
    • 2.TestCase 编写测试用例
    • 3.跳过要执行的测试用例
    • 4.引入TestFixture
      • @classmethod 装饰器
    • 5.Unittest的断言
    • 6.TestSuite和TestRunner(不支持并发结果合并)
      • 1)运行时自动触发unittest.main()逻辑,需修改 PyCharm 配置
      • 2)TestSuite添加测试用例的3种方式
      • 3)TestLoader添加测试用例
    • 7. 生成测试报告TestResult
      • 1)TextTestRunner生成的文本格式报告
      • 2)HTMLTestRunner_PY3生成的报告(好用,需安装)
    • 8. 框架进行并发(unittest不适合,使用pytest)

Unittest 框架


作用: 管理测试用例、断言、生成测试报告

1.Unittest 单元测试框架的组成


Unittest 组成部分作用
test fixture测试固定组件,unittest框架中,一些有固定用法的组件
test case测试用例,被执行测试的最小单元
test suite测试套件,它是一个用例集,用来汇总应该一起执行的测试用例
test runner测试运行器,它是一个设计测试执行方式的元件,主要对用户提供了输出结果的展现方式。它可以用图标、文本、html等方式来展现测试结果

2.TestCase 编写测试用例

  • 简单执行一个用例 import unittest

Unittest运行的测试用例,必须是继承了 unittest.TestCase 的方法,并且这个方法默认以 test 开头

默认执行顺序是,在test以后,按照ASCII码比对大小

---- 导入包 unittest
import unittest----   创建继承  unittest.TestCase  的类
class FirstDemo(unittest.TestCase):   ------- 固定写法,必须继承def test01(self):print("执行用例一")def test02(self):print("执行用例二")if __name__ == '__main__':unittest.main()      ----- 固定写法,调用底层逻辑main执行用例,查看下图

在这里插入图片描述

  • 执行结果(左侧为执行情况,右侧为执行输出和执行时间)

在这里插入图片描述

  • 若想更换执行时的测试运行程序

在这里插入图片描述

3.跳过要执行的测试用例

方法:使用装饰器 @unitest.skip(“备注”)

  • 案例
---- 导入包 unittest
import unittest----   创建继承  unittest.TestCase  的类
class FirstDemo(unittest.TestCase):   ------- 固定写法,必须继承def test01(self):print("执行用例一")@unittest.skip("跳过用例二")      ------ @unitest.skipdef test02(self): print("执行用例二")if __name__ == '__main__':unittest.main()
  • 运行结果:跳过的内容会被标注

在这里插入图片描述

4.引入TestFixture

TestFixture一般都是写在运行的测试用例的类中,作用该类的类方法或者实例方法而存在
运行顺序:setUpClass() - - - 反复执行{ setUp()、测试用例test、tearDown() } - - - tearDownClass()|

TestFixture常用方法应用场景
setUp()每运行一个测试用例之前,先运行的函数。主要用于设置一些配置信息,静态属性等
setUpClass()类方法,必须和@classmethod装饰器结合使用,实例化类后,会自动运行的方法主要用于实例化类、设置某些环境配置如数据库连接配置等
tearDown()每运行完一个测试用例之后,后运行的函数。主要用于销毁每个测试用例之间的数据,释放资源,还原数据
tearDownClass()类中的代码全部运行完成后,会自动运行的方法,必须和@classmethod装饰器结合使用。主要用于销毁类级别的资源,还原数据

@classmethod 装饰器

类方法:被 @classmethod 装饰的函数,可以不用实例化类,就能够访问呢
举例:class A: pass - - - 实例化: A().aa - - - 不实例化: A.bb

在 unittest 当中 @classmethod 是 setUpClass() 和 tearDownClass() 的固定写法

  • 案例:测试加法运算
# 导入unittest模块
import unittest# 创建要执行的测试类
class add_doing:def Calculator(self,x,y):return x + y# 创建unittest的测试类
class TestPlus(unittest.TestCase):add = None# 编写测试固件def setUp(self):   # 如果不想写内容可以写pass跳过self.x = 1self.y = 1print("运行了setUp")@classmethoddef setUpClass(cls):cls.add = add_doing()print("运行了setUpClass")def tearDown(self):   # 和setUp一一对应del self.xdel self.yprint("运行了tearDown")@classmethoddef tearDownClass(cls):   # 和setUpClass一一对应del cls.addprint("运行了tearDownClass")# 测试用例,测试要执行的测试类def test01(self):print(self.add.Calculator(2,4))def test02(self):print(self.add.Calculator(5,6))def test03(self):print(self.add.Calculator(self.x,self.y))if __name__ == '__main__':unittest.main()
  • 运行结果

在这里插入图片描述

5.Unittest的断言

Unittest断言方法作用
assertEqual(a,b)检査 a和b是否相等
assertTrue(x)检查x是不是一个True
assertls(a,b)检查a和b是不是完全一样
assertlsNone(x)检查x是不是一个None
assertIn(a,b)检查a是不是b的子集
assertlsInstance(a,b)检查a、b两个对象,实例类型是否相同
  • 案例
import unittestclass TestAssert(unittest.TestCase):
----- unittest的断言是在TestCase中实现的,所以必须继承TestCase之后,才能够使用unittest的断言方法def setUp(self):self.l1,self.l2 = [1,2],[1,2]self.a = 1self.b = 1def test01_assertEqual(self):-----  断言self.a和self.b是否完全相等self.assertEqual(self.a, self.b)self.assertEqual(self.l1, self.l2)def test02_assertTrue(self):-----  assertTrue(x)可以根据传入的数据,判断真或者假(TrueFalse)#  assertTrue(0)是False#  assertTrue(None)是False#  assertTrue(1)是Trueself.assertTrue(self.a)self.assertTrue(self.l1)def test03_assertIs(self):-----  断言self.a和self.b是否完全相同self.assertIs(self.a, self.b)self.assertIs(self.l1, self.l2)    # Falsedef test04_assertIn(self):-----   断言a是否是 l1 的子集self.assertIn(self.a, self.l1)     # Trueself.assertIn(self.l1, self.l2)    ----- False  列表不能做子集运算def test05_assertIsNone(self):-----  断言是不是Noneself.assertIsNone(self.a)          # Falseself.assertIsNone(None)         # Truedef test06_assertIsInstance(self):-----   断言类型self.assertIsInstance(self.a, int)  # 判断a是不是整形  Trueself.assertIsInstance(self.l1, int) # False

6.TestSuite和TestRunner(不支持并发结果合并)

test suite测试套件,它是一个用例集,用来汇总应该一起执行的测试用例
test runner测试运行器,它是一个设计测试执行方式的元件,主要对用户的输出结果进行展示
  • 案例
# 导包
import unittest# 创建要执行的测试用例类
class TestSuiteDemo(unittest.TestCase):def test01(self):print("执行的测试用例test01,a")def test02(self):print("执行的测试用例test02,b")class TestSuiteDemo2(unittest.TestCase):def test01(self):print("执行的测试用例test01,张三")def test02(self):print("执行的测试用例test02,李四")if __name__ == '__main__':
# 实例化测试套件suite = unittest.TestSuite()# 将测试用例添加到测试套件中suite.addTest(TestSuiteDemo('test01'))suite.addTest(TestSuiteDemo2('test02'))
# 实例化runnerrunner = unittest.TextTestRunner()# 使用runner运行测试用例生成测试报告runner.run(suite)

1)运行时自动触发unittest.main()逻辑,需修改 PyCharm 配置

在这里插入图片描述

  • 修改配置后的运行结果

在这里插入图片描述

2)TestSuite添加测试用例的3种方式

TestSuite添加测试用例的3种方式写法举例(括号内命名可变)
suite.addTest 单个添加suite.addTest(TestSuiteDemo(‘test01’))
suite.addTests 多个添加suie.addTests([TestSuiteDemo(‘test01’),TestSuiteDemo2(‘test02’)])
TestLoader下面会重点介绍

3)TestLoader添加测试用例

两种方法解释
TestLoader().discover(“./”,“*.py”)根据执行的路径来寻找指定py文件中的测试用例,加载到测试套件当中
TestLoader().loadTestsFromTestCase(测试用例类名)根据测试用例的类名来加载测试用例
  • 案例
# 导入模块
import unittest# 创建测试用例的类
class TestSuiteDemo1(unittest.TestCase):def test01(self):print("执行的测试用例test01,a")def test02(self):print("执行的测试用例test02,b")class TestSuiteDemo2(unittest.TestCase):def test01(self):print("执行的测试用例test01,张三")def test02(self):print("执行的测试用例test02,李四")class TestSuiteDemo3(unittest.TestCase):def test01(self):print("单元测试")def test02(self):print("集成测试")def test03(self):print("系统测试")
  • 方法一:TestLoader().discover(“./”,“*.py”)
if __name__ == '__main__':------ 实例化testloaderstl = unittest.TestLoader()--- 使用testloader的对象tl来加载测试用例成测试套件suite = tl.discover('./','four_unittest.py')runner = unittest.TextTestRunner()runner.run(suite)
  • 运行结果

在这里插入图片描述

  • 方法二:TestLoader().loadTestsFromTestCase(测试用例类名)
if __name__ == '__main__':# 实例化testloaderstl = unittest.TestLoader()# 使用testloader的对象tl来加载测试用例成测试套件suite = tl.loadTestsFromTestCase(TestSuiteDemo3)runner = unittest.TextTestRunner()runner.run(suite)
  • 运行结果

在这里插入图片描述

7. 生成测试报告TestResult

使用unittest运行测试用例,最后会生成测试报告,我们可以把测试报告保存到文件中

1)TextTestRunner生成的文本格式报告

  • 查看TextTestRunner底层代码

在这里插入图片描述

  • 案例
if __name__ == '__main__':tl = unittest.TestLoader()suite = tl.discover('./','four_unittest.py')---  使用TextTestRunner生成测试报告---  1.打开要保存的测试报告文件,‘w’是写入的意思with open('./result.txt',mode='w') as f:---  2.实例化TextTestRunnerrunner = unittest.TextTestRunner(f, verbosity=3,descriptions=True)---  3.使用runner运行测试套件runner.run(suite)
  • 运行结果
    在这里插入图片描述

2)HTMLTestRunner_PY3生成的报告(好用,需安装)

HTMLTestRunner_Py3是一个能生成HTML格式的,显示更友好的测试报告,它不仅能够显示出测试用例的执行结果,还能跟踪测试用例执行失败的原因

HTMLTestRunner_PY3下载安装地址

  • 安装成功结果显示

在这里插入图片描述

  • 案例
from Scripts.HTMLTestRunner import HTMLTestRunnerif __name__ == '__main__':tl = unittest.TestLoader()suite = tl.discover('./','four_unittest.py')---  使用HTMLTestRunner生成测试报告---  1.打开要保存的测试报告文件,‘wb’是写入的意思with open('./result.html',mode='wb') as f:---  2.实例化HTMLTestRunnerrunner = HTMLTestRunner(f,verbosity=2,title='演示HTML测试报告')---  3.使用runner运行测试套件runner.run(suite)
  • 运行结果

在这里插入图片描述

  • 浏览器展示

在这里插入图片描述

8. 框架进行并发(unittest不适合,使用pytest)

使用多线程运行,可以并行执行测试用例,提升测试速度

框架是否推荐多线程推荐方式
unittest不推荐手动用 threading 或 threadpool使用 concurrent.futures + 手动结果汇总,或改用 pytest
pytest强烈推荐使用并发执行使用 pytest-xdist 插件(基于多进程,非多线程)
  • unittest使用concurrent.futures多线程举例(适用于老项目)
from concurrent.futures import ThreadPoolExecutor
import unittestdef run_test_case(test):result = unittest.TestResult()test(result)return resultif __name__ == '__main__':# 拆分测试用例suite = unittest.TestLoader().discover('./','*.py')test_cases = [test for test in suite]with ThreadPoolExecutor(max_workers=4) as executor:futures = [executor.submit(run_test_case, test) for test in test_cases]# 汇总结果total_result = unittest.TestResult()for future in futures:result = future.result()# 手动合并结果(注意线程安全)total_result.errors.extend(result.errors)total_result.failures.extend(result.failures)total_result.testsRun += result.testsRun
http://www.xdnf.cn/news/1459765.html

相关文章:

  • 无人机防风技术难点解析
  • TDengine TIMETRUNCATE 函数用户使用手册
  • Netty从0到1系列之Buffer【下】
  • 2025年百度商业AI技术创新大赛赛道二:视频广告生成推理性能优化-初赛第五名,复赛第九名方案分享
  • JVM 运行时数据区域
  • java面试中经常会问到的dubbo问题有哪些(基础版)
  • JVM 类加载全过程
  • Node-RED服务成本/价格很高?那这不到“三张”的怎么说?
  • QT卡顿的可能原因
  • TP8 数组在模板html文件中输出json字符串格式{“0“:“x1“,“1“:“x2“,“2“:“x3“}
  • 在Spring MVC中使用查询字符串与参数
  • 2025市面上比较实用的财会行业证书,最值得考的8个职业证书推荐
  • 本地部署开源数据生成器项目实战指南
  • HarmonyOS应用开发之界面列表不刷新问题Bug排查记:从现象到解决完整记录
  • JS函数进阶
  • Roo Code之自定义指令(Custom Instructions),规则(Rules)
  • 硬盘分区格式化后产生了哪些变化
  • OpenStack VLAN网络类型实训案例
  • 机器学习:后篇
  • LangChain4j的初步学习【逐步添加中】
  • 强化学习DQN解决Cart_Pole问题
  • claude code route 使用教程|命令大全
  • linux中的awk使用详解
  • 深度解读《实施“人工智能+”行动的意见》:一场由场景、数据与价值链共同定义的产业升级
  • 【8】C#上位机---泛型、委托delegate与多线程Task
  • 2025年代理IP服务深度评测:三大平台横评,谁是最强业务助手?
  • 检查数据集格式(77)
  • 计算机二级C语言操作题(填空、修改、设计题)——真题库(16)附解析答案
  • C++基础——模板进阶
  • 【C++题解】关联容器