如何用Pytest Fixture生成多个类实例并匹配对应预期值?
Hey there! Let's solve this problem step by step. The key here is to pair each Building instance with its corresponding expected roof angle so pytest can test each pair individually. Here are a few straightforward approaches tailored to your needs:
方法1:直接参数化测试函数(最直观)
If your Building instances are easy to create, you can use @pytest.mark.parametrize to pass tuples of (building_instance, expected_angle) directly to your test function. This keeps everything in one place and is super readable.
First, let's assume your Building class looks something like this (adjust the calculation logic to match your actual code):
class Building: def __init__(self, roof_slope): self.roof_slope = roof_slope def calculate_roof_angle(self): # Example calculation: convert slope to angle (adjust this to your real logic) return self.roof_slope * 6
Then your test code would look like this:
import pytest @pytest.mark.parametrize("building, expected_angle", [ (Building(2), 12), # Slope 2 → expected angle 12 (Building(3), 18), # Slope 3 → expected angle 18 (Building(1.5), 9), # Slope 1.5 → expected angle 9 ]) def test_roof_angle_matches_expected(building, expected_angle): assert building.calculate_roof_angle() == expected_angle
When you run pytest, it will run a separate test for each tuple, so you'll see exactly which instance/expected value pair passes or fails.
方法2:参数化Fixture(适合复杂实例生成)
If creating your Building instances requires more setup (like pulling data from a config, using other fixtures, or complex initialization), you can create a parameterized fixture that returns pairs of (building, expected_angle).
Here's how that would work:
import pytest @pytest.fixture(params=[ (2, 12), (3, 18), (1.5, 9), ]) def building_with_expected(request): # Unpack the parameters: slope value and expected angle slope, expected = request.param # Create your Building instance (add any complex setup here) building = Building(slope) # Return both the instance and its expected angle return building, expected def test_roof_angle_from_fixture(building_with_expected): building, expected_angle = building_with_expected assert building.calculate_roof_angle() == expected_angle
This approach keeps your test function clean and centralizes all the instance setup logic in the fixture.
额外技巧:处理带依赖的实例
If your Building instances depend on other fixtures (e.g., a shared config or utility object), you can easily include those in the parameterized fixture:
# A fixture for shared dependencies @pytest.fixture def slope_multiplier(): # Example shared value used in building initialization return 0.8 @pytest.fixture(params=[ (2, 12), (3, 18), ]) def complex_building_with_expected(request, slope_multiplier): slope, base_expected = request.param # Use the shared dependency to create the building adjusted_slope = slope * slope_multiplier building = Building(adjusted_slope) # Adjust the expected angle to match the modified slope adjusted_expected = base_expected * slope_multiplier return building, adjusted_expected def test_complex_roof_angle(complex_building_with_expected): building, expected_angle = complex_building_with_expected assert building.calculate_roof_angle() == expected_angle
内容的提问来源于stack exchange,提问作者Eduardo

