Lov*_*ode 7 python testing pytest
我正在使用 Pytest 测试多个版本的组件。有些测试可以在所有版本上运行,有些是特定于版本的。例如
tests
|
|-- version1_tests
| |-- test_feature_1_1.py
| |-- test_feature_1_2.py
| |-- test_feature_1_n.py
|
|-- version2_tests
| |-- test_feature_2_1.py
| |-- test_feature_2_2.py
| |-- test_feature_2_n.py
|
|-- common_tests
| |-- test_feature_common_1.py
| |-- test_feature_common_2.py
| |-- test_feature_common_n.py
Run Code Online (Sandbox Code Playgroud)
我想标记我的测试,以便我可以选择是否要从命令行测试版本 1 (version1_tests + common_tests) 或版本 2 (version2_tests + common_tests)。
我目前这样做的方式是针对每个测试模块,我添加一个 pytest 标记,然后从命令行指定标记。例如,在test_feature_1_1.py:
import pytest
pytestmark = pytest.mark.version1
class TestSpecificFeature(object):
...
Run Code Online (Sandbox Code Playgroud)
然后运行: python -m pytest -m "common and version1"
这工作正常,但我必须手动将标记添加到每个模块,这很乏味,因为实际上有几十个(而不是示例中的 3 个)。
我们曾经使用 Robot Framework,通过在__init__.robot文件中添加标签来“标记”整个文件夹是微不足道的。在 Pytest 中是否有任何等效的方法可以做到这一点,或者是否将每个模块标记为我能做的最好的?
hoe*_*ing 11
您可以在运行时使用item.add_marker()方法将标记注册到收集的测试中。这是在 中注册标记的示例pytest_collection_modifyitems:
import pathlib
import pytest
def pytest_collection_modifyitems(config, items):
# python 3.4/3.5 compat: rootdir = pathlib.Path(str(config.rootdir))
rootdir = pathlib.Path(config.rootdir)
for item in items:
rel_path = pathlib.Path(item.fspath).relative_to(rootdir)
mark_name = next((part for part in rel_path.parts if part.endswith('_tests')), '').rstrip('_tests')
if mark_name:
mark = getattr(pytest.mark, mark_name)
item.add_marker(mark)
Run Code Online (Sandbox Code Playgroud)
将代码写入conftest.py项目根目录并尝试:
$ pytest -m "common or version2" --collect-only -q
tests/common_tests/test_feature_common_1.py::test_spam
tests/common_tests/test_feature_common_1.py::test_eggs
tests/common_tests/test_feature_common_2.py::test_spam
tests/common_tests/test_feature_common_2.py::test_eggs
tests/common_tests/test_feature_common_n.py::test_spam
tests/common_tests/test_feature_common_n.py::test_eggs
tests/version2_tests/test_feature_2_1.py::test_spam
tests/version2_tests/test_feature_2_1.py::test_eggs
tests/version2_tests/test_feature_2_2.py::test_spam
tests/version2_tests/test_feature_2_2.py::test_eggs
tests/version2_tests/test_feature_2_n.py::test_spam
tests/version2_tests/test_feature_2_n.py::test_eggs
Run Code Online (Sandbox Code Playgroud)
仅选择了common_tests和下的测试version2_tests。
对于每个收集到的测试项,我们提取相对于项目根目录的路径(rel_path),rel_path以 结尾的第一部分_tests将用作标记名称提取的来源。例如,collect_tests是标记名称collect等的来源。一旦我们有了标记名称,我们就创建标记(使用,getattr因为我们不能使用属性访问)并通过 附加标记item.add_marker(mark)。您可以编写自己的,不那么抽象的版本,例如
for item in items:
if `common_tests` in str(item.fspath):
item.add_marker(pytest.mark.common)
elif `version1_tests` in str(item.fspath):
item.add_marker(pytest.mark.version1)
elif `version2_tests` in str(item.fspath):
item.add_marker(pytest.mark.version2)
Run Code Online (Sandbox Code Playgroud)
使用最新版本的pytest,您应该收到 ,PytestUnknownMarkWarning因为动态生成的标记未注册。查看为解决方案注册标记部分- 您可以在以下位置添加标记名称pytest.ini:
[pytest]
markers =
common
version1
version2
Run Code Online (Sandbox Code Playgroud)
或通过pytest_configure钩子动态添加它们,例如
def pytest_configure(config):
rootdir = pathlib.Path(config.rootdir)
for dir_ in rootdir.rglob('*_tests'):
mark_name = dir_.stem.rstrip('_tests')
config.addinivalue_line('markers', mark_name)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2480 次 |
| 最近记录: |