对于一个简单的Python模块来说,非常常见的目录结构似乎是将单元测试分离到它们自己的测试目录中:

new_project/
    antigravity/
        antigravity.py
    test/
        test_antigravity.py
    setup.py
    etc.

我的问题很简单,实际运行测试的通常方式是什么?我怀疑这对每个人来说都是显而易见的,除了我,但你不能只是从测试目录运行python test_antigravity.py,因为它的导入antigravity将失败,因为模块不在路径上。

我知道我可以修改PYTHONPATH和其他与搜索路径相关的技巧,但我不能相信这是最简单的方法——如果您是开发人员,这很好,但如果用户只是想检查测试是否通过,那么期望他们使用这种方法是不现实的。

另一种替代方法是将测试文件复制到另一个目录中,但这似乎有点愚蠢,并且没有注意到将它们放在一个单独的目录中。

那么,如果您刚刚下载源代码到我的新项目,您将如何运行单元测试?我更喜欢这样的答案:“要运行单元测试,请执行x。”


当前回答

这种方式将允许您从任何您想要的地方运行测试脚本,而不会从命令行中破坏系统变量。

这将把主项目文件夹添加到python路径中,其位置相对于脚本本身,而不是相对于当前工作目录。

import sys, os

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.realpath(__file__))))

将其添加到所有测试脚本的顶部。这将把主项目文件夹添加到系统路径中,因此从那里导入的任何模块现在都可以工作了。你在哪里做测试并不重要

显然,您可以更改project_path_hack文件以匹配您的主项目文件夹位置。

其他回答

我也遇到了同样的问题,使用了一个单独的单元测试文件夹。根据上述建议,我将绝对源路径添加到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

这种方式将允许您从任何您想要的地方运行测试脚本,而不会从命令行中破坏系统变量。

这将把主项目文件夹添加到python路径中,其位置相对于脚本本身,而不是相对于当前工作目录。

import sys, os

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.realpath(__file__))))

将其添加到所有测试脚本的顶部。这将把主项目文件夹添加到系统路径中,因此从那里导入的任何模块现在都可以工作了。你在哪里做测试并不重要

显然,您可以更改project_path_hack文件以匹配您的主项目文件夹位置。

项目中的单元测试有setup.py文件。试一试:

python3 setup.py build

and

python3 setup.py develop --user

做配置路径之类的工作。试一试!

如果您正在寻找命令行解决方案:

基于以下目录结构(使用专用源目录进行概括):

new_project/
    src/
        antigravity.py
    test/
        test_antigravity.py

Windows:(在new_project中)

$ set PYTHONPATH=%PYTHONPATH%;%cd%\src
$ python -m unittest discover -s test

如果您想在批for循环中使用此语句,请参阅此问题。

Linux:(在new_project中)

$ export PYTHONPATH=$PYTHONPATH:$(pwd)/src  [I think - please edit this answer if you are a Linux user and you know this]
$ python -m unittest discover -s test

使用这种方法,还可以在必要时向PYTHONPATH添加更多目录。

如果你运行“python setup.py develop”,那么包就会在路径中。但你可能不想这样做,因为你可能会感染你的系统python安装,这就是virtualenv和buildout等工具存在的原因。