使用典型的测试目录结构运行unittest
甚至一个简单的Python模块的通用目录结构似乎是将单元测试分离到他们自己的test
目录中:
new_project/
antigravity/
antigravity.py
test/
test_antigravity.py
setup.py
etc.
例如看到这个Python项目howto。
我的问题只是实际运行测试的常用方法是什么? 我怀疑这对除我以外的所有人都是显而易见的,但是您不能仅仅从测试目录运行python test_antigravity.py
,因为import antigravity
python test_antigravity.py
将失败,因为模块不在路径上。
我知道我可以修改PYTHONPATH和其他搜索路径相关的技巧,但我不能相信这是最简单的方法 - 如果你是开发者,这很好,但如果他们只想检查测试,那么期望用户使用它就不现实了。通过。
另一种方法是将测试文件复制到另一个目录中,但它似乎有点笨拙,并且错过了将它们放在单独目录中的一点。
所以,如果你刚刚将源代码下载到我的新项目中,你将如何运行单元测试? 我更喜欢一个答案,让我对我的用户说:“运行单元测试做X.”
我认为最好的解决方案是使用unittest
命令行界面,该界面将目录添加到sys.path
因此您不必(在TestLoader
类中完成)。
例如,对于像这样的目录结构:
new_project
├── antigravity.py
└── test_antigravity.py
你可以运行:
$ cd new_project
$ python -m unittest test_antigravity
对于像你这样的目录结构:
new_project
├── antigravity
│ ├── __init__.py # make it a package
│ └── antigravity.py
└── test
├── __init__.py # also make test a package
└── test_antigravity.py
在test
包内的测试模块中,您可以照常导入antigravity
包及其模块:
# import the package
import antigravity
# import the antigravity module
from antigravity import antigravity
# or an object inside the antigravity module
from antigravity.antigravity import my_object
运行一个测试模块:
要运行一个测试模块,在这种情况下是test_antigravity.py
:
$ cd new_project
$ python -m unittest test.test_antigravity
只需引用测试模块的方式与导入它的方式相同。
运行单个测试用例或测试方法:
您也可以运行单个TestCase
或单个测试方法:
$ python -m unittest test.test_antigravity.GravityTestCase
$ python -m unittest test.test_antigravity.GravityTestCase.test_method
运行所有测试:
你也可以使用测试发现来发现和运行你所有的测试,它们必须是名为test*.py
(可以用-p, --pattern
标志改变)的模块或者包:
$ cd new_project
$ python -m unittest discover
这将运行test
包内的所有test*.py
模块。
对于您的用户来说,最简单的解决方案是提供一个可执行脚本( runtests.py
或其他一些),用于引导必要的测试环境,包括(如果需要)临时将根项目目录添加到sys.path中。 这不需要用户设置环境变量,像这样的东西可以在引导脚本中正常工作:
import sys, os
sys.path.insert(0, os.path.dirname(__file__))
然后,您的用户指令可以像“python runtests.py”一样简单。
当然,如果你真正需要的路径是os.path.dirname(__file__)
,那么你根本不需要将它添加到sys.path
; Python总是将当前正在运行的脚本的目录放在sys.path
的开头,因此根据目录结构的不同,只需在适当的地方找到runtests.py
就可以了。
此外,Python 2.7+中的unittest模块(针对Python 2.6及更早版本,它作为unittest2反向移植)现在具有内置的测试发现功能,因此如果您希望自动发现测试,则不再需要鼻子:您的用户指令可以像“python -m unittest discover”。
我通常在加载我的“所有测试”套件的项目目录(源目录和test
共同的目录)中创建一个“运行测试”脚本。 这通常是样板代码,所以我可以在项目中重复使用它。
run_tests.py:
import unittest
import test.all_tests
testSuite = test.all_tests.create_test_suite()
text_runner = unittest.TextTestRunner().run(testSuite)
test / all_tests.py(从我如何在目录中运行所有Python单元测试?)
import glob
import unittest
def create_test_suite():
test_file_strings = glob.glob('test/test_*.py')
module_strings = ['test.'+str[5:len(str)-3] for str in test_file_strings]
suites = [unittest.defaultTestLoader.loadTestsFromName(name)
for name in module_strings]
testSuite = unittest.TestSuite(suites)
return testSuite
有了这个设置,你的确include antigravity
在你的测试模块中include antigravity
。 缺点是你需要更多的支持代码来执行特定的测试......我只是每次都运行它们。