软件测试基础十七(python Unittest)
Unittest
一、Unittest 简介
unittest是 Python 内置的标准测试框架,用于编写和运行单元测试。它提供了一组工具和类,帮助开发者组织、编写和执行测试用例,以验证代码的正确性。
二、Unittest 核心要素
1. TestCase(测试用例类)
- 定义与作用:
-
TestCase是unittest框架中最小的测试单元,用于封装一个具体的测试场景。它通常是一个继承自unittest.TestCase的类,每个类中的方法代表一个具体的测试用例。- 测试用例应该是独立的、可重复执行的,并且能够验证被测试代码的特定功能或行为。
- 主要方法:
例如:
import unittestclass TestCase(unittest.TestCase):def setUp(self):self.num = 5def tearDown(self):del self.numdef test_equal(self):self.assertEqual(self.num, 5)if __name__ == '__main__':unittest.main()
-
setUp():在每个测试方法执行之前被调用,用于设置测试环境,例如初始化对象、创建临时文件等。tearDown():在每个测试方法执行之后被调用,用于清理测试环境,例如删除临时文件、释放资源等。- 测试方法:以“test_”开头的方法被视为测试方法,这些方法中包含具体的测试逻辑和断言,用于验证被测试代码的输出是否符合预期。
2. TestSuite(测试套件)
- 定义与作用:
-
TestSuite用于组合多个测试用例或测试套件,形成一个更大的测试集合。它可以将多个相关的测试用例组织在一起,方便一次性执行。- 通过
TestSuite,可以灵活地选择要执行的测试用例,以及控制测试的执行顺序。
- 主要方法:
例如:
import unittestclass TestA(unittest.TestCase):def test_a(self):passclass TestB(unittest.TestCase):def test_b(self):passsuite = unittest.TestSuite()
suite.addTest(TestA('test_a'))
suite.addTest(TestB('test_b'))
-
addTest(test_case):将一个测试用例添加到测试套件中。addTests(test_cases):将多个测试用例添加到测试套件中。
3. TestRunner(测试运行器)
- 定义与作用:
-
TestRunner负责执行测试用例或测试套件,并生成测试结果报告。它可以将测试结果以文本形式或其他格式输出,以便开发者查看测试的执行情况。- 不同的
TestRunner可以提供不同的输出格式和功能,例如TextTestRunner以文本形式输出测试结果,而一些第三方库可以生成 HTML 格式的测试报告。
- 主要方法:
例如:
import unittestsuite = unittest.TestSuite()
# 添加测试用例到套件
runner = unittest.TextTestRunner()
result = runner.run(suite)
-
run(test):执行给定的测试用例或测试套件,并返回一个TestResult对象,其中包含测试的结果信息。
4. 示例代码:
4.1. 新建一个文件test01.py,用例如下:
import unittestdef sum_( a, b):return a + bclass TestA(unittest.TestCase):def test_add_1(self):result = sum_(1, 2)self.assertEqual(result, 3)def test_add_2(self):result = sum_(2, 3)self.assertNotEqual(result, 4)
4.2. 新建一个文件test02.py,用例如下:
import unittestdef sub_( a, b):return a - bclass TestB(unittest.TestCase):def test_sub_1(self):result = sub_(4, 2)self.assertEqual(result, 2)def test_sub_2(self):result = sub_(4, 1)self.assertNotEqual(result, 4)
4.3. 新建一个文件003.py,通过TestSuite选择用例进行执行:
import unittest
import test01
import test02suite = unittest.TestSuite()
# 添加test01文件中的用例test_add_1
suite.addTest(test01.TestA("test_add_1"))
# 添加test02文件中的用例test_sub_1
suite.addTest(test02.TestB("test_sub_1"))
runner = unittest.TextTestRunner()
runner.run(suite)
5. TestLoader(测试加载器)
5.1. 定义与作用
-
TestLoader用于自动发现和加载测试用例。它可以根据指定的规则搜索测试模块、测试类和测试方法,并将它们加载到测试套件中。TestLoader使得开发者可以方便地组织和执行大量的测试用例,而无需手动添加每个测试用例到测试套件中。
5.2. 主要方法
例如:
import unittestloader = unittest.TestLoader()
suite = loader.loadTestsFromModule(__name__)
-
loadTestsFromModule(module):从一个 Python 模块中加载测试用例。loadTestsFromTestCase(test_case_class):从一个测试用例类中加载测试用例。loadTestsFromName(name):根据给定的名称加载测试用例,可以是模块名、类名或方法名。
5.3. 示例
5.3.1. loadTestsFromModule(module)
创建一个名为my_module.py的模块,其中包含以下测试用例类:
# my_module.py
import unittestclass MyTestCase1(unittest.TestCase):def test_method1(self):self.assertEqual(2 + 2, 4)class MyTestCase2(unittest.TestCase):def test_method2(self):self.assertTrue(5 > 3)
使用loadTestsFromModule执行用例
import unittest
import my_moduleloader = unittest.TestLoader()
suite = loader.loadTestsFromModule(my_module)runner = unittest.TextTestRunner()
runner.run(suite)
5.3.2. loadTestsFromTestCase(test_case_class)
创建一个测试用例类定义如下:
import unittestclass MySpecialTestCase(unittest.TestCase):def test_something(self):self.assertEqual(3 * 3, 9)def test_another_thing(self):self.assertFalse(2 == 3)
使用loadTestsFromTestCase执行用例:
import unittest
from your_module import MySpecialTestCaseloader = unittest.TestLoader()
suite = loader.loadTestsFromTestCase(MySpecialTestCase)runner = unittest.TextTestRunner()
runner.run(suite)
5.3.3. loadTestsFromName(name)
- 以模块名为例:
-
- 创建一个模块
test_module.py,其中包含测试用例类。
- 创建一个模块
# test_module.py
import unittestclass TestInModule(unittest.TestCase):def test_one(self):self.assertEqual(4 * 2, 8)
import unittestloader = unittest.TestLoader()
suite = loader.loadTestsFromName('test_module') # 注意这里有引号runner = unittest.TextTestRunner()
runner.run(suite)
- 以类名为例:
-
- 继续使用上面的
test_module.py模块。
- 继续使用上面的
import unittestloader = unittest.TestLoader()
suite = loader.loadTestsFromName('test_module.TestInModule') # 注意这里有引号runner = unittest.TextTestRunner()
runner.run(suite)
- 以方法名为例:
-
- 同样使用上面的模块。
import unittestloader = unittest.TestLoader()
suite = loader.loadTestsFromName('test_module.TestInModule.test_one') # 注意这里有引号runner = unittest.TextTestRunner()
runner.run(suite)
6. Fixture
6.1. 定义与作用
-
- Fixture 是在测试用例执行前后执行的一组操作,用于设置测试环境和清理资源。例如,在测试数据库操作时,可以在测试用例执行前连接数据库,在测试用例执行后关闭数据库连接。
- Fixture 可以确保每个测试用例都在相同的初始状态下执行,提高测试的可重复性和可靠性。
6.2. 主要方法
例如:
import unittestclass MyTest(unittest.TestCase):@classmethoddef setUpClass(cls):print("Set up class.")def setUp(self):print("Set up.")def test_method(self):print("Running test method.")def tearDown(self):print("Tear down.")@classmethoddef tearDownClass(cls):print("Tear down class.")
-
setUp():在每个测试用例执行前调用,用于设置测试环境。tearDown():在每个测试用例执行后调用,用于清理测试环境。setUpClass():在测试类的所有测试用例执行前调用一次,通常用于执行一些耗时的初始化操作,如连接数据库。tearDownClass():在测试类的所有测试用例执行后调用一次,用于清理资源,如关闭数据库连接。
总之,unittest的这些核心要素相互配合,提供了一个强大的测试框架,帮助开发者编写、组织和执行单元测试,以确保代码的质量和稳定性。
三、断言(Assertions)
1. 定义和作用
-
- 断言是用于验证测试结果是否符合预期的语句。在测试用例中,通过断言来检查实际结果与预期结果是否一致。如果断言失败,测试用例将被标记为失败。
- 断言可以帮助开发者快速发现代码中的错误,提高代码的质量和可靠性。
2. 常见的断言方法
例如:
import unittestclass MyTest(unittest.TestCase):def test_equal(self):self.assertEqual(2 + 2, 4)def test_not_equal(self):self.assertNotEqual(2 + 2, 5)def test_true(self):self.assertTrue(2 < 3)def test_false(self):self.assertFalse(2 > 3)
-
assertEqual(a, b):断言a和b相等。assertNotEqual(a, b):断言a和b不相等。assertTrue(x):断言x为True。assertFalse(x):断言x为False。assertIs(a, b):断言a和b是同一个对象。assertIsNot(a, b):断言a和b不是同一个对象。assertIsNone(x):断言x是None。assertIsNotNone(x):断言x不是None。assertIn(a, b):断言a在b中。assertNotIn(a, b):断言a不在b中。
四、参数化(Parameterization)
1. 定义和作用
-
- 参数化测试是一种将相同的测试逻辑应用于不同的输入数据的技术。通过参数化,可以减少重复的测试代码,提高测试的效率和覆盖度。
- 参数化测试可以使用不同的输入数据来验证代码的正确性,从而发现更多的错误。
2. 实现方法
2.1. 使用 unittest.TestCase.subTest() 方法
-
- 使用
unittest.TestCase.subTest()方法:可以在一个测试方法中使用subTest方法来对不同的输入数据进行测试。每次调用subTest方法时,都会执行相同的测试逻辑,但使用不同的输入数据。
- 使用
import unittestclass MyTest(unittest.TestCase):def test_addition(self):data = [(2, 3, 5), (4, 5, 9), (6, 7, 13)]for a, b, expected in data:with self.subTest(a=a, b=b):self.assertEqual(a + b, expected)
2.2. 使用第三方库
-
- 如
pytest或parameterized:这些库提供了更强大的参数化测试功能,可以更方便地实现参数化测试。 - 安装第三方库: pip install parameterized
- 导包:from parameterized import parameterized
- 代码示例:
- 如
import unittest
from parameterized import parameterizeddef add_numbers(a, b):return a + bclass TestAddNumbers(unittest.TestCase):@parameterized.expand([(1, 2, 3),(4, 5, 9),(10, -5, 5)])def test_add_numbers(self, a, b, expected_result):result = add_numbers(a, b)self.assertEqual(result, expected_result)if __name__ == '__main__':unittest.main()
五、跳过(Skipping)
1. 定义和作用
-
- 有时候,某些测试用例可能在特定的条件下不适合执行,或者已知存在问题。在这种情况下,可以使用跳过机制来跳过这些测试用例,避免不必要的失败。
- 跳过测试用例可以提高测试的效率,并且可以在特定的情况下避免错误的报告。
2. 实现方法
例如:
import unittestclass MyTest(unittest.TestCase):@unittest.skip("This test is skipped for now.")def test_skipped_method(self):pass@unittest.skipIf(2 > 3, "This test is skipped if 2 > 3.")def test_skipped_if_method(self):pass@unittest.skipUnless(2 < 3, "This test is skipped unless 2 < 3.")def test_skipped_unless_method(self):pass
-
- 使用
unittest.skip(reason)装饰器:可以在测试方法上使用skip装饰器来跳过该测试用例。reason参数是一个字符串,用于说明跳过的原因。 - 使用
unittest.skipIf(condition, reason)装饰器:可以根据特定的条件来跳过测试用例。如果condition为True,则跳过该测试用例。 - 使用
unittest.skipUnless(condition, reason)装饰器:与skipIf相反,只有当condition为True时,才执行该测试用例。
- 使用
六、生成 HTML 测试报告
1. 定义和作用
-
- 生成 HTML 测试报告可以将测试结果以更直观的形式展示出来,方便开发者查看和分析测试结果。
- HTML 测试报告可以包含测试用例的名称、执行时间、结果状态等信息,以及详细的错误信息和堆栈跟踪。
2. 实现方法
例如,使用 HTMLTestRunner(这里可能会出现兼容问题,生成报告内容为空,具体问题具体解决):
import unittest
import HTMLTestRunnerclass MyTest(unittest.TestCase):def test_method(self):self.assertEqual(2 + 2, 4)if __name__ == '__main__':suite = unittest.TestLoader().loadTestsFromTestCase(MyTest)with open('test_report.html', 'wb') as f:runner = HTMLTestRunner.HTMLTestRunner(stream=f, title='Test Report', description='Unit Test Results')runner.run(suite)
参数说明:
stream:open 函数打开的文件流;
title:[可选参数],为报告标题;
description:[可选参数],为报告描述信息;比如操作系统、浏览器等版本;
-
- 使用第三方库,如
HTMLTestRunner:HTMLTestRunner是一个用于生成 HTML 测试报告的第三方库。可以将测试用例的执行结果输出为 HTML 格式的报告。 - 使用
unittest的TextTestRunner并结合其他工具:可以使用TextTestRunner来执行测试用例,并将结果输出到一个文件中。然后,可以使用其他工具将文本报告转换为 HTML 格式的报告。
- 使用第三方库,如
总之,unittest模块提供了丰富的功能来支持单元测试,包括Fixture、断言、参数化、跳过和生成 HTML 测试报告等。这些功能可以帮助开发者提高代码的质量和可靠性,并且可以更方便地进行测试和调试。
相关文章:
软件测试基础十七(python Unittest)
Unittest 一、Unittest 简介 unittest是 Python 内置的标准测试框架,用于编写和运行单元测试。它提供了一组工具和类,帮助开发者组织、编写和执行测试用例,以验证代码的正确性。 二、Unittest 核心要素 1. TestCase(测试用例类…...
技术领导者的道与术:从领导者到领导力
目录标题 领导者现实看起来是这样技术领导者不应该和个人坐在一起技术领导力仍然是必须的从技术领导到技术领导力小结领导者 你可能想成为或者已经是一位技术领导者,估计你现在心里想成为超级英雄的想法正在爆棚。 你是Java、JavaScript、Angular等技术的专家,公司的项目代…...
Starrocks Compaction的分析
背景 本文基于 Starrocks 3.1.7 结论 Starrocks 会启动一个线程周期性的去进行Compaction,该周期间隔为 200 MS, 该Compaction以table的partition为切入点,tablet(也就是bucket)为粒度进行task的创建。 分析 CompactionMgr start 方法会启动一个Com…...
淘淘商城实战高并发分布式项目(有源码)
通过百度网盘分享的文件:淘淘商城实战高并发分布式项目(有源码) 链接:https://pan.baidu.com/s/1V94gRALxHgMVwpcXoE-miA?pwdglu7 提取码:glu7 在互联网技术飞速发展的当下,高并发分布式项目成为了众多电商平台等大型应用的核心…...
内网部署web项目,外网访问不了?只有局域网能访问!怎样解决?
相关技术 要实现“内网部署,外网访问”,可以使用内网穿透、VPN技术、DMZ主机、端口映射等方法。以下是对这些方法的详细解释: 一、内网穿透 内网穿透是一种技术,它通过将内网设备映射到公网上的方式,实现外网访问内…...
Jenkins系列
jenkins 1、搭建Jenkins 搭建Jenkins 2、这是什么 3、这是什么 4、 这是什么 5、这是什么 文章目录 jenkins1、搭建Jenkins2、这是什么3、这是什么4、 这是什么5、这是什么 前言 前言 提示:这里可以添加本文要记录的大概内容: 例如:随…...
技术总结(二十四)
一、Redis 分布式锁的常见使用场景有哪些? 资源竞争控制 数据库事务控制:在分布式系统中,多个服务可能会同时对数据库中的同一行数据进行操作。例如,在一个电商系统里,多个订单处理服务可能会同时尝试更新同一个订单的…...
原生鸿蒙应用市场:赋能开发者全生命周期服务体验
文章目录 背景自动化检测前移:早发现,早解决技术细节:静态代码分析与兼容性测试应用场景 按需加载:优化性能,提升用户体验技术细节:模块化与懒加载实现应用场景 应用加密:保护应用代码安全&…...
深入解析TOML、XML、YAML和JSON:优劣对比与场景应用
摘要:本文将介绍四种常见的配置文件和数据交换格式:TOML、XML、YAML和JSON,通过具体的使用例子分析它们的优缺点,并探讨在不同场景下的应用选择。 正文: 一、TOML 优点: 易于阅读和编写:TOML的…...
前端UniApp面试题及参考答案(100道题)
目录 UniApp 支持哪些平台? UniApp 在不同平台上的表现有何差异? 如何处理 UniApp 中的平台差异? UniApp 项目创建与目录结构 项目创建 目录结构 如何创建一个 UniApp 项目? UniApp 项目的基本目录结构是什么样的? 解释一下 UniApp 中的页面生命周期钩子函数有哪…...
MoonBit 双周报 Vol.59:新增编译器常量支持,改进未使用警告,支持跨包函数导入...多个关键技术持续优化中!
2024-11-04 MoonBit更新 增加了编译期常量的支持。常量的名字以大写字母开头,用语法 const C ... 声明。常量的类型必须是内建的数字类型或 String。常量可以当作普通的值使用,也可以用于模式匹配。常量的值目前只能是字面量: const MIN_…...
Linux相关概念和易错知识点(20)(dentry、分区、挂载)
目录 1.dentry (1)路径缓存的原因 (2)dentry的结构 ①多叉树结构 ②file和dentry之间的联系 ③路径概念存在的意义 2.分区 (1)为什么要确认分区 (2)挂载 ①进入分区 ②被挂…...
论 ONLYOFFICE:开源办公套件的深度探索
公主请阅 引言第一部分:ONLYOFFICE 的历史背景1.1 开源软件的崛起1.2 ONLYOFFICE 的发展历程 第二部分:ONLYOFFICE 的核心功能2.1 文档处理2.2 电子表格2.3 演示文稿 第三部分:技术架构与兼容性3.1 技术架构3.2 兼容性 第四部分:部…...
兵马未动,粮草先行-InnoDB统计数据是如何收集的
我们前面介绍查询成本的时候经常用到一些统计数据,比如通过SHOW TABLE STATUS可以看到关于表的统计数据,通过SHOW INDEX可以看到关于索引的统计数据,那么这些统计数据是怎么来的呢?它们是以什么方式收集的呢?本章将聚焦…...
oracle服务器意外宕机数据库启动失败故障处理记录
客户反馈由于服务器意外宕机,导致数据库业务不能正常运行,经过一番努力后通过redo日志恢复成功! 故障描述:ORA-00600: 内部错误代码, 参数: [krctcr_4], [1179922061], [1179942042], [], [], [], [], [], [], [], [], [] 现将主要…...
学习笔记——MathType公式编号:右编号和随章节变化
1.如何在word文档中插入带有编号的公式? 步骤:(前提是已经安装mathtype) 2.MathType公式编号怎么随章节变化? 想要编号级数也随标题级数进行自动变化,则需要插入或修改文档的“分隔符” 步骤:...
如何使用 SSH 连接并管理你的 WordPress 网站
在当今数字化的世界里,网站的管理与维护至关重要。对于使用 WordPress 搭建网站的用户而言,掌握基本的 SSH(安全壳)命令能够极大地简化网站管理工作。本指南将向你介绍 SSH 的基本知识,并教你如何通过 SSH 连接和管理你…...
力扣60. 排列序列
描述 力扣60. 排列序列 给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。 按大小顺序列出所有排列情况,并一一标记,当 n 3 时, 所有排列如下: “123” “132” “213” “231” “312” “321” 给定 n 和 k,返回…...
Mac如何实现最简单的随时监测实时运行状态的方法
Mac book有着不同于Windows的设计逻辑与交互设计,使得Mac book有着非常棒的使用体验,但是在Mac电脑的使用时间过长时,电脑也会出现响应速度变慢或应用程序崩溃的情况,当发生的时候却不知道什么原因导致的,想要查询电脑…...
时间管理应用(可复制源码)
创建一个简单的时间管理应用程序,结合 Pomodoro 技术使用 HTML、CSS 和 JavaScript 1. HTML 创建一个基本的 HTML 文件 (index.html): <!DOCTYPE html> <html lang"zh"> <head> <meta charset"UTF-8"&…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...
实战三:开发网页端界面完成黑白视频转为彩色视频
一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 二、实现思路 总体思路: 用户通过Gradio界面上…...
【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅
目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...
Leetcode33( 搜索旋转排序数组)
题目表述 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...
恶补电源:1.电桥
一、元器件的选择 搜索并选择电桥,再multisim中选择FWB,就有各种型号的电桥: 电桥是用来干嘛的呢? 它是一个由四个二极管搭成的“桥梁”形状的电路,用来把交流电(AC)变成直流电(DC)。…...
大数据治理的常见方式
大数据治理的常见方式 大数据治理是确保数据质量、安全性和可用性的系统性方法,以下是几种常见的治理方式: 1. 数据质量管理 核心方法: 数据校验:建立数据校验规则(格式、范围、一致性等)数据清洗&…...
