对于一个简单的Python模块来说,非常常见的目录结构似乎是将单元测试分离到它们自己的测试目录中:
new_project/
antigravity/
antigravity.py
test/
test_antigravity.py
setup.py
etc.
我的问题很简单,实际运行测试的通常方式是什么?我怀疑这对每个人来说都是显而易见的,除了我,但你不能只是从测试目录运行python test_antigravity.py,因为它的导入antigravity将失败,因为模块不在路径上。
我知道我可以修改PYTHONPATH和其他与搜索路径相关的技巧,但我不能相信这是最简单的方法——如果您是开发人员,这很好,但如果用户只是想检查测试是否通过,那么期望他们使用这种方法是不现实的。
另一种替代方法是将测试文件复制到另一个目录中,但这似乎有点愚蠢,并且没有注意到将它们放在一个单独的目录中。
那么,如果您刚刚下载源代码到我的新项目,您将如何运行单元测试?我更喜欢这样的答案:“要运行单元测试,请执行x。”
如果在测试目录中有多个目录,则必须向每个目录添加__init__.py文件。
/home/johndoe/snakeoil
└── test
├── __init__.py
└── frontend
└── __init__.py
└── test_foo.py
└── backend
└── __init__.py
└── test_bar.py
然后一次运行所有测试,运行:
python -m unittest discover -s /home/johndoe/snakeoil/test -t /home/johndoe/snakeoil
来源:python -m unittest -h
-s START, --start-directory START
Directory to start discovery ('.' default)
-t TOP, --top-level-directory TOP
Top level directory of project (defaults to start
directory)
在我看来,最好的解决方案是使用unittest命令行界面,它会将目录添加到sys. exe目录。路径,因此您不必(在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
在测试包中的测试模块中,可以像往常一样导入反重力包及其模块:
# 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
$ # Also works without discover for Python 3
$ # as suggested by @Burrito in the comments
$ python -m unittest
这将运行测试包中的所有test*.py模块。
我也遇到了同样的问题,使用了一个单独的单元测试文件夹。根据上述建议,我将绝对源路径添加到sys.path中。
以下解决方案的好处是,你可以运行test/test_yourmodule.py文件,而不需要一开始就切换到test目录:
import sys, os
testdir = os.path.dirname(__file__)
srcdir = '../antigravity'
sys.path.insert(0, os.path.abspath(os.path.join(testdir, srcdir)))
import antigravity
import unittest