Wal*_*elt 5 python bdd pytest python-behave pytest-bdd
我想定义一个基于 PyTest-BDD 的场景大纲,其中包含多个示例。示例片段:
        Scenario Outline: front to back validation
          When tester executes access view sql query <sqlCommandProp> into av dataframe
          And tester adds investment quant id to av dataframe
          And tester reads raw file <fileNameProp> from datalake into raw dataframe
        @raw2AccessValidation
        Examples:
       |sqlCommandProp|fileNameProp|
       |sqlCommand    | fileName   |
        @raw2AccessValidation2
       Examples:
       |sqlCommandProp|fileNameProp|
       |eric          | shane      |
我想为每个示例都有单独的标签,因为我可能不想运行所有示例。
我已经尝试了上面的方法,发现多个示例都可以。但是,我似乎无法识别不同的标签,因此我无法指定要运行这两个(或更多)中的哪一个。
我问是因为这可以用 java/cucumber 引擎完成。想知道我是否使用 pytest-bdd 遗漏了什么,做错了什么?
谢谢
基于这个问题,目前还不支持。
解决方案1:利用标记并将它们注册到 pytest 挂钩中
在上述问题得到解决之前,您可以选择使用 pytest 挂钩并手动注册标记。以下代码迭代所有已注册的测试项,并根据其各自的特征文件在其上注册新标记。它依赖于 pytest-bdd 库的几个内部属性,但它甚至在库内部合并该功能之前就可以有效运行:
# conftest.py
import re
from pathlib import Path
from typing import List
import pytest
def pytest_collection_modifyitems(config: pytest.Config, items: List[pytest.Item]):
    for item in items:
        if not hasattr(item, "_pyfuncitem") or not hasattr(item, "callspec"):
            continue
        feature = item._pyfuncitem._obj.__scenario__.feature
        feature_content_lines = Path(feature.filename).read_text().splitlines()
        parameters = list(item.callspec.params["_pytest_bdd_example"].values())
        examples_start_line = None
        for i, line in enumerate(feature_content_lines):
            if "Examples:" in line:
                examples_start_line = i
                continue
            elif re.match(r"[|\s]+{}[|\s]+".format(r"[|\s]+".join(parameters)), line):
                break
        if examples_start_line is None:
            continue
        tag_match = re.search(
            r"@(?P<tag>\S+)", feature_content_lines[examples_start_line - 1]
        )
        if tag_match is None:
            continue
        tag = tag_match.group("tag")
        item.add_marker(tag)
考虑以下功能文件:
Feature: Scenario outlines
    Scenario Outline: Outlined given, when, then
        Given there are <start> cucumbers
        When I eat <eat> cucumbers
        Then I should have <left> cucumbers
        @part1
        Examples:
        | start | eat | left |
        |  12   |  5  |  7   |
        |  12   |  4  |  8   |
        @part2
        Examples:
        | start | eat | left |
        |  11   |  5  |  6   |
以及以下测试文件:
# test_scenario_outlines.py
from pytest_bdd import given, parsers, scenarios, then, when
scenarios("scenario_outlines.feature")
@given(parsers.parse("there are {start:d} cucumbers"), target_fixture="cucumbers")
def given_cucumbers(start):
    return {"start": start, "eat": 0}
@when(parsers.parse("I eat {eat:d} cucumbers"))
def eat_cucumbers(cucumbers, eat):
    cucumbers["eat"] += eat
@then(parsers.parse("I should have {left:d} cucumbers"))
def should_have_left_cucumbers(cucumbers, left):
    assert cucumbers["start"] - cucumbers["eat"] == left
您可以简单地使用标记来运行特定的示例记录:
pytest . -m part1
pytest . -m part2
注意:您应该注册标记以防止 pytest 警告。
解决方案 2:使用参数作为标签
您可以向参数表添加新列,并指定标签:
# scenario_outlines.feature
Feature: Scenario outlines
    Scenario Outline: Outlined given, when, then
        Given there are <start> cucumbers
        When I eat <eat> cucumbers
        Then I should have <left> cucumbers
        Examples:
        | start | eat | left |   tag   |
        |  12   |  5  |  7   |  part1  |
        |  12   |  4  |  8   |  part1  |
        Examples:
        | start | eat | left |   tag   |
        |  11   |  5  |  6   |  part2  |
无需编辑Python测试文件或关注tag代码中的参数。相反,只需利用该-k选项有选择地选择具有特定标签值的记录:
pytest . -k part1
pytest . -k part2
| 归档时间: | 
 | 
| 查看次数: | 1243 次 | 
| 最近记录: |