pytest-dev / pytest-dev/pytest
Keyword-based parameter sets
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 14.5k
- Forks
- 3.4k
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 35
Description
In many of my tests I've been using pytest.param(..., id="...") as means of providing more readable identifiers for my tests inline, since otherwise with multiple parameters, the autogenerated id is hard to read.
Some of my parameter-driven tests end up growing beyond 2-3 arguments and maintaining the parameters positionally becomes error-prone and hurts readability. The reader has to mentally "zip" a list of parameters (of a parameter set) to the parameter names defined earlier, and if you need to add a parameter, now you need to add them to each and every test, and if you want to insert it (e.g. to maintain grouping), you'd have to carefully count parameters in each of the sets.
One pattern I've been introducing in such cases is defining a "ParamSet" attrs base class:
import attr
@attr.s(auto_attribs=True, kw_only=True)
class ParamSet:
"""
Use as base class for sets for parameters for @pytest.mark.parametrize
when you find yourself passing too many parameters positionally.
"""
id: str
@property
def __name__(self) -> str: # indicate the id to pytest
return self.id
From there, a test would look like:
@attr.s(auto_attribs=True, kw_only=True)
class MyComplexTestParamSet(ParamSet):
foo: int
bar: str = 'some_default'
expected_baz: float
@pytest.mark.parameterize('params', [
MyComplexTestParamSet(foo=42, expected_baz=42.42, id="happy path"),
...
])
def test_complex(params: MyComplexTestParamSet):
...
Before we discuss specifics, is this something we'd want pytest.param to enable?
To give an idea, I'd imagine usage like:
@pytest.mark.parameterize('params', [
pytest.param(foo=42, expected_baz=42.42, id="happy path"),
...
])
def test_complex(params: Any):
...
or something more typed like this: (I like the fact that the type hint enables better developer experience when working on the test)
class MyComplexTestParamSet(pytest.ParameterSet):
foo: int
...
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Review the current pytest.param and @pytest.mark.parametrize entry points, focusing on how parameter values and readable IDs are represented. Compare the requested keyword-based and typed ParameterSet examples with existing behavior. Done means establishing whether a coherent API and scope can be defined; the issue does not name implementation files or tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- testing
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100