[转]单元测试框架unittest之subTest()

本文深入探讨unittest框架中subTest()的使用,通过实例对比展示如何利用subTest()在一个测试方法中处理参数细微差异,实现更全面的自动化测试覆盖。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

一、摘要

 

假设我们有一组测试方法差别非常小,比如仅仅是所需要的参数有少许变化时,我们的自动化测试如何进行?unittest框架为这种场景提供了一种方式,它允许我们用subTest()上下文管理器在一个测试方法内识别这种细小的不同,这么说可能有点晕

 

实际上我觉得还不如直接看代码更能清晰的表达它为我们的测试带来了什么

 

二、代码实例

 

# coding:utf-8
import unittest


class NumbersTest(unittest.TestCase):

    def test_even(self):
        """
        使用subTest上下文管理器,区分细小的变化
        取模运算,返回除法的余数,但是参数是0到5的整数,没必要单独写方法
        """
        for i in range(0, 6):
            with self.subTest(i=i):
                self.assertEqual(i % 2, 0)


if __name__ == '__main__':
    unittest.main()
 

 

执行这段代码的结果会是:

 

SubTest failure: Traceback (most recent call last):
  File "C:\Python37\lib\unittest\case.py", line 59, in testPartExecutor
    yield
  File "C:\Python37\lib\unittest\case.py", line 533, in subTest
    yield
  File "D:\Programs\Python\Demo\unittest4\subtestDemo.py", line 14, in test_even
    self.assertEqual(i % 2, 0)
  File "C:\Program Files\JetBrains\PyCharm Community Edition 2018.3.1\helpers\pycharm\teamcity\diff_tools.py", line 39, in _patched_equals
    raise native_error
  File "C:\Program Files\JetBrains\PyCharm Community Edition 2018.3.1\helpers\pycharm\teamcity\diff_tools.py", line 32, in _patched_equals
    old(self, first, second, msg)
  File "C:\Python37\lib\unittest\case.py", line 839, in assertEqual
    assertion_func(first, second, msg=msg)
  File "C:\Python37\lib\unittest\case.py", line 832, in _baseAssertEqual
    raise self.failureException(msg)
AssertionError: 1 != 0

SubTest failure: Traceback (most recent call last):
  File "C:\Python37\lib\unittest\case.py", line 59, in testPartExecutor
    yield
  File "C:\Python37\lib\unittest\case.py", line 533, in subTest
    yield
  File "D:\Programs\Python\Demo\unittest4\subtestDemo.py", line 14, in test_even
    self.assertEqual(i % 2, 0)
  File "C:\Program Files\JetBrains\PyCharm Community Edition 2018.3.1\helpers\pycharm\teamcity\diff_tools.py", line 39, in _patched_equals
    raise native_error
  File "C:\Program Files\JetBrains\PyCharm Community Edition 2018.3.1\helpers\pycharm\teamcity\diff_tools.py", line 32, in _patched_equals
    old(self, first, second, msg)
  File "C:\Python37\lib\unittest\case.py", line 839, in assertEqual
    assertion_func(first, second, msg=msg)
  File "C:\Python37\lib\unittest\case.py", line 832, in _baseAssertEqual
    raise self.failureException(msg)
AssertionError: 1 != 0

SubTest failure: Traceback (most recent call last):
  File "C:\Python37\lib\unittest\case.py", line 59, in testPartExecutor
    yield
  File "C:\Python37\lib\unittest\case.py", line 533, in subTest
    yield
  File "D:\Programs\Python\Demo\unittest4\subtestDemo.py", line 14, in test_even
    self.assertEqual(i % 2, 0)
  File "C:\Program Files\JetBrains\PyCharm Community Edition 2018.3.1\helpers\pycharm\teamcity\diff_tools.py", line 39, in _patched_equals
    raise native_error
  File "C:\Program Files\JetBrains\PyCharm Community Edition 2018.3.1\helpers\pycharm\teamcity\diff_tools.py", line 32, in _patched_equals
    old(self, first, second, msg)
  File "C:\Python37\lib\unittest\case.py", line 839, in assertEqual
    assertion_func(first, second, msg=msg)
  File "C:\Python37\lib\unittest\case.py", line 832, in _baseAssertEqual
    raise self.failureException(msg)
AssertionError: 1 != 0


One or more subtests failed
Failed subtests list: (i=1), (i=3), (i=5)


Ran 1 test in 0.020s

FAILED (failures=3)

Process finished with exit code 1
 

 

而如果我们不使用subTest(), 只是写个简单的循环去断言,当程序执行到第一个断言失败时就会终止了,后边可能还有断言能够成功的也就不会被执行了

 

# coding:utf-8
import unittest


class NumbersTest(unittest.TestCase):

    def test_even(self):
        for i in range(0, 6):
            # with self.subTest(i=i):
            print("当前参数是:%d" % i)
            self.assertEqual(i % 2, 0)


if __name__ == '__main__':
    unittest.main()
 

 

执行结果会是:

 

当前参数是:0
当前参数是:1


Ran 1 test in 0.010s

FAILED (failures=1)


0 != 1

Expected :1
Actual   :0
 <Click to see difference>

Traceback (most recent call last):
  File "C:\Program Files\JetBrains\PyCharm Community Edition 2018.3.1\helpers\pycharm\teamcity\diff_tools.py", line 32, in _patched_equals
    old(self, first, second, msg)
  File "C:\Python37\lib\unittest\case.py", line 839, in assertEqual
    assertion_func(first, second, msg=msg)
  File "C:\Python37\lib\unittest\case.py", line 832, in _baseAssertEqual
    raise self.failureException(msg)
AssertionError: 1 != 0

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Python37\lib\unittest\case.py", line 59, in testPartExecutor
    yield
  File "C:\Python37\lib\unittest\case.py", line 615, in run
    testMethod()
  File "D:\Programs\Python\Demo\unittest4\subtestDemo.py", line 15, in test_even
    self.assertEqual(i % 2, 0)


Process finished with exit code 1
 


---------------------
作者:__davieyang__
来源:优快云
原文:https://blog.youkuaiyun.com/dawei_yang000000/article/details/86327875
版权声明:本文为作者原创文章,转载请附上博文链接!

在 Python 的 `unittest` 测试框架中,`TestSuite` 是用于组织和运行多个测试用例的核心机制之一。它允许将多个测试用例或测试类组合在一起,并按照指定顺序执行[^3]。 ### 1. 创建测试套件 首先需要创建一个 `TestSuite` 实例,这可以通过调用 `unittest.TestSuite()` 来完成: ```python suite = unittest.TestSuite() ``` ### 2. 添加测试用例到测试套件 #### 单个添加测试方法 可以使用 `addTest()` 方法将单个测试方法添加到测试套件中: ```python suite.addTest(TestMathMethod('test_two_num_add')) ``` 这种方法适用于仅需执行特定的测试方法的情况[^1]。 #### 批量添加测试类中的所有测试用例 通过 `TestLoader().loadTestsFromTestCase()` 可以将某个测试类中的所有测试用例批量添加进测试套件: ```python suite.addTest(unittest.TestLoader().loadTestsFromTestCase(TestMathMethod)) ``` 该方式适合一次性加载某测试类下的全部测试用例[^1]。 #### 从模块批量加载测试用例 如果测试用例分布在不同的模块中,可以通过 `TestLoader().loadTestsFromModule()` 加载整个模块内的测试用例: ```python import test_module # 替换为实际的模块名 suite.addTest(unittest.TestLoader().loadTestsFromModule(test_module)) ``` 这种方式适用于模块内有多个测试类且需要统一执行的情况[^1]。 #### 按名称添加测试用例 还可以通过 `TestLoader().loadTestsFromName()` 指定具体的测试用例名称进行加载: ```python suite.addTest(unittest.TestLoader().loadTestsFromName('test_two_num_sub', test_module)) ``` 此方法适合只关注特定测试用例时使用。 #### 使用 discover 动态发现并加载测试用例 最后,`discover` 方法可以根据文件路径动态发现符合命名规则的测试模块,并自动加载其中的测试用例: ```python suite.addTest(unittest.TestLoader().discover(r'path_to_test_directory', pattern='test_*')) ``` 这种策略非常适合项目规模较大、测试用例分布广泛时使用,可以避免手动逐个添加测试用例。 ### 3. 执行测试套件 一旦测试用例被成功添加到测试套件中,就可以通过 `TextTestRunner` 来执行这些测试: ```python runner = unittest.TextTestRunner() runner.run(suite) ``` 这段代码会输出详细的测试执行结果,包括每个测试用例的状态(成功、失败或错误)以及总的测试统计信息[^2]。 ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值