微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用外部夹具跳过pytest?

背景

我在conftest file中使用fixture运行py.test.您可以看到下面的代码(这一切正常):

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')

conftest.py

import pytest

@pytest.fixture
def platform_external():
    return "android"

问题

现在我希望能够跳过一些不适用于我当前测试运行的测试.在我的示例中,我正在为iOS或Android运行测试(这仅用于演示目的,可以是任何其他表达式).

不幸的是,我无法在skipif语句中获得(我的外部定义的fixture)platform_external.当我运行下面的代码时,我收到以下异常:NameError:未定义名称’platform_external’.我不知道这是否是py.test错误,因为本地定义的灯具正在工作.

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')

所以我想我会创建自己的装饰器,只是为了看到它不会收到灯具作为参数:

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')

如何在conftest文件中定义夹具并使用它(有条件地)跳过测试?

解决方法:

在评估skipif的表达式时,似乎py.test不使用测试夹具.通过您的示例,test_ios实际上是成功的,因为它将模块命名空间中找到的函数平台与“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))   

关键点是autouse参数,它将使所有测试自动包含该夹具.然后你的测试可以标记要跳过的平台如下:

@pytest.mark.skip_platform('ios')
def test_ios(platform, request):
    assert 0, 'should be skipped' 

希望有所帮助!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐