python - 如何在单个 Python 单元测试中处理多个断言?

标签 python unit-testing testing unittest2

这是在执行具有多个独立故障模式的单个测试时出现的问题,这是由于具有多个输出流。我还想展示在所有这些模式下断言数据的结果,无论哪个先失败。 Python 的 unittest 除了使用 Suite 来表示单个测试之外没有这样的功能,这是 Not Acceptable ,因为我的单个测试总是需要作为单个单元运行;它只是没有捕捉到事物的本质。

一个实际的例子是测试一个也生成日志的对象。你想断言它的方法的输出,但你也想断言日志输出。这两个输出需要不同的测试,可以巧妙地表示为两个常用的断言表达式,但您也不希望其中一个的失败隐藏另一个可能失败的测试。所以您确实需要同时测试两者。

我拼凑了这个有用的小部件来解决我的问题。

def logFailures(fnList):
    failurelog = []
    for fn in fnList:
        try:
            fn()
        except AssertionError as e:
            failurelog.append("\nFailure %d: %s" % (len(failurelog)+1,str(e)))

    if len(failurelog) != 0:
        raise AssertionError(
            "%d failures within test.\n %s" % (len(failurelog),"\n".join(failurelog))
        )

像这样使用:

def test__myTest():
    # do some work here
    logFailures([
        lambda: assert_(False,"This test failed."),
        lambda: assert_(False,"This test also failed."),
    ])

结果是 logFailures() 将引发异常,其中包含在列表中的方法中引发的所有断言的日志。

问题:虽然这样做了,但我想知道是否有更好的方法来处理这个问题,而不是必须花时间创建嵌套的测试套件等等?

最佳答案

使用子测试,执行不会在第一次失败后停止 https://docs.python.org/3/library/unittest.html#subtests

这里有两个失败断言的例子:

class TestMultipleAsserts(unittest.TestCase):

    def test_multipleasserts(self):
        with self.subTest():
            self.assertEqual(1, 0)
        with self.subTest():
            self.assertEqual(2, 0)

输出将是:

======================================================================
FAIL: test_multipleasserts (__main__.TestMultipleAsserts) (<subtest>)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "./test.py", line 9, in test_multipleasserts
    self.assertEqual(1, 0)
AssertionError: 1 != 0

======================================================================
FAIL: test_multipleasserts (__main__.TestMultipleAsserts) (<subtest>)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "./test.py", line 11, in test_multipleasserts
    self.assertEqual(2, 0)
AssertionError: 2 != 0

----------------------------------------------------------------------
Ran 1 test in 0.000s

FAILED (failures=2)

您可以像下面这样轻松包装子测试

class MyTestCase(unittest.TestCase):
    def expectEqual(self, first, second, msg=None):
        with self.subTest():
            self.assertEqual(first, second, msg)

class TestMA(MyTestCase):
    def test_ma(self):
        self.expectEqual(3, 0)
        self.expectEqual(4, 0)

关于python - 如何在单个 Python 单元测试中处理多个断言?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9829331/

相关文章:

python - 使用 sklearn 进行逻辑回归

python - 使用 python pandas 注意(保存)dataset_a 和 dataset_b 的不匹配条目

android - 模拟 OkHttpClient

android - 从 JUnit 单元测试设置 android.location.Location 对象的参数

c# - 如何在测试方法中模拟按键?

Python、MongoDB、Mongoengine - 类型错误 : string indices must be integers, 不是 str

python - 如何将 TKinter 中的 .configure 压缩为一个命令?

php - 测试2个mysql数据库之间的内容

ruby-on-rails - PG::错误:错误:关系 "users"不存在

javascript - 使用 join() 或 concat 创建字符串?