未加载功能级别上的Python behavior fixture



这在一定程度上与这个问题有关,但在下面的这个最小示例中,我还有一些进一步的问题。

对于一个功能测试,我准备了一个夹具,它备份了一个文件,该文件将在测试运行期间进行修改(例如,添加了一行(。测试运行后,此fixture将恢复原始文件。

项目文件:

└───features
│   environment.py
│   modify_file.feature
│
└───steps
file_ops.py
#!/usr/bin/env python
# FILE: features/environment.py
import logging
from behave import fixture
from behave.runner import Context
logger = logging.getLogger(__name__)

@fixture
def backup_file(context: Context):
"""
A file will be modified during the feature test.
This fixture shall backup the file before the feature test
and restore the backup after the test.
"""
file = Path.home() / "important.txt"
backup_suffix = ".backup"
file.touch()
file.replace(file.with_suffix(backup_suffix))
logger.info("File backed up")
yield
file.with_suffix(backup_suffix).replace(file)
logger.info("File restored")
# FILE: features/modify_file.feature
@fixture.backup.file
Feature: Modify file
@wip
Scenario: Append a line to a file
Given the file exists
When I append a line to the file
Then the line appears at the end of the file
#!/usr/bin/env python
# File features/steps/file_ops.py
from pathlib import Path
from behave import given
from behave import when
from behave import then
from behave.runner import Context
import logging
logger = logging.getLogger(__name__)
file = Path.home() / "important.txt"

@given("the file exists")
def step_impl(context: Context):
logger.info(f"Touching file")
file.touch()

@when("I append a line to the file")
def step_impl(context: Context):
logger.info(f"Appending a line to file")
context.appended = "Test line appendedn"
with open(file, mode="a") as f:
f.write(context.appended)

@then("the line appears at the end of the file")
def step_impl(context: Context):
logger.info(f"Checking if line was appended")
with open(file, mode="r") as f:
for line in f:
pass
logger.info(f"Last line is '{line.strip()}'")
assert line == context.appended

我想在运行所有场景之前,在功能级别应用fixture。所有场景运行后,应恢复文件。然而,情况显然并非如此。

当我运行behave -w(没有日志捕获,只有wip标记(时,我看不到来自正在输出的fixture的任何日志行,而且每次运行时,我都会看到另一行附加到文件中。这意味着没有备份和还原文件。即使在中我将设备向下移动到场景级别的modify_file.feature文件,也不会应用设备。

你能帮我了解一下这里发生了什么吗?我也很好奇为什么fixture标签使用点符号(@fixture.backup.file(而不是(fixture.backup_file(,因为这与实际的函数名称相似。行为文档中没有对此进行解释。

我在设置fixture时也遇到了问题,因为文档不太清楚必须显式启用它们。在features/environment.py中有@fixture装饰是不够的。您还必须致电use_fixture()。例如,在before_tag()内部,如下所示:

def before_tag(context, tag):
if tag == "fixture.backup.file":
use_fixture(backup_file, context)

这个例子帮助我明白了这一点:https://github.com/behave/behave/blob/main/features/fixture.feature#L16

以下是如何在没有@fixture的情况下,只需使用before_tag挂钩:

#!/usr/bin/env python
# FILE: features/environment.py
import logging
from behave.runner import Context
from behave.model import Tag
from pathlib import Path
logger = logging.getLogger(__name__)

def rename_file(origin: Path, target: Path) -> tuple[Path, Path]:
"""
Will rename the `origin` to `target`, replaces existing `target`
"""
origin.touch()
backup = origin.replace(target)
logger.info(f"File {str(origin)} renamed to {str(target)}")
return origin, backup

def before_tag(context: Context, tag: Tag):
if tag == "backup.file.important.txt":
file = Path.home() / "important.txt"
backup = file.with_suffix(".backup")
context.file, context.backup_file = rename_file(file, backup)
context.add_cleanup(rename_file, context.backup_file, context.file)
#!/usr/bin/env python
# File features/steps/file_ops.py
from pathlib import Path
from behave import given
from behave import when
from behave import then
from behave.runner import Context
import logging
logger = logging.getLogger(__name__)

@given("the file exists")
def step_impl(context: Context):
logger.info(f"Touching file")
context.file.touch()

@when("I append a line to the file")
def step_impl(context: Context):
logger.info(f"Appending a line to file")
context.appended = "Test line appendedn"
with open(context.file, mode="a") as f:
f.write(context.appended)

@then("the line appears at the end of the file")
def step_impl(context: Context):
logger.info(f"Checking if line was appended")
with open(context.file, mode="r") as f:
for n, line in enumerate(f, start=1):
logger.info(f"Line {n} is {line}")
logger.info(f"Last line is '{line.strip()}'")
assert line == context.appended

但是,使用一个fixture和fixture注册表(如behavior文档中的Realistic示例中所述(是更好的,因为以后可能会有更多的设置清理对。

最新更新