Mar*_*kov 18 python decorator pytest python-decorators
我运行py.test用夹具在conftest文件.你可以看到下面的代码(一切正常):
example_test.py
import pytest
@pytest.fixture
def platform():
return "ios"
@pytest.mark.skipif("platform == 'ios'")
def test_ios(platform):
if platform != 'ios':
raise Exception('not ios')
def test_android_external(platform_external):
if platform_external != 'android':
raise Exception('not android')
Run Code Online (Sandbox Code Playgroud)
conftest.py
import pytest
@pytest.fixture
def platform_external():
return "android"
Run Code Online (Sandbox Code Playgroud)
现在我希望能够跳过一些不适用于我当前测试运行的测试.在我的例子中,我正在为iOS或Android运行测试(这仅用于演示目的,可以是任何其他表达式).
不幸的是,我无法在声明中得到(我的外部定义夹具).当我运行下面的代码时,我收到以下异常:.我不知道这是否是py.test错误,因为本地定义的灯具正在工作.platform_external
skipif
NameError: name 'platform_external' is not defined
example_test.py的附加组件
@pytest.mark.skipif("platform_external == 'android'")
def test_android(platform_external):
"""This test will fail as 'platform_external' is not available in the decorator.
It is only available for the function parameter."""
if platform_external != 'android':
raise Exception('not android')
Run Code Online (Sandbox Code Playgroud)
所以我想我会创建自己的装饰器,只是为了看到它不会收到灯具作为参数:
from functools import wraps
def platform_custom_decorator(func):
@wraps(func)
def func_wrapper(*args, **kwargs):
return func(*args, **kwargs)
return func_wrapper
@platform_custom_decorator
def test_android_2(platform_external):
"""This test will also fail as 'platform_external' will not be given to the
decorator."""
if platform_external != 'android':
raise Exception('not android')
Run Code Online (Sandbox Code Playgroud)
如何在conftest文件中定义夹具并使用它(有条件地)跳过测试?
Bru*_*ira 28
在评估表达式时,似乎py.test不使用测试夹具skipif
.通过您的示例,test_ios
实际上是成功的,因为它将模块命名空间中找到的函数 platform
与"ios"
字符串进行比较,该字符串的计算结果False
是测试执行并成功.如果pytest正在按预期插入夹具进行评估,那么应该跳过该测试.
解决问题的方法(不是你的问题)是实现一个检测标记到测试中的夹具,并相应地跳过它们:
# conftest.py
import pytest
@pytest.fixture
def platform():
return "ios"
@pytest.fixture(autouse=True)
def skip_by_platform(request, platform):
if request.node.get_closest_marker('skip_platform'):
if request.node.get_closest_marker('skip_platform').args[0] == platform:
pytest.skip('skipped on this platform: {}'.format(platform))
Run Code Online (Sandbox Code Playgroud)
关键点是autouse
参数,这将使所有测试自动包含该夹具.然后你的测试可以标记要跳过的平台:
@pytest.mark.skip_platform('ios')
def test_ios(platform, request):
assert 0, 'should be skipped'
Run Code Online (Sandbox Code Playgroud)
希望有所帮助!
小智 6
Bruno Oliveira 的解决方案正在运行,但对于新的 pytest (>= 3.5.0),您需要添加 pytest_configure:
# conftest.py
import pytest
@pytest.fixture
def platform():
return "ios"
@pytest.fixture(autouse=True)
def skip_by_platform(request, platform):
if request.node.get_closest_marker('skip_platform'):
if request.node.get_closest_marker('skip_platform').args[0] == platform:
pytest.skip('skipped on this platform: {}'.format(platform))
def pytest_configure(config):
config.addinivalue_line(
"markers", "skip_by_platform(platform): skip test for the given search engine",
)
Run Code Online (Sandbox Code Playgroud)
用:
@pytest.mark.skip_platform('ios')
def test_ios(platform, request):
assert 0, 'should be skipped'
Run Code Online (Sandbox Code Playgroud)
使用从另一个 SO 问题的答案中获得的灵感,我正在使用这种方法来解决这个问题,效果很好:
import pytest
@pytest.fixture(scope='session')
def requires_something(request):
something = 'a_thing'
if request.param != something:
pytest.skip(f"Test requires {request.param} but environment has {something}")
@pytest.mark.parametrize('requires_something',('something_else',), indirect=True)
def test_indirect(requires_something):
print("Executing test: test_indirect")
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8067 次 |
最近记录: |