【问题标题】:How to check which pytest mark is the test running for如何检查正在运行的测试是哪个 pytest 标记
【发布时间】:2020-05-05 09:03:18
【问题描述】:

我有一个测试文件,例如:test_my_api.py

我调用 pytest 开始使用下面的命令执行,只运行带有特定标记的测试

pipenv run pytest -m "integration"

现在在我的 test_my_api.py 文件中,我有多个功能标记为“集成”

我还有一个全局变量配置如下,并在所有方法中使用这个全局值 DATA

DATA = get_my_data()

现在我有了另一个标记,叫做“smoke”,现在一些测试用例同时具有标记“smoke”和“integration”。对于烟雾,我需要如下不同的全局数据,

DATA = get_smoke_data()

问题是在运行测试用例时,我无法拆分这个测试用例被调用的标记。即用于烟雾或集成。如何在全球范围内获取此信息?

以前我知道有一个叫做标记信息的东西,例如:from _pytest.mark import MarkInfo,但现在它被删除了。这仅在每种方法中可用我怎样才能在全局级别上获得它

【问题讨论】:

  • 我不确定我是否理解你的问题:“这个测试用例被调用的标记是什么”是什么意思?你的意思是如果你过滤测试,测试必须知道使用了哪个过滤器?你能解释一下你想达到什么目标吗?
  • 是的,正确的过滤了我们执行的这个测试。即如果我可以用 2 个过滤器标记一个测试用例,并且在运行时我将只指定一个过滤器(即标记),所以在运行时我想知道这个测试用例正在执行哪个过滤器
  • 所以你想根据调用它的过滤器来改变测试的行为吗?例如。如果 pytest 过滤integration 一种行为,如果它过滤smoke,并且如果在没有过滤器的情况下调用,还有别的吗?这听起来好像你在这里混合了两个概念 - 过滤和测试配置。我仍然不确定你想要达到什么目标,也许有更好的方法?
  • 我想知道如何获得这个值? docs.pytest.org/en/latest/…。这表示我可以使用“_pytest.nodes.Node.iter_markers()”来获取标记名称。但我不知道如何使用它没有例子
  • 这是为了获取测试函数的标记,例如,从夹具或插件中获取。这与您在 pytest 中使用的过滤器无关。取决于您实际想要做什么(仍然不知道),这可能对您有帮助,也可能对您没有帮助。

标签: python-3.x pytest


【解决方案1】:

如果我理解正确,您想知道在运行时有多个标记的测试方法调用哪个标记?

这是你要找的东西吗?

import pytest

@pytest.fixture
def my_common_fixture(request, pytestconfig):
    markers_arg = pytestconfig.getoption('-m')
    request.cls.marker_name = markers_arg


class TestSmokeIntegration:
    @pytest.mark.smoke
    @pytest.mark.integration
    def test_for_smoke_integration(self, my_common_fixture):
        print("marker used: ", self.marker_name)
        assert True

    def test_somthing_else(my_common_fixture):
        assert True
pytest -vvv -s test_marker.py -m smoke

输出:

test_marker.py::TestSmokeIntegration::test_for_smoke_integration markers used:  smoke
PASSED
pytest -vvv -s test_marker.py -m integration

输出:

test_marker.py::TestSmokeIntegration::test_for_smoke_integration marker used:  integration
PASSED

【讨论】:

  • 这对我来说效果很好。只是一个建议——如果你在你的夹具装饰器中添加autouse=True,那么你不需要将它作为参数传递给你的测试函数。
【解决方案2】:

如果您希望能够支持标记表达式,例如-m foo OR bar 或动态添加的标记(即add_marker()),那么您可能需要更精细的东西:

@pytest.fixture(scope="function")
def active_marks(request):

  # Collect all the marks for this node (test)
  current_node = request.node
  marks = []
  while current_node:
    marks += [mark.name for mark in current_node.iter_markers()]
    current_node = current_node.parent

  # Get the mark expression - what was passed to -m
  markExpr = request.config.option.markexpr

  # Compile the mark expression
  from _pytest.mark.expression import Expression
  compiledMarkExpr = Expression.compile(markExpr)

  # Return a sequence of markers that match
  return [ mark for mark in marks if compiledMarkExpr.evaluate( lambda candidate: candidate == mark ) ]


class TestClass:
  def test_foo(active_marks):
    print(f"Active marks are {active_marks}")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-23
    • 2011-05-04
    • 2020-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-01
    相关资源
    最近更新 更多