Inject a hidden autouse, function scoped fixture into the collected module object that invokes setup_function/teardown_function if either or both are available. Using a fixture to invoke this methods ensures we play nicely and unsurprisingly with other fixtures (#517).
(self)
| 559 | self.obj.__pytest_setup_module = xunit_setup_module_fixture |
| 560 | |
| 561 | def _inject_setup_function_fixture(self) -> None: |
| 562 | """Inject a hidden autouse, function scoped fixture into the collected module object |
| 563 | that invokes setup_function/teardown_function if either or both are available. |
| 564 | |
| 565 | Using a fixture to invoke this methods ensures we play nicely and unsurprisingly with |
| 566 | other fixtures (#517). |
| 567 | """ |
| 568 | setup_function = _get_first_non_fixture_func(self.obj, ("setup_function",)) |
| 569 | teardown_function = _get_first_non_fixture_func( |
| 570 | self.obj, ("teardown_function",) |
| 571 | ) |
| 572 | if setup_function is None and teardown_function is None: |
| 573 | return |
| 574 | |
| 575 | @fixtures.fixture( |
| 576 | autouse=True, |
| 577 | scope="function", |
| 578 | # Use a unique name to speed up lookup. |
| 579 | name=f"_xunit_setup_function_fixture_{self.obj.__name__}", |
| 580 | ) |
| 581 | def xunit_setup_function_fixture(request) -> Generator[None, None, None]: |
| 582 | if request.instance is not None: |
| 583 | # in this case we are bound to an instance, so we need to let |
| 584 | # setup_method handle this |
| 585 | yield |
| 586 | return |
| 587 | if setup_function is not None: |
| 588 | _call_with_optional_argument(setup_function, request.function) |
| 589 | yield |
| 590 | if teardown_function is not None: |
| 591 | _call_with_optional_argument(teardown_function, request.function) |
| 592 | |
| 593 | self.obj.__pytest_setup_function = xunit_setup_function_fixture |
| 594 | |
| 595 | def _importtestmodule(self): |
| 596 | # We assume we are only called once per module. |
no test coverage detected