Python 在未加载的功能级别上表现夹具
Python behave fixture on feature level not loaded
这与 this question 有点相关,但我在下面的这个最小示例中还有一些其他问题。
为了功能测试,我准备了一个固定装置,它备份了一个文件,该文件将在测试期间进行修改运行(例如,附加了一行)。经过测试运行这个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 appended\n"
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
标签)时,我没有看到正在输出的夹具的任何日志行以及每个 运行 我看到文件中附加了另一行。这意味着文件没有被备份和恢复。即使在我将夹具向下移动到场景级别 modify_file.feature
文件中,也不会应用夹具。
你能帮我理解这是怎么回事吗?我也很好奇为什么夹具标签使用点符号 (@fixture.backup.file
) 而不是 (fixture.backup_file
),因为这与实际函数名称相似。 behave documentation.
中没有对此的解释
下面是不用 @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 appended\n"
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
但是使用 behave 文档中 Realistic example 中描述的夹具和夹具注册表是更好的选择,因为您以后可能会得到更多 setup-cleanup 对。
这与 this question 有点相关,但我在下面的这个最小示例中还有一些其他问题。
为了功能测试,我准备了一个固定装置,它备份了一个文件,该文件将在测试期间进行修改运行(例如,附加了一行)。经过测试运行这个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 appended\n"
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
标签)时,我没有看到正在输出的夹具的任何日志行以及每个 运行 我看到文件中附加了另一行。这意味着文件没有被备份和恢复。即使在我将夹具向下移动到场景级别 modify_file.feature
文件中,也不会应用夹具。
你能帮我理解这是怎么回事吗?我也很好奇为什么夹具标签使用点符号 (@fixture.backup.file
) 而不是 (fixture.backup_file
),因为这与实际函数名称相似。 behave documentation.
下面是不用 @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 appended\n"
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
但是使用 behave 文档中 Realistic example 中描述的夹具和夹具注册表是更好的选择,因为您以后可能会得到更多 setup-cleanup 对。