Python 单元测试:运行 对值列表进行相同的测试,但将它们视为单独的测试

Python unittest: run same test over a list of values, but treat them as separate tests

我正在编写一个测试来验证我的程序是否能够针对不同的复杂程度解决手头的问题。预期结果始终相同(解决方案已完成),因此单个测试定义适用于所有问题。

我如何运行 相同的测试 用于从文件读取的值列表,但告诉 unittest 将这些问题中的每一个都视为一个单独的测试,以便我可以查明所有 failing/passing 个案例?(最好没有外部库)

为了避免显式 test_solution_1, test_solution_2... test_solution_n,我最初的想法是对列表的每一项进行 for 循环 运行,并且 运行 一次一个断言:

class TestProblem(unittest.TestCase):
    def test_all(self):
        results = Counter()
        rng = 50
        for i in range(rng):
            p = Problem(matrix_index=i)  # generate instance of problem.
            p.solve()
            results[p.is_complete()] += 1  # log result of test.
            self.assertTrue(p.is_complete(), msg="Failed at %s" % str(i))
        # Now ensure all instances passed (useful when above assertion not included).
        self.assertEqual(results[True], rng, msg="SCORE: %s / %s" % (results[True], rng))

这种方法的问题是第一个失败会阻止 运行ning 中的其余部分,因此更难全面了解错误所在。

使用subTest() 上下文管理器来区分单个测试主体中的测试。 (Python 3.4+)

    def test_all(self):
        results = Counter()
        rng = 50
        for i in range(rng):
            with self.subTest(i=i):  # <----------------------
                p = Problem(matrix_index=i)  # generate instance of problem.
                p.solve()
                results[p.is_complete()] += 1  # log result of test.
                self.assertTrue(p.is_complete())
        self.assertEqual(results[True], rng, msg="SCORE: %s / %s" % (results[True], rng))

来自 PyCharm 的结果:

您可以查看每个案例的单独结果,并一次查看所有失败的案例。请注意,它仍然被视为单个逻辑测试 ("运行 1 test"),这是有道理的,因为它测试的是相同的功能。每个案例都被视为一个子测试。


其他需要考虑的事项:

  • 如果使用旧版本的 Python 或者你想使用其他库,你可以查看 ddt 通过装饰器添加测试数据 @data(3, 4, 12, 23).