即使是简单的Python模块,非常常见的目录结构似乎是将单元测试分成它们自己的 test
目录:
new_project/
antigravity/
antigravity.py
test/
test_antigravity.py
setup.py
etc.
例如,见Python project howto .
我的问题只是 What's the usual way of actually running the tests? 我怀疑除了我以外,每个人都很明显,但是你不能只是从测试目录运行 python test_antigravity.py
,因为它的 import antigravity
会失败,因为模块不在路径上 .
我知道我可以修改PYTHONPATH和其他搜索路径相关的技巧,但我不能相信这是最简单的方法 - 如果你是开发人员,那就没关系,但是如果他们只是想检查测试,那么期望用户使用是不现实的通过 .
另一种选择只是将测试文件复制到另一个目录中,但它看起来有点愚蠢,并且忽略了将它们放在一个单独的目录中的重点 .
那么,如果您刚刚将源代码下载到我的新项目中,您将如何运行单元测试?我更喜欢一个能让我对用户说的答案:“运行单元测试做X.”
18 回答
Python 3
添加到@Pierre
像这样使用
unittest
目录结构:要运行测试模块
test_antigravity.py
:或单个
TestCase
Mandatory 不要忘记
__init__.py
即使是空的否则将无效 .Solution/Example for Python unittest module
鉴于以下项目结构:
您可以使用
python project_name
从根目录运行项目,该目录调用ProjectName/project_name/__main__.py
.要使用
python test
运行测试,有效地运行ProjectName/test/__main__.py
,您需要执行以下操作:1) 通过添加
__init__.py
文件将test/models
目录转换为包 . 这使得子目录中的测试用例可以从父test
目录访问 .2) 在
test/__main__.py
中修改系统路径以包含project_name
目录 .现在,您可以在测试中从
project_name
成功导入内容 .可以使用运行选定或所有测试的包装器 .
例如:
或者以递归方式运行所有测试使用globbing(
tests/**/*.py
)(由shopt -s globstar
启用) .包装器基本上可以使用
argparse
来解析参数,如:然后加载所有测试:
然后将它们添加到您的测试套件中(使用
inspect
):并运行它们:
有关详细信息,请查看this示例 .
另见:How to run all Python unit tests in a directory?
如果你运行"python setup.py develop"那么包将在路径中 . 但是你可能不想这样做,因为你可能会感染你的系统python安装,这就是为什么像virtualenv和buildout这样的工具存在的原因 .
如果您使用VS代码并且您的测试与项目位于同一级别,则运行和调试代码不能立即使用 . 你可以做的是改变你的launch.json文件:
这里的关键是envFile
在项目的根目录中添加.env文件
在.env文件中添加项目根目录的路径 . 这将暂时添加
项目的路径,您将能够使用VS Code中的调试单元测试
在我看来,最好的解决方案是使用
unittest
command line interface将目录添加到sys.path
,这样您就不必(在TestLoader
类中完成) .例如,对于像这样的目录结构:
你可以运行:
对于像您这样的目录结构:
在
test
包中的测试模块中,您可以像往常一样导入antigravity
包及其模块:Running a single test module:
要运行单个测试模块,在本例中为
test_antigravity.py
:只需像导入它一样引用测试模块 .
Running a single test case or test method:
您还可以运行单个
TestCase
或单个测试方法:Running all tests:
您还可以使用test discovery来发现并运行所有测试,它们必须是名为
test*.py
的模块或包(可以使用-p, --pattern
标志进行更改):这将运行
test
包中的所有test*.py
模块 .我有同样的问题,有一个单独的单元测试文件夹 . 从提到的建议我添加 absolute source path 到
sys.path
.以下解决方案的好处是,可以在不首先更改为test-directory的情况下运行文件
test/test_yourmodule.py
:以下是我的项目结构:
我发现在setUp()方法中导入更好:
我注意到,如果从“src”目录运行unittest命令行界面,则导入无需修改即可正常工作 .
如果要将其放在项目目录中的批处理文件中,可以执行以下操作:
我通常在项目目录(源目录和
test
共有的)中创建一个"run tests"脚本来加载我的"All Tests"套件 . 这通常是样板代码,所以我可以重用它从项目到项目 .run_tests.py:
test / all_tests.py(来自How do I run all Python unit tests in a directory?)
通过这种设置,您确实可以在测试模块中使用
include antigravity
. 缺点是你需要更多的支持代码来执行特定的测试...我每次都运行它们 .如果测试目录中有多个目录,则必须向每个目录添加
__init__.py
文件 .然后立即运行每个测试,运行:
资料来源:
python -m unittest -h
无论您在哪个工作目录中,此BASH脚本都将从文件系统中的任何位置执行python unittest测试目录 .
这在停留在
./src
或./example
工作目录中并且您需要快速单元测试时非常有用:生产环境 过程中不需要
test/__init__.py
文件来增加包/内存开销 .没有一些伏都教,你无法从父目录导入 . 这是另一种适用于至少Python 3.6的方法 .
首先,让文件test / context.py包含以下内容:
然后在文件test / test_antigravity.py中进行以下导入:
请注意,此try-except子句的原因是
使用"python test_antigravity.py"和_运行时
从new_project目录运行"python -m unittest"时
有了这个诡计他们都工作 .
现在,您可以使用以下命令在测试目录中运行 all 测试文件:
或运行单个测试文件:
好吧,它比在test_antigravity.py中使用context.py的内容更漂亮,但也许有点 . 欢迎提出建议 .
对您的用户来说,最简单的解决方案是提供一个可执行脚本(
runtests.py
或其他类似的脚本)来引导必要的测试环境,包括在需要时将您的根项目目录临时添加到sys.path . 这不需要用户设置环境变量,这样的东西在引导脚本中工作正常:然后,您对用户的指示可以像“python runtests.py”一样简单 .
当然,如果您真正需要的路径是
os.path.dirname(__file__)
,那么您根本不需要将其添加到sys.path
; Python始终将当前运行的脚本的目录放在sys.path
的开头,因此根据您的目录结构,只需将runtests.py
定位在正确的位置即可 .此外,unittest module in Python 2.7+(对于Python 2.6和更早版本反向移植为unittest2)现在内置了test discovery,因此如果您想要自动测试发现,则不再需要使用鼻子:您的用户指令可以像"python -m unittest discover"一样简单 .
从您链接的文章:
$ export PYTHONPATH = $ PYTHONPATH:/ path / to / googlemaps / googlemaps
$ python test / test_googlemaps.py
最后,还有一个更受欢迎的Python单元测试框架(它非常重要!),鼻子 . nose有助于简化和扩展内置单元测试框架(例如,它可以自动找到您的测试代码并为您设置PYTHONPATH),但它不包含在标准Python发行版中 .
也许你应该看看它建议的nose?
使用
setup.py develop
使您的工作目录成为已安装的Python环境的一部分,然后运行测试 .我使用Python 3.6.2
要安装pytest:
sudo pip install pytest
我没有设置任何路径变量,我的导入没有失败,具有相同的“测试”项目结构 .
我评论了这个东西:
if __name__ == '__main__'
像这样:test_antigravity.py
你应该真的使用pip工具 .
使用
pip install -e
在开发模式下安装软件包 . 这是一个非常好的做法 .在下面给出的参考网址中,给出了2个经典项目(带测试)布局,您可以按照其中任何一个进行操作 .
Ref :