不会引发Python unittest AssertionError

时间:2018-08-08 02:05:42

标签: python unit-testing assert python-unittest

我正在尝试为我的python包编写单元测试,我发现当我运行测试时,没有引发AssertionErrors的错误,应该出现的错误。这是MWE:

在exampleModule.py中,我有:

#! /usr/bin/env python                                                                                                                                                          
import unittest

class UnitTest(unittest.TestCase):

    def runTest(self):
        print("Starting test...")
        a = 4
        b = 5
        self.assertEqual(a,b)
        print("TEST COMPLETE")
        return

,在testError.py中,我有:

#! /usr/bin/env python                                                                                                                                                          
import unittest

class AllTests(unittest.TestCase):

    def testExample(self):
        from exampleModule import UnitTest
        UT = UnitTest()
        UT.run()
        return

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

当我运行testError.py时,我希望看到exampleModule.py中UnitTest报告的AssertionError,但是,我只是看到以下内容:

> ./testError.py
Starting test...
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

为什么没有引发AssertionError?如果我将UnitTest()类放在testError.py中(即所有内容都放在同一个文件中),则会引发AssertionError。那么,为什么当UnitTest存储在另一个文件中时,错误不会出现?

谢谢!

2 个答案:

答案 0 :(得分:1)

TestCase.run() 创建或更新 TestResult 对象,假设您打算对这些结果做一些有趣的事情。 但是您立即将它们扔掉了:

    UT.run()

任何故障或错误-包括引发的异常-都会存在于该结果对象中。 例如:

def testExample(self):
    from exampleModule import UnitTest
    UT = UnitTest()
    result = UT.run()
    print('Errors:  {!r}'.format(result.errors))
    print('Failures:  {!r}'.format(result.failures))
    return

此打印:

  

失败:[(,'跟踪(最近一次通话最近):\ n文件“ /home/kjc/tmp/exampleModule.py”,第11行,在runTest \ n self.assertEqual(a,b)\ n AssertionError:4!= 5 \ n')]

它捕获了各种异常,例如本示例,其中我在断言之前添加了sys.exit()

  

错误:[(,'跟踪(最近一次通话最后一次):\ n文件“ /home/kjc/tmp/exampleModule.py”,第11行,在runTest \ n import sys; sys.exit()\ n SystemExit \ n')]

为便于记录,您的示例所产生的一项通过测试是testExample本身。 您可以通过在self.fail()的早期致电testExample来进行验证。 (正如一位评论员所说,从单元测试 调用单元测试是一件很奇怪的事情。)

一个解决方案

您似乎想正常运行测试,但是要从多个文件运行。 如果是这样,您可以制作一堆典型的 unittest.main()样式 测试模块,然后手动加载它们。 您的所有测试脚本如下所示:

#!/usr/bin/env python
import unittest


# Edit this to include new modules or TestCases to run.
_NAMES = ['testmoda', 'testmodb']  # testothermodule.SomeTestCase, etc...


def _main():
    suite = unittest.defaultTestLoader.loadTestsFromNames(_NAMES)
    unittest.TextTestRunner().run(suite)
    return  # WARNING: This always returns a successful exit value.


if __name__ == '__main__':
    _main()

您的测试模块将是通常的一个或多个TestCase,并有条件地调用unittest.main(),因此每个模块都可以独立运行:

#!/usr/bin/env python
import unittest


class TestModA(unittest.TestCase):

    def testThatPasses(self):
        self.assertEqual(0, -0)
        return

    def testThatFails(self):
        self.assertEqual(0, float('inf'))
        return

    def testThatBlowsUp(self):
        raise RuntimeError('OMG!')
        return


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

如果这还不够适合您,您还可以阅读 discover() method 或模块级 load_tests protocol

答案 1 :(得分:0)

构造单元测试的约定如下:

将所有测试保存在tests目录中。

测试模块将以test_modulea.py命名为class TestClassA

nosetests -vw tests以运行所有测试。