我正在尝试用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
是否应该启动所有单元测试?
答案 0 :(得分:6)
首先:目录中的__init__.py
文件将目录标记为包,其中以.py
结尾的所有其他文件都是模块。
第二:要验证__name__ == '__main__'
条件,您必须执行该文件。所以一个简单的import
不会做。
关于包和模块结构的进一步问题,我建议你阅读Official Python Documentation on Packages。
单元测试结构为测试套件,可包含一个或多个测试套件,其中包含一个或多个测试。
测试通常是TestCase派生类的方法。您可以通过定义runTest()
方法或定义多个test_*
方法来运行测试,这些方法将自动执行。要执行Unittest,您可以使用便捷函数unittest.main()
,它基本上尝试使用默认规则构建一个testsuite,testresult和testrunner对象。
您的unittest本身的执行由testrunner对象完成。标准testrunner类是TextTestRunner
,它使用TextTestResult
- 类来存储测试结果并将它们打印到stdout
。有关最简单的变体,请参阅Official unittest Documentation for unittest.main()。
1)单元测试基本上是一个包含一个或多个TestCase的TestSuite:
TestSuite <---executed by--- TestRunner
+ TestCaseA |
+test_a() |
+test_b() stores test-results
... into
+test_z() |
+ TestCaseB V
+ TestCaseC TestResult
2) TestCases是unittest.TestCase
的子类。您可以使用加载器(例如:unittest.defaultTestLoader
)创建TestSuite,该加载器基本上是测试套件的工厂,或者您可以手动添加TestCases(suite.addTest(test) / suite.addTests(tests)
- tests
可能是{ {1}}或甚至其他TestCases
)或将这两种方法结合起来。
3)要执行测试套件,请使用TestSuites
- 对象,将结果保存在unittest.TestRunner
对象中。
Normaly你会使用unittest.TestResult
- object来获得测试结果到stdout的简单输出。
令人兴奋的是你的主程序中也会发生什么:
unittest.TextTestRunner
要执行测试套件,您必须执行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()
。