为什么这个方法被调用两次(pytest)
why is this method being called twice (pytest)
我在 models.py
中有一个名为 Tree
的 class 和一个名为 Property
的 class:
class Tree:
def __init__(self, name=None):
self.name = name
self.properties = []
def get_name(self):
return self.name
def add_property(self, prop):
if prop.__class__.__name__ != 'Property':
raise TypeError('Only properties may be added as properties')
else:
print('adding property: ' + str(prop))
self.properties.append(prop)
def add_properties(self, arr):
for label in arr:
property = Property(label=label)
self.add_property(property)
def get_properties(self):
return self.properties
class Property:
def __init__(self, label=None):
self.label = label
self.tree = None
self.values = []
def __str__(self):
return self.label
我正在尝试使用以下 pytest 测试脚本测试这些 classes,该脚本从 .feature 文件获取输入:
import pytest
from pytest_bdd import scenario, given, when, then, parsers
from models import Tree
@scenario('../features/Tree.feature',
'add properties to a tree')
def test_tree():
pass
@given("a new tree is created", target_fixture="create_tree")
def create_tree():
return Tree()
@pytest.fixture()
@when(parsers.cfparse("{properties} are added as properties"))
def add_properties(create_tree, properties):
properties = properties.split(',')
create_tree.add_properties(properties)
return create_tree
@then("I can get these properties")
def publish_article(add_properties):
result = add_properties.get_properties()
assert len(result) == 3
Tree.feature
Feature: Tree
# BUILD TOP-DOWN
Scenario: add properties to a tree
Given a new tree is created
When height, weight, age are added as properties
Then I can get these properties
不知何故,when
步骤中的 add_properties
方法被调用了两次。我知道这是因为打印了以下内容:
add_properties = <models.Tree object at 0x10b792760>
@then("I can get these properties")
def publish_article(add_properties):
print(add_properties.get_properties())
> assert len(add_properties.get_properties()) == 3
E assert 6 == 3
E + where 6 = len([<models.Property object at 0x10b792b50>, <models.Property object at 0x10b792a00>, <models.Property object at 0x10b792...dels.Property object at 0x10b62a280>, <models.Property object at 0x10b62a040>, <models.Property object at 0x10b62a0d0>])
E + where [<models.Property object at 0x10b792b50>, <models.Property object at 0x10b792a00>, <models.Property object at 0x10b792...dels.Property object at 0x10b62a280>, <models.Property object at 0x10b62a040>, <models.Property object at 0x10b62a0d0>] = <bound method Tree.get_properties of <models.Tree object at 0x10b792760>>()
E + where <bound method Tree.get_properties of <models.Tree object at 0x10b792760>> = <models.Tree object at 0x10b792760>.get_properties
tests/step_defs/test_tree.py:26: AssertionError
----------------------------- Captured stdout call -----------------------------
adding property: height
adding property: weight
adding property: age
adding property: height
adding property: weight
adding property: age
[<models.Property object at 0x10b792b50>, <models.Property object at 0x10b792a00>, <models.Property object at 0x10b792a60>, <models.Property object at 0x10b62a280>, <models.Property object at 0x10b62a040>, <models.Property object at 0x10b62a0d0>]
=========================== short test summary info ============================
FAILED tests/step_defs/test_property.py::test_property - pytest_bdd.exception...
FAILED tests/step_defs/test_tree.py::test_tree - assert 6 == 3
========================= 2 failed, 1 passed in 0.24s ==========================
为什么要添加两次属性?
我认为问题在于 pytest_bdd 允许您将 @given
用作固定装置,但您还在 @when
上添加了 @pytest.fixture
装饰器。
这意味着 add_properties
函数作为 when
步骤调用一次,然后作为 pytest fixture 再次调用。删除额外的装饰器并使用原来的 create_tree
fixture。
import pytest
from pytest_bdd import scenario, given, when, then, parsers
from models import Tree
@scenario('../features/Tree.feature',
'add properties to a tree')
def test_tree():
pass
@given("a new tree is created", target_fixture="create_tree")
def create_tree():
return Tree()
@when(parsers.cfparse("{properties} are added as properties"))
def add_properties(create_tree, properties):
properties = properties.split(',')
create_tree.add_properties(properties)
return create_tree
@then("I can get these properties")
def publish_article(create_tree):
result = create_tree.get_properties()
assert len(result) == 3
我在 models.py
中有一个名为 Tree
的 class 和一个名为 Property
的 class:
class Tree:
def __init__(self, name=None):
self.name = name
self.properties = []
def get_name(self):
return self.name
def add_property(self, prop):
if prop.__class__.__name__ != 'Property':
raise TypeError('Only properties may be added as properties')
else:
print('adding property: ' + str(prop))
self.properties.append(prop)
def add_properties(self, arr):
for label in arr:
property = Property(label=label)
self.add_property(property)
def get_properties(self):
return self.properties
class Property:
def __init__(self, label=None):
self.label = label
self.tree = None
self.values = []
def __str__(self):
return self.label
我正在尝试使用以下 pytest 测试脚本测试这些 classes,该脚本从 .feature 文件获取输入:
import pytest
from pytest_bdd import scenario, given, when, then, parsers
from models import Tree
@scenario('../features/Tree.feature',
'add properties to a tree')
def test_tree():
pass
@given("a new tree is created", target_fixture="create_tree")
def create_tree():
return Tree()
@pytest.fixture()
@when(parsers.cfparse("{properties} are added as properties"))
def add_properties(create_tree, properties):
properties = properties.split(',')
create_tree.add_properties(properties)
return create_tree
@then("I can get these properties")
def publish_article(add_properties):
result = add_properties.get_properties()
assert len(result) == 3
Tree.feature
Feature: Tree
# BUILD TOP-DOWN
Scenario: add properties to a tree
Given a new tree is created
When height, weight, age are added as properties
Then I can get these properties
不知何故,when
步骤中的 add_properties
方法被调用了两次。我知道这是因为打印了以下内容:
add_properties = <models.Tree object at 0x10b792760>
@then("I can get these properties")
def publish_article(add_properties):
print(add_properties.get_properties())
> assert len(add_properties.get_properties()) == 3
E assert 6 == 3
E + where 6 = len([<models.Property object at 0x10b792b50>, <models.Property object at 0x10b792a00>, <models.Property object at 0x10b792...dels.Property object at 0x10b62a280>, <models.Property object at 0x10b62a040>, <models.Property object at 0x10b62a0d0>])
E + where [<models.Property object at 0x10b792b50>, <models.Property object at 0x10b792a00>, <models.Property object at 0x10b792...dels.Property object at 0x10b62a280>, <models.Property object at 0x10b62a040>, <models.Property object at 0x10b62a0d0>] = <bound method Tree.get_properties of <models.Tree object at 0x10b792760>>()
E + where <bound method Tree.get_properties of <models.Tree object at 0x10b792760>> = <models.Tree object at 0x10b792760>.get_properties
tests/step_defs/test_tree.py:26: AssertionError
----------------------------- Captured stdout call -----------------------------
adding property: height
adding property: weight
adding property: age
adding property: height
adding property: weight
adding property: age
[<models.Property object at 0x10b792b50>, <models.Property object at 0x10b792a00>, <models.Property object at 0x10b792a60>, <models.Property object at 0x10b62a280>, <models.Property object at 0x10b62a040>, <models.Property object at 0x10b62a0d0>]
=========================== short test summary info ============================
FAILED tests/step_defs/test_property.py::test_property - pytest_bdd.exception...
FAILED tests/step_defs/test_tree.py::test_tree - assert 6 == 3
========================= 2 failed, 1 passed in 0.24s ==========================
为什么要添加两次属性?
我认为问题在于 pytest_bdd 允许您将 @given
用作固定装置,但您还在 @when
上添加了 @pytest.fixture
装饰器。
这意味着 add_properties
函数作为 when
步骤调用一次,然后作为 pytest fixture 再次调用。删除额外的装饰器并使用原来的 create_tree
fixture。
import pytest
from pytest_bdd import scenario, given, when, then, parsers
from models import Tree
@scenario('../features/Tree.feature',
'add properties to a tree')
def test_tree():
pass
@given("a new tree is created", target_fixture="create_tree")
def create_tree():
return Tree()
@when(parsers.cfparse("{properties} are added as properties"))
def add_properties(create_tree, properties):
properties = properties.split(',')
create_tree.add_properties(properties)
return create_tree
@then("I can get these properties")
def publish_article(create_tree):
result = create_tree.get_properties()
assert len(result) == 3