Python unittest:如何只运行测试文件的部分内容?

89 投票
16 回答
68174 浏览
提问于 2025-04-15 12:36

我有一个测试文件,里面有一些测试需要花费比较长的时间(因为它们要把计算任务发送到一个集群,然后等待结果)。这些测试都在一个特定的 TestCase 类里面。

因为这些测试耗时较长,而且出错的可能性不大,所以我想要能够选择是否运行这一部分测试(最好的方法是通过命令行参数,比如 "./tests.py --offline" 之类的),这样我就可以经常快速地运行大部分测试,而在有时间的时候再运行全部的测试。

目前,我只是用 unittest.main() 来启动测试。

16 个回答

25

我正在使用一个简单的 skipIf 来实现这个功能:

import os

SLOW_TESTS = int(os.getenv('SLOW_TESTS', '0'))

@unittest.skipIf(not SLOW_TESTS, "slow")
class CheckMyFeature(unittest.TestCase):
    def runTest(self):
        …

这样我只需要在已经存在的测试案例上加上一行代码(不需要创建测试套件或类似的东西,只需在我的单元测试文件开头加上这一行 os.getenv()),这样默认情况下这个测试就会被跳过。

如果我想尽管这个测试很慢还是执行它,我只需像这样调用我的脚本:

SLOW_TESTS=1 python -m unittest …
102

如果你只想运行一个特定的测试,可以使用:

python -m unittest test_module.TestClass.test_method

更多信息可以在 这里 找到。

55

默认情况下,unittest.main()会使用默认的测试加载器,从当前运行的模块中创建一个测试套件。

不过,你不一定要使用这个默认的方式。

比如,你可以创建三个不同的 unittest.TestSuite 实例。

  1. 第一个是“快速”测试集。

    fast = TestSuite()
    fast.addTests(TestFastThis)
    fast.addTests(TestFastThat)
    
  2. 第二个是“慢速”测试集。

    slow = TestSuite()
    slow.addTests(TestSlowAnother)
    slow.addTests(TestSlowSomeMore)
    
  3. 第三个是“全部”测试集。

    alltests = unittest.TestSuite([fast, slow])
    

注意,我调整了测试用例的名称,以便区分快速和慢速测试。你可以通过继承 unittest.TestLoader 来解析类的名称,从而创建多个加载器。

然后,你的主程序可以使用 optparseargparse(从2.7或3.2版本开始提供)来解析命令行参数,选择你想运行的测试集,可以是快速的、慢速的,或者全部的。

或者,你也可以相信 sys.argv[1] 是三个值中的一个,然后用简单的方式来处理,比如这样:

if __name__ == "__main__":
    suite = eval(sys.argv[1])  # Be careful with this line!
    unittest.TextTestRunner().run(suite)

撰写回答