Pytest 使用固定装置比较几个 class 个实例
Pytest compare several class instances using fixtures
我正在学习 pytest,我正在尝试使用固定装置生成多个 class 实例,并将方法的结果与值进行比较。
比如我有下面的代码。在这种情况下,我有一个名为 building 的 class,它具有计算屋顶角度的方法。我正在生成 class 的两个实例,但我想将角度与两个不同的值进行比较。目前我正在与固定值 (12) 进行比较。
如何设置每个实例对应的值进行比较?
import pytest
from pywind.geometry import Building
params = [(60, 30, 6, 16, 0, 'gable'), (30, 50, 7, 13, 0, 'shed')] # Arguments
@pytest.fixture(params=params)
def building(request):
building = Building(*request.param)
return building
def test_roof_angle(building):
assert building.roof_angle() == 12
我认为你正在尝试做的事情与夹具的概念背道而驰。来自 pytest 文档,fixture 页面上的第一句话:
The purpose of test fixtures is to provide a fixed baseline upon which tests can reliably and repeatedly execute.
我添加了对固定基线的强调。这里有 两个 基线:山墙和棚子。为了符合固定装置的概念,您应该考虑将山墙和棚子拆分成单独的固定装置:
@pytest.fixture(params=[60, 30, 6, 16, 0, 'gable'])
def gable(request):
building = Building(*request.param)
return building
@pytest.fixture(params=[30, 50, 7, 13, 0, 'shed'])
def shed(request):
building = Building(*request.param)
return building
然后为每个创建带有适当断言的测试:
def test_roof_angle_1(gable):
assert building.roof_angle() == 12
def test_roof_angle_2(shed):
assert building.roof_angle() == 23
当多个灯具应该 运行 用于相同的精确测试时,向 params 参数提供多个参数列表很有用。在 pytest fixture docs 的示例中,他们测试了来自不同 URL 的 SMTP 响应。
在你的例子中,如果你有不同的建筑类型,它们应该都具有相同的特征(即,它们都具有相同的屋顶角度),那么使用多个参数来自动计算将是有用和合适的-运行 测试多个灯具。您可以将其命名为 buildings_with_12roof,而不是使用通用的 "building" fixture。
如果我没理解错的话,你希望你的夹具不仅提供一个测试实例,还提供一堆预期值,以便在测试中进行比较。请记住,您可以根据需要传递任意数量的参数;但是,以可读的方式组织它们取决于您。例如,您可以引入一些同时包含建筑实例和预期角度的中间容器:
from collections import namedtuple
BuildingData = namedtuple('BuildingData', ('instance', 'expected_angle', ))
params = [(60, 30, 6, 16, 0, 'gable', 12),
(30, 50, 7, 13, 0, 'shed', 42)]
@pytest.fixture(params=params)
def building(request):
# all params except the last one are constructor args
instance_args = request.param[:-1]
instance = Building(*instance_args)
# last param is the expected roof angle
expected_angle = request.param[-1]
return BuildingData(instance, expected_angle)
def test_roof_angle(building):
assert building.instance.roof_angle() == building.expected_angle
我正在学习 pytest,我正在尝试使用固定装置生成多个 class 实例,并将方法的结果与值进行比较。
比如我有下面的代码。在这种情况下,我有一个名为 building 的 class,它具有计算屋顶角度的方法。我正在生成 class 的两个实例,但我想将角度与两个不同的值进行比较。目前我正在与固定值 (12) 进行比较。
如何设置每个实例对应的值进行比较?
import pytest
from pywind.geometry import Building
params = [(60, 30, 6, 16, 0, 'gable'), (30, 50, 7, 13, 0, 'shed')] # Arguments
@pytest.fixture(params=params)
def building(request):
building = Building(*request.param)
return building
def test_roof_angle(building):
assert building.roof_angle() == 12
我认为你正在尝试做的事情与夹具的概念背道而驰。来自 pytest 文档,fixture 页面上的第一句话:
The purpose of test fixtures is to provide a fixed baseline upon which tests can reliably and repeatedly execute.
我添加了对固定基线的强调。这里有 两个 基线:山墙和棚子。为了符合固定装置的概念,您应该考虑将山墙和棚子拆分成单独的固定装置:
@pytest.fixture(params=[60, 30, 6, 16, 0, 'gable'])
def gable(request):
building = Building(*request.param)
return building
@pytest.fixture(params=[30, 50, 7, 13, 0, 'shed'])
def shed(request):
building = Building(*request.param)
return building
然后为每个创建带有适当断言的测试:
def test_roof_angle_1(gable):
assert building.roof_angle() == 12
def test_roof_angle_2(shed):
assert building.roof_angle() == 23
当多个灯具应该 运行 用于相同的精确测试时,向 params 参数提供多个参数列表很有用。在 pytest fixture docs 的示例中,他们测试了来自不同 URL 的 SMTP 响应。
在你的例子中,如果你有不同的建筑类型,它们应该都具有相同的特征(即,它们都具有相同的屋顶角度),那么使用多个参数来自动计算将是有用和合适的-运行 测试多个灯具。您可以将其命名为 buildings_with_12roof,而不是使用通用的 "building" fixture。
如果我没理解错的话,你希望你的夹具不仅提供一个测试实例,还提供一堆预期值,以便在测试中进行比较。请记住,您可以根据需要传递任意数量的参数;但是,以可读的方式组织它们取决于您。例如,您可以引入一些同时包含建筑实例和预期角度的中间容器:
from collections import namedtuple
BuildingData = namedtuple('BuildingData', ('instance', 'expected_angle', ))
params = [(60, 30, 6, 16, 0, 'gable', 12),
(30, 50, 7, 13, 0, 'shed', 42)]
@pytest.fixture(params=params)
def building(request):
# all params except the last one are constructor args
instance_args = request.param[:-1]
instance = Building(*instance_args)
# last param is the expected roof angle
expected_angle = request.param[-1]
return BuildingData(instance, expected_angle)
def test_roof_angle(building):
assert building.instance.roof_angle() == building.expected_angle