背景
我在一个conftest文件中运行一个py.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')
- 对照品py**
import pytest
@pytest.fixture
def platform_external():
return "android"
问题
现在我希望能够跳过一些不适用于我当前测试运行的测试。在我的示例中,我正在运行iOS或Android的测试(这仅用于演示目的,可以是任何其他表达式)。
不幸的是,我无法在skipif
语句中获取(我的 * external * definedfixture)platform_external
。我不知道这是否是一个py。测试bug,因为 * 本地 * 定义的fixture正在工作。
- 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')
所以我想我将创建我自己的装饰器,只是为了确保它不会接收fixture作为参数:
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文件中定义一个fixture并使用它(有条件地)跳过一个测试?
4条答案
按热度按时间ttvkxqim1#
在为
skipif
计算表达式时,py.test似乎没有使用测试fixture。在您的示例中,test_ios
实际上是成功的,因为它将在模块的命名空间中找到的函数platform
与"ios"
字符串进行比较。其评估结果为False
,因此测试执行并成功。如果pytest按照您的预期插入fixture进行评估,则应该跳过该测试。您的问题(不是您的问题)的一个解决方案是实现一个fixture,该fixture检查测试中的标记,并相应地跳过它们:
一个关键点是
autouse
参数,它会使fixture自动包含在所有测试中,然后您的测试可以标记哪些平台跳过,如下所示:sh7euo9m2#
Bruno Oliveira的解决方案是可行的,但是对于新的pytest(〉= 3.5.0),您需要添加pytest_configure:
use:
yeotifhr3#
从这个answer中得到的灵感用于另一个SO问题,我使用这个方法来解决这个问题,效果很好:
vecaoik14#
我有一个类似的问题,我不知道这是否仍然与您相关,但我可能已经找到了一个变通办法,将做你想要的。
其思想是扩展
MarkEvaluator
类并覆盖_getglobals
方法,以强制在evaluator使用的全局集中添加fixture值:添加一个钩子到测试调用:
那么你可以在你的测试用例中使用标记
skipif_call
:不幸的是,这对于每个求值表达式只起作用一次,因为MarkEvaluator使用基于表达式的缓存eval作为键,所以下次测试相同的表达式时,结果将是缓存的值。
表达式在
_istrue
方法中求值。遗憾的是,无法配置求值器以避免缓存结果。避免缓存的唯一方法是覆盖_istrue
方法,使其不使用cached_eval函数:现在测试被跳过,因为'myfixture'值已经更新。
希望有帮助。
干杯
亚历克斯