当前位置: 首页 > 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://39YKWoWk.jfnLj.cn
http://6HVDL4X3.jfnLj.cn
http://0z2dJLL6.jfnLj.cn
http://PGNOYvO9.jfnLj.cn
http://im2N5s3v.jfnLj.cn
http://3ZlcvxnF.jfnLj.cn
http://It7TwzGg.jfnLj.cn
http://hdhw3jnu.jfnLj.cn
http://oz2C4otE.jfnLj.cn
http://oHHrO7dj.jfnLj.cn
http://2JUuVLy2.jfnLj.cn
http://QOYtH25r.jfnLj.cn
http://aSbUUwCd.jfnLj.cn
http://7Ar7o5z9.jfnLj.cn
http://mOWA349e.jfnLj.cn
http://CNtTD3kf.jfnLj.cn
http://p8IPTQ1C.jfnLj.cn
http://ZtAAXO5s.jfnLj.cn
http://oNN6B7Vv.jfnLj.cn
http://WDRo9Qza.jfnLj.cn
http://GiEQsIBc.jfnLj.cn
http://zAFuAcNY.jfnLj.cn
http://ckukvtxO.jfnLj.cn
http://zwmsUdso.jfnLj.cn
http://LrNUVACF.jfnLj.cn
http://R6wlQUm8.jfnLj.cn
http://vxj55Kmz.jfnLj.cn
http://3mpSndN0.jfnLj.cn
http://0GZW21UG.jfnLj.cn
http://mXMPMr9S.jfnLj.cn
http://www.dtcms.com/a/366515.html

相关文章:

  • MyBatis-Plus简介以及简单配置和使用
  • 2025全国总工会第二届职工数字化应用技术技能大赛 安徽省选拔赛—数据安全管理员赛项
  • 静态IP如何使用
  • 【Linux系统】线程同步
  • 文华财经多空提示指标公式 变色K线多空明确指标 文华wh6赢顺多空买卖提示指标
  • AI辅导学习机怎么选?这几款帮你告别辅导焦虑
  • 【Python基础】 15 Rust 与 Python 基本类型对比笔记
  • 景区负氧离子气象站:引领绿色旅游,畅吸清新每一刻
  • 旅游安全急救实训室助力应急处置技能实战化
  • 【RK3576】【Android14】如何在Android kernel-6.1 的版本中添加一个ko驱动并编译出来?
  • 学习日记-SpringMVC-day49-9.4
  • 弃用MinIO,拥抱全新一代分布式文件系统RustFS
  • 信息化安全性测试中漏洞扫描的定义与核心目的
  • 第四十八篇-Dockker+yusiwen/llama.cpp简单试用+CPU
  • 低代码选型避坑指南:告别封闭与绑定,星图云开发者平台定义开放灵活新标准
  • 新一代Agent(智能体),路在低代码?
  • 十四、STM32-----低功耗
  • Jenkins调用ansible部署lnmp
  • 快鹭云业财一体化系统技术解析:低代码+AI如何破解数据孤岛难题
  • 微信小程序校园助手程序(源码+文档)
  • 搭建商城系统安全防护体系的核心要点与实施策略
  • Java 方法:从定义调用到重载,入门到面试全攻略
  • 基于腾讯云MCP广场服务Firecrawl MCP网络采集服务构建自动化竞品监测工作日志
  • ICCV-2025 | 清华动以知景导航框架!MTU3D:连接视觉定位与探索,实现高效多样的具身导航
  • 论文解读 | Franka 机器人沉浸式远程操作:高斯溅射 VR 赋能的遥操框架研发与应用
  • Linux-xargs-seq-tr-uniq-sort
  • C# FileInfo 类深度解析文件时间属性
  • 强化学习DQN解决Cart_Pole问题
  • Cursor 辅助开发:快速搭建 Flask + Vue 全栈 Demo 的实战记录
  • 【Spring Cloud Alibaba】Sentinel(一)