Configuration
This plugin provides a typing_scenario_runner fixture that lets a test use a
pytest_typing_runner.Scenario object to create a scenario to run a type checker
against.
There are several objects involved in this that allow customisation and a few fixtures that provide the ability to inject these customized objects into different parts of the pytest run.
There are these relevant protocols:
There are a few pytest fixtures that can be overridden within any pytest scope to change what concrete implementations get used:
from pytest_typing_runner import protocols
import pytest
@pytest.fixture
def typing_runner_config(pytestconfig: pytest.Config) -> protocols.RunnerConfig:
"""
Fixture to get a RunnerConfig with all the relevant settings from the pytest config
Override this if you want a RunnerConfig that overrides the options provided
by the command line
"""
from pytest_typing_runner import protocols, Scenario
import pytest
@pytest.fixture
def typing_scenario_maker() -> protocols.ScenarioMaker[Scenario]:
"""
Fixture to override the specific Scenario class that should be used.
"""
from pytest_typing_runner import protocols, Scenario
import pytest
@pytest.fixture
def typing_scenario_runner_maker() -> protocols.ScenarioRunnerMaker[Scenario]:
"""
Fixture to override what object may be used to drive the scenario
Note that the default implementation of ``ScenarioRunner`` already satisfies
the ``ScenarioRunnerMaker`` protocol, but ultimately that is what this fixture
should return.
It should also be typed in terms of what scenario class is active for that
scope.
Also note that pytest and this plugin does not provide any verification
that the type annotations are correct and it's recommended to have
protective assertions in complicated setups.
"""
import pytest
import pathlib
@pytest.fixture
def typing_scenario_root_dir(tmp_path: pathlib.Path) -> pathlib.Path:
"""
This sets the root path for all the files in the scenario.
This example shows the default
"""
return tmp_path / "scenario_root"
Example
For example:
import typing
import pytest
from pytest_typing_runner import protocols, scenarios
def test_it_works(typing_scenario_runner: scenarios.ScenarioRunner[scenarios.Scenario]) -> None:
assert isinstance(typing_scenario_runner, scenarios.ScenarioRunner)
assert isinstance(typing_scenario_runner.scenario, scenarios.Scenario)
class TestOther:
class MyScenario(scenarios.Scenario):
info: int = 1
def some_functionality(self) -> None:
self.info = 2
class MyScenarioRunner(scenarios.ScenarioRunner[MyScenario]):
def prepare_scenario(self) -> None:
self.scenario.some_functionality()
if typing.TYPE_CHECKING:
# Let our type checker tell us if we satisfy the maker protocols
_MS: protocols.ScenarioMaker[MyScenario] = MyScenario.create
_MSH: protocols.ScenarioRunnerMaker[MyScenario] = MyScenarioRunner.create
@pytest.fixture
def typing_scenario_maker(self) -> protocols.ScenarioMaker[MyScenario]:
return self.MyScenario.create
@pytest.fixture
def typing_scenario_runner_maker(self) -> protocols.ScenarioRunnerMaker[MyScenario]:
return self.MyScenarioRunner.create
def test_it_works(self, typing_scenario_runner: MyScenarioRunner) -> None:
assert isinstance(typing_scenario_runner, scenarios.ScenarioRunner)
assert isinstance(typing_scenario_runner.scenario, self.MyScenario)
assert typing_scenario_runner.scenario.info == 2