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

软件测试基础十七(python Unittest)

Unittest

一、Unittest 简介

unittest是 Python 内置的标准测试框架,用于编写和运行单元测试。它提供了一组工具和类,帮助开发者组织、编写和执行测试用例,以验证代码的正确性。

二、Unittest 核心要素

1. TestCase(测试用例类)

  1. 定义与作用:
    • TestCaseunittest框架中最小的测试单元,用于封装一个具体的测试场景。它通常是一个继承自unittest.TestCase的类,每个类中的方法代表一个具体的测试用例。
    • 测试用例应该是独立的、可重复执行的,并且能够验证被测试代码的特定功能或行为。
  1. 主要方法:

例如:

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(测试套件)

  1. 定义与作用:
    • TestSuite用于组合多个测试用例或测试套件,形成一个更大的测试集合。它可以将多个相关的测试用例组织在一起,方便一次性执行。
    • 通过TestSuite,可以灵活地选择要执行的测试用例,以及控制测试的执行顺序。
  1. 主要方法:

例如:

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(测试运行器)

  1. 定义与作用:
    • TestRunner负责执行测试用例或测试套件,并生成测试结果报告。它可以将测试结果以文本形式或其他格式输出,以便开发者查看测试的执行情况。
    • 不同的TestRunner可以提供不同的输出格式和功能,例如TextTestRunner以文本形式输出测试结果,而一些第三方库可以生成 HTML 格式的测试报告。
  1. 主要方法:

例如:

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)
  1. 以模块名为例:
    • 创建一个模块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)
  1. 以类名为例:
    • 继续使用上面的test_module.py模块。
import unittestloader = unittest.TestLoader()
suite = loader.loadTestsFromName('test_module.TestInModule') # 注意这里有引号runner = unittest.TextTestRunner()
runner.run(suite)
  1. 以方法名为例:
    • 同样使用上面的模块。
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):断言 ab 相等。
    • assertNotEqual(a, b):断言 ab 不相等。
    • assertTrue(x):断言 xTrue
    • assertFalse(x):断言 xFalse
    • assertIs(a, b):断言 ab 是同一个对象。
    • assertIsNot(a, b):断言 ab 不是同一个对象。
    • assertIsNone(x):断言 xNone
    • assertIsNotNone(x):断言 x 不是 None
    • assertIn(a, b):断言 ab 中。
    • 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. 使用第三方库
    • pytestparameterized:这些库提供了更强大的参数化测试功能,可以更方便地实现参数化测试。
    • 安装第三方库: 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) 装饰器:可以根据特定的条件来跳过测试用例。如果 conditionTrue,则跳过该测试用例。
    • 使用 unittest.skipUnless(condition, reason) 装饰器:与 skipIf 相反,只有当 conditionTrue 时,才执行该测试用例。

六、生成 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:[可选参数],为报告描述信息;比如操作系统、浏览器等版本;

    • 使用第三方库,如 HTMLTestRunnerHTMLTestRunner 是一个用于生成 HTML 测试报告的第三方库。可以将测试用例的执行结果输出为 HTML 格式的报告。
    • 使用 unittestTextTestRunner 并结合其他工具:可以使用 TextTestRunner 来执行测试用例,并将结果输出到一个文件中。然后,可以使用其他工具将文本报告转换为 HTML 格式的报告。

总之,unittest模块提供了丰富的功能来支持单元测试,包括Fixture、断言、参数化、跳过和生成 HTML 测试报告等。这些功能可以帮助开发者提高代码的质量和可靠性,并且可以更方便地进行测试和调试。

http://www.lryc.cn/news/480537.html

相关文章:

  • 技术领导者的道与术:从领导者到领导力
  • Starrocks Compaction的分析
  • 淘淘商城实战高并发分布式项目(有源码)
  • 内网部署web项目,外网访问不了?只有局域网能访问!怎样解决?
  • Jenkins系列
  • 技术总结(二十四)
  • 原生鸿蒙应用市场:赋能开发者全生命周期服务体验
  • 深入解析TOML、XML、YAML和JSON:优劣对比与场景应用
  • 前端UniApp面试题及参考答案(100道题)
  • MoonBit 双周报 Vol.59:新增编译器常量支持,改进未使用警告,支持跨包函数导入...多个关键技术持续优化中!
  • Linux相关概念和易错知识点(20)(dentry、分区、挂载)
  • 论 ONLYOFFICE:开源办公套件的深度探索
  • 兵马未动,粮草先行-InnoDB统计数据是如何收集的
  • oracle服务器意外宕机数据库启动失败故障处理记录
  • 学习笔记——MathType公式编号:右编号和随章节变化
  • 如何使用 SSH 连接并管理你的 WordPress 网站
  • 力扣60. 排列序列
  • Mac如何实现最简单的随时监测实时运行状态的方法
  • 时间管理应用(可复制源码)
  • SQL server 列转行
  • aws申请ssl证书的方法【该证书仅供aws】
  • Linux中目录配置标准的FHS
  • 目标检测YOLO实战应用案例100讲-基于深度学习的人眼视线检测
  • SpringCloud篇(微服务)
  • [每日一练]过去30天的用户活动
  • 华为2288HV2服务器安装BCLinux8U6无法显示完整安装界面的问题处理
  • 【python】OpenCV—findContours(4.6)
  • 【C++】——多态
  • Web前端开发--HTML语言
  • AI驱动的网络空间智能对抗;无人集群系统,多体协同算法创新和故障智能预警