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

标签 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()

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

python 控制台中的 import tests 是否应该启动所有单元测试?

最佳答案

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

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

关于包和模块结构的进一步问题,我建议您阅读 Official Python Documentation on Packages .

单元测试被构造成测试套件,其中可以包含一个或多个由一个或多个测试组成的测试用例。

测试通常是 TestCase 派生类的方法。您可以通过定义 runTest() 方法或定义多个 test_* 方法来运行测试,这些方法将自动执行。要执行单元测试,您可以使用便利函数 unittest.main(),它基本上尝试使用默认规则构建测试套件、测试结果和测试运行器对象。

单元测试本身的执行是由测试运行器对象完成的。标准的测试运行器类是 TextTestRunner,它使用 TextTestResult 类来存储测试结果并将它们打印到 stdout。参见 Official unittest Documentation for unittest.main()对于最简单的变体。

总结

1) 单元测试基本上是一个包含一个或多个测试用例的测试套件:

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

2) 测试用例是 unittest.TestCase 的子类。您可以使用加载器(例如:unittest.defaultTestLoader)创建测试套件,它基本上是测试套件的工厂,或者您可以手动添加测试用例(suite.addTest(test)/suite.addTests(tests) - tests 可以是 TestCases 或什至其他 TestSuites) 或通过组合这两种方法。

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

通常您会使用 unittest.TextTestRunner-object 将测试结果简单输出到标准输出。

这正是您的主例程中发生的事情:

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()

要执行您的测试套件,您必须执行 python __init__.py

关于python - 在 Python 的测试包中运行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8728426/

相关文章:

python - 扫描字符串文字错误时 EOL

python - 如何在Python中提取最后一行文本(不包括新行)?

python - 检查是否使用不同参数多次调用函数

python - 如何使用 web 插件将 JSON 有效负载发送到 RabbitMQ?

python - 在 python 中使用这段代码有什么好处? (先设置 i = [0],然后设置 i[0] += size)

python - 通过同一列连接多个 pandas 数据框并求和

c++ - 在 C++ 中模拟非类方法

unit-testing - 如何测试windows phone 7 类库?

python - 如何模拟 psycopg2 光标对象?

c# - 我应该如何使用 C# 和 NUnit 对单元测试进行分组?