def setup_test_methods(request): from sqlalchemy.testing import asyncio # called for each test self = request.instance # before this fixture runs: # 1. function level "autouse" fixtures under py3k (examples: TablesTest # define tables / data, MappedTest define tables / mappers / data) # 2. run homegrown function level "autouse" fixtures under py2k if py2k: reinvent_fixtures_py2k.run_fn_fixture_setup(request) # 3. run outer xdist-style setup if hasattr(self, "setup_test"): asyncio._maybe_async(self.setup_test) # alembic test suite is using setUp and tearDown # xdist methods; support these in the test suite # for the near term if hasattr(self, "setUp"): asyncio._maybe_async(self.setUp) # inside the yield: # 4. function level fixtures defined on test functions themselves, # e.g. "connection", "metadata" run next # 5. pytest hook pytest_runtest_call then runs # 6. test itself runs yield # yield finishes: # 7. function level fixtures defined on test functions # themselves, e.g. "connection" rolls back the transaction, "metadata" # emits drop all # 8. pytest hook pytest_runtest_teardown hook runs, this is associated # with fixtures close all sessions, provisioning.stop_test_class(), # engines.testing_reaper -> ensure all connection pool connections # are returned, engines created by testing_engine that aren't the # config engine are disposed asyncio._maybe_async(plugin_base.after_test_fixtures, self) # 10. run xdist-style teardown if hasattr(self, "tearDown"): asyncio._maybe_async(self.tearDown) if hasattr(self, "teardown_test"): asyncio._maybe_async(self.teardown_test) # 11. run homegrown function-level "autouse" fixtures under py2k if py2k: reinvent_fixtures_py2k.run_fn_fixture_teardown(request)
def pytest_runtest_teardown(item, nextitem): # runs inside of pytest function fixture scope # after test function runs from sqlalchemy.testing import asyncio asyncio._maybe_async(plugin_base.after_test, item)
def pytest_runtest_setup(item): from sqlalchemy.testing import asyncio # here we seem to get called only based on what we collected # in pytest_collection_modifyitems. So to do class-based stuff # we have to tear that out. global _current_class if not isinstance(item, pytest.Function): return # ... so we're doing a little dance here to figure it out... if _current_class is None: asyncio._maybe_async(class_setup, item.parent.parent) _current_class = item.parent.parent # this is needed for the class-level, to ensure that the # teardown runs after the class is completed with its own # class-level teardown... def finalize(): global _current_class asyncio._maybe_async(class_teardown, item.parent.parent) _current_class = None item.parent.parent.addfinalizer(finalize) asyncio._maybe_async(test_setup, item)
def pytest_runtest_teardown(item): from sqlalchemy.testing import asyncio # ...but this works better as the hook here rather than # using a finalizer, as the finalizer seems to get in the way # of the test reporting failures correctly (you get a bunch of # pytest assertion stuff instead) asyncio._maybe_async(test_teardown, item)
def pytest_runtest_call(item): # runs inside of pytest function fixture scope # before test function runs from sqlalchemy.testing import asyncio asyncio._maybe_async( plugin_base.before_test, item, item.parent.module.__name__, item.parent.cls, item.name, )
def pytest_runtest_teardown(item, nextitem): # runs inside of pytest function fixture scope # after test function runs from sqlalchemy.testing import asyncio asyncio._maybe_async(plugin_base.after_test, item) yield # this is now after all the fixture teardown have run, the class can be # finalized. Since pytest v7 this finalizer can no longer be added in # pytest_runtest_setup since the class has not yet been setup at that # time. # See https://github.com/pytest-dev/pytest/issues/9343 global _current_class, _current_report if _current_class is not None and ( # last test or a new class nextitem is None or nextitem.getparent(pytest.Class) is not _current_class ): _current_class = None try: asyncio._maybe_async_provisioning( plugin_base.stop_test_class_outside_fixtures, item.cls ) except Exception as e: # in case of an exception during teardown attach the original # error to the exception message, otherwise it will get lost if _current_report.failed: if not e.args: e.args = ( "__Original test failure__:\n" + _current_report.longreprtext, ) elif e.args[-1] and isinstance(e.args[-1], str): args = list(e.args) args[-1] += ( "\n__Original test failure__:\n" + _current_report.longreprtext ) e.args = tuple(args) else: e.args += ( "__Original test failure__", _current_report.longreprtext, ) raise finally: _current_report = None
def setup_class_methods(request): from sqlalchemy.testing import asyncio cls = request.cls if hasattr(cls, "setup_test_class"): asyncio._maybe_async(cls.setup_test_class) yield if hasattr(cls, "teardown_test_class"): asyncio._maybe_async(cls.teardown_test_class) asyncio._maybe_async(plugin_base.stop_test_class, cls)
def setup_class_methods(request): from sqlalchemy.testing import asyncio cls = request.cls if hasattr(cls, "setup_test_class"): asyncio._maybe_async(cls.setup_test_class) if py2k: reinvent_fixtures_py2k.run_class_fixture_setup(request) yield if py2k: reinvent_fixtures_py2k.run_class_fixture_teardown(request) if hasattr(cls, "teardown_test_class"): asyncio._maybe_async(cls.teardown_test_class) asyncio._maybe_async(plugin_base.stop_test_class, cls)
def make_async(fn, *args, **kwargs): return asyncio._maybe_async(fn, *args, **kwargs)
def finalize(): global _current_class asyncio._maybe_async(class_teardown, item.parent.parent) _current_class = None