【问题标题】:Python unittest: make AssertionError an error instead of a failurePython unittest:使 AssertionError 成为错误而不是失败
【发布时间】:2019-03-25 11:31:08
【问题描述】:

Python 2.7。 The unittest doc 说:

为了更轻松地迁移现有测试套件,unittest 支持测试引发 AssertionError 以指示测试失败。但是,建议您改用显式 TestCase.fail*() 和 TestCase.assert*() 方法,因为未来版本的 unittest 可能会以不同的方式处理 AssertionError。

我在测试代码中使用了很多 assert 语句,但这些断言失败应该是测试错误(即“代码没有正确运行这些输入”)而不是失败(即“代码给出错误的输出”)。

我可以看到以下可能的解决方案:

  1. 重写测试代码以抛出类型更好的异常
  2. 将除测试断言本身 (self.assertSomething(...)) 之外的所有内容都封装在测试方法中,并放在 try...except AssertionError: raise SomeOtherException 块中
  3. 更改 unittest 的行为,使其考虑这些错误而不是失败。

选项 1 需要相当长的时间,选项 2 感觉很老套;选项 3 对我来说是最好的,但它可用吗? (以防万一:不,我无法切换到 Python 3。)我在网上看不到任何内容,但很难使用特定的关键字。

MWE:

import unittest


def add_one_to_int(a):
    assert isinstance(a, int)
    return a + 1


class TestAddOne(unittest.TestCase):
    def test_one_plus_one_is_three(self):
        # This tests fails with
        #   AssertionError: 2 != 3
        # which is fine
        self.assertEqual(add_one_to_int(1), 3)  

    def test_add_one_to_str(self):
        # This tests fails with
        #   AssertionError
        # when I would rather have it an error
        add_one_to_int('some string')

if __name__ == '__main__':
    unittest.main(verbosity=2)  # 2 failures instead of 1 failure, 1 error

【问题讨论】:

    标签: python python-unittest


    【解决方案1】:

    我认为选项 3 可以通过类属性“failureException”来实现,正如 Python 2.7 的 unittest 文档中所定义的那样:

    失败异常: 此类属性给出了测试方法引发的异常。如果一个测试框架需要使用一个特殊的异常,可能携带额外的信息,它必须子类这个异常以便与框架“公平竞争”。该属性的初始值为 AssertionError。

    例如:

    import unittest
    
    class MyException(Exception): 
        pass
    
    class MyUnitTest(unittest.TestCase):
        failureException = MyException
    
    def add_one_to_int(a):
        assert isinstance(a, int)
        return a + 1
    
    
    class TestAddOne(MyUnitTest):  # <--------- See above
        def test_one_plus_one_is_three(self):
            # This tests fails with
            #   AssertionError: 2 != 3
            # which is fine
            self.assertEqual(add_one_to_int(1), 3)  
    
        def test_add_one_to_str(self):
            # This tests fails with
            #   AssertionError
            # when I would rather have it an error
            add_one_to_int('some string')
    
    if __name__ == '__main__':
        unittest.main(verbosity=2)  # ------> FAILED (failures=1, errors=1)
    

    【讨论】:

    • 成功了。只是为了挑剔:我使用MyException(AssertionError) 子类化而不是MyException(Exception),因为我觉得它更精确(尽管它可能无关紧要)。
    猜你喜欢
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 2016-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-12
    • 1970-01-01
    相关资源
    最近更新 更多