我的用例是远程(RESTful API等)测试整个系统的子系统。这意味着“pytest test only package”对生产代码没有任何依赖性(意味着其他生产代码python包)。
我创建了一个python包,它只包含测试相关的东西,如pytest测试,pytest fixtures,util模块中的测试帮助函数,pytests conftest.py
,pytests pytest.ini
等。它不包含任何生产代码相关的东西。
现在功能正在运行,但包的结构非常“hacky”。这意味着安装无法正常工作(测试,夹具和conftest文件未通过site_packages
正确安装到MANIFEST.ini
),并且必须“手动”完成软件包的部署。
在pytest文档中,我刚刚找到了有关如何构建包含production和pytest测试代码的包的最佳实践:Tests outside application code,Tests as part of application code和Test directory structure。
可能的解决方案2.: avocado-framework 在setup.py
中将example tests部署为data files。 Dependent on the configuration默认情况下,测试会部署到/usr/share/avocado/tests
。
答案 0 :(得分:2)
我认为,您有三个要求:
考虑到这一点,我将如何构建项目:创建一些虚拟包(但具有唯一可区分的名称)并将测试目录放在那里,以及 import itertools
min_length = 2
max_length = 5
s = 'ABCDEF'
for i in range(min_length, max_length):
print('length', i, 'cominations')
print([_ for _ in itertools.combinations(s, i)])
和实用程序模块。这是它的样子:
conftest.py
project/
├── setup.py
└── mypkg/
├── __init__.py
└── tests/
├── conftest.py
├── utils.py
├── other_utils.py
├── test_spam.py
├── test_eggs.py
└── other_tests/ # if you need to further grouping of tests
├── conftest.py # if you need special conftest for other tests
└── test_bacon.py
setup.py
有了这个项目结构:
在from setuptools import setup
setup(
name='mypkg-tests',
version='0.1',
install_requires=['pytest'],
packages=['mypkg'],
package_data={'mypkg': ['tests/*', 'tests/**/*']},
)
dir:
project/
当您构建源tar或wheel并安装软件包时,通过提供软件包名称可以轻松运行测试:
$ pytest -v
============================= test session starts =============================
platform darwin -- Python 3.6.3, pytest-3.3.2, py-1.5.2, pluggy-0.6.0 -- /Users
/hoefling/.virtualenvs/stackoverflow/bin/python
cachedir: .cache
rootdir: /Users/hoefling/projects/private/stackoverflow/so-48111426, inifile:
plugins: forked-0.2, asyncio-0.8.0, xdist-1.22.0, mock-1.6.3, hypothesis-3.44.4
collected 3 items
spam/tests/test_eggs.py::test_foo PASSED [ 33%]
spam/tests/test_spam.py::test_bar PASSED [ 66%]
spam/tests/other_tests/test_bacon.py::test_baz PASSED [100%]
========================== 3 passed in 0.03 seconds ===========================
您将获得完全相同的测试结果,因为$ pytest -pyargs mypkg
...
发现测试的方式与在本地运行测试的方式相同,而不是扫描当前工作目录,包的目录将是扫描。
虽然所有测试以及config和utils都安装在pytest
中,但它们本身不是包或模块。对于外部世界,分发仅包含空包site-packages
; mypkg
中的任何内容都不可导入,只有tests/
可见。
pytest
不可靠当然,您可以在设置脚本中声明类似的内容:
data_files
首先,创建和维护要包含的测试列表并不方便(尽管可以使用setup(
...
data_files=[
('tests', ['tests/test_spam.py', 'tests/test_eggs.py']), # etc
]
)
编写某种自定义测试查找或者os.walk
或其他)。但更重要的是,您无法将pathlib.glob
可靠地安装到绝对路径上。我想在这里详细介绍一下;请随时查看my other answer以获取更多信息 - 但基本上,data_files
包会将wheel
到data_files
中的每个绝对路径相对化,即使你构建了一个源代码分发,sys.prefix
将首先构建一个轮子,然后安装轮子。因此,如果要从已安装的软件包运行测试,首先需要确定pip install
并自行构建路径:
sys.prefix
避免$ SYS_PREFIX=$(python -c "import sys; print(sys.prefix)")
$ pytest -v $SYS_PREFIX/whatever/dir/mapped/in/data_files/tests
问题的唯一方法是构建源代码分发并使用wheel
进行安装。此选项将强制pip install mypkg --no-binary=mypkg
跳过车轮构建步骤并直接从源安装。只有这样,测试才会安装到绝对路径上。我发现它非常不方便,因为有时你会忘记pip
arg,并会花时间寻找错误源。或者有人必须安装包,而你不在那里指导他,并且无法运行测试。只是不要使用no-binary
。