在Python中运行测试包中的单元测试

Gor*_*tch 2 python unit-testing

我试图用Python编写一个解析器,用于特殊的文本文件格式.为了了解如何构造代码,我查看了JSON解析器的源代码,它是Python标准库(Python/Lib/json)的一部分.

在这个json目录中有一个tests目录,它包含许多单元测试.我用我的测试替换了json测试,但现在我不知道如何调用它们.

查看目录有一个__init__.py文件使它成为一个模块,在这个文件里面有以下用于运行测试的代码片段:

here = os.path.dirname(__file__)

def test_suite():
    suite = additional_tests()
    loader = unittest.TestLoader()
    for fn in os.listdir(here):
        if fn.startswith("test") and fn.endswith(".py"):
            modname = "json.tests." + fn[:-3]
            __import__(modname)
            module = sys.modules[modname]
            suite.addTests(loader.loadTestsFromModule(module))
    return suite

def additional_tests():
    suite = unittest.TestSuite()
    for mod in (json, json.encoder, json.decoder):
        suite.addTest(doctest.DocTestSuite(mod))
    suite.addTest(TestPyTest('test_pyjson'))
    suite.addTest(TestCTest('test_cjson'))
    return suite

def main():
    suite = test_suite()
    runner = unittest.TextTestRunner()
    runner.run(suite)

if __name__ == '__main__':
    sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
    main()
Run Code Online (Sandbox Code Playgroud)

我现在的问题是如何执行这些单元测试?我感到困惑,因为if __name__ == '__main__':如果直接调用此文件而不将其作为模块导入,则if子句将验证为true.但是因为它在__init__.py模块的文件中,所以应该在导入后立即执行.

如果import tests在python控制台中启动所有单元测试?

Don*_*ion 6

第一:__init__.py目录中的文件将目录标记为包,.py其中包含结尾的所有其他文件都是模块.

第二:要验证__name__ == '__main__'条件,您必须执行该文件.所以一个简单的import做不到.

有关包和模块结构的进一步问题,我建议请阅读有关包官方Python文档.

单元测试结构为测试套件,可以包含一个或多个测试套件,其中包含一个或多个测试.

测试通常是TestCase派生类的方法.您可以通过定义runTest()方法或定义多个test_*方法来运行测试,这些方法将自动执行.要执行Unittest,您可以使用unittest.main()基本尝试通过使用default-rules构建testsuite,testresult和testrunner对象的便捷函数.

您的unittest本身的执行由testrunner对象完成.标准的testrunner类是TextTestRunner,它使用TextTestResult-class来存储测试结果并将它们打印到stdout.有关最简单的变体,请参阅unittest.main()的官方单元测试文档.

摘要

1) unittest基本上是一个包含一个或多个TestCases的TestSuite:

TestSuite      <---executed by--- TestRunner
   + TestCaseA                        |
       +test_a()                      |
       +test_b()             stores test-results 
           ...                      into
       +test_z()                      |
    + TestCaseB                       V
    + TestCaseC                  TestResult
Run Code Online (Sandbox Code Playgroud)

2) TestCases是.的子类unittest.TestCase.您可以创建一个TestSuite,通过使用装载程序(如:unittest.defaultTestLoader),这基本上是一个测试套件工厂,或者您也可以手动添加的TestCase(suite.addTest(test) / suite.addTests(tests)- tests可能TestCases甚至其他TestSuites),或通过这两种方法相结合.

3)要执行测试套件,可以使用unittest.TestRunner-object将结果保存在unittest.TestResult对象中.

Normaly你会使用unittest.TextTestRunner-object将测试结果输出到stdout.

令人兴奋的是,你的主程序中也会发生什么:

def main():
    suite = test_suite()                #1 create a TestSuite object
    runner = unittest.TextTestRunner()  #2 create a TextTestRunner object
    runner.run(suite)                   #3 executes the TestSuite with TestSuite
                                        #  build by the function test_suite()
Run Code Online (Sandbox Code Playgroud)

要执行您的测试套件,您可以执行python __init__.py.