-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Description
I don't know whether it is idiomatic or not, but I use the following approach to parametrize pytest
tests. Tests are defined as method in a class. Parameters are defined as fixtures in a class. Fixtures are overridden in subclasses to run tests with different parameters.
For example:
import pytest
class TestA:
@pytest.fixture
def foo(self) -> int:
return 42
def test_foo(self, foo: int) -> None:
assert foo > 0
@pytest.fixture
def bar() -> str:
return "abc"
class TestB(TestA):
@pytest.fixture
def foo(self, bar: str) -> int: # line 20
return len(bar)
TestA.test_foo
and TestB.test_foo
are executed with different values of foo
. The problem is that fixtures can depend on other fixtures, and signatures for methods defining fixture can be different. MyPy complains:
t.py:20: error: Signature of "foo" incompatible with supertype "TestA"
t.py:20: note: Superclass:
t.py:20: note: def foo(self) -> int
t.py:20: note: Subclass:
t.py:20: note: def foo(self, bar: str) -> int
It is not real error in the user code that the methods have different signatures. These methods are not called directly. They are called by pytest which provides all arguments.
I can add "# type: ignore", but I do not want to lose static type checking completely. It is useful to check that the type of the parameter matches the returning type of corresponding fixture function.
mypy 0.961 (compiled: yes)
pytest 7.1.2
Python 3.9.13