A few months ago I explained how I efficiently test Django forms with pytest parameterization. Last week, I learned a new trick from Raphael Pierzina’s post about ids for fixtures and parametrize, which is:
You you can add multiple parametrization markers to a test function which then create a test parameter matrix.
The list of test cases can thus be written much more clearly. Compare the example code from my previous post:
from django import forms
import pytest
class ExampleForm(forms.Form):
name = forms.CharField(required=True)
age = forms.IntegerField(min_value=18)
@pytest.mark.parametrize(
'name, age, validity',
[('Hugo', 18, True),
('Egon', 17, False),
('Balder', None, False),
('', 18, False),
(None, 18, False),
])
def test_example_form(name, age, validity):
form = ExampleForm(data={
'name': name,
'age': age,
})
assert form.is_valid() is validity
to the same test using multiple parameterization markers:
@pytest.mark.parametrize(
'name, valid_name',
[
('Hugo', True),
('', False),
(None, False),
]
)
@pytest.mark.parametrize(
'age, valid_age',
[
('18', True),
('17', False),
(None, False),
]
)
def test_example_form(name, age, valid_name, valid_age):
form = ExampleForm(data={
'name': name,
'age': age,
})
assert form.is_valid() is (valid_name and valid_age)
This tests all 9 possible combinations of the three test cases each for name and age. Maybe that’s overkill, but on the other hand I can be sure that I touch all the relevant combinations.
Take note of the last line that checks that the form only validates when both input parameters are valid.
The main advantage I see is legibility. For each form field, I only have to understand the list of test parameters for exactly that field, and not any additional combinations with other fields.
I’m loving it!

Comments
Nothing yet. Say the first thing.
Sign in to join the conversation.