Python unittest AssertionError 没有被引发

Python unittest AssertionError not being raised

我正在尝试为我的 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 中看到单元测试报告的 AssertionError,但是,我只看到以下内容:

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

OK

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

谢谢!

构造单元测试的约定是这样的:

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

测试模块将被命名为 test_modulea.pyclass TestClassA

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

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

这会打印:

Failures: [(<exampleModule.UnitTest testMethod=runTest>, 'Traceback (most recent call last):\n File "/home/kjc/tmp/exampleModule.py", line 11, in runTest\n self.assertEqual(a, b)\nAssertionError: 4 != 5\n')]

它捕获各种异常,就像这个例子,我在断言之前添加了 sys.exit()

Errors: [(<exampleModule.UnitTest testMethod=runTest>, 'Traceback (most recent call last):\n File "/home/kjc/tmp/exampleModule.py", line 11, in runTest\n import sys; sys.exit()\nSystemExit\n')]

郑重声明,您的示例生成的通过测试是 testExample 本身。 您可以通过在 testExample 的早期调用 self.fail() 来验证这一点。 (正如一位评论员所说,从 单元测试调用单元测试 是一件非常奇怪的事情。)

一个解决方案

您似乎想要 运行 正常测试,但是来自多个文件。 如果是这样,你可以制作一堆典型的 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()

您的测试模块将是通常的一个或多个 TestCases,有条件地调用 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.