# regarding conftest: # If you have conftest.py files which do not reside in a python package directory # (i.e. one containing an __init__.py) then “import conftest” can be ambiguous # because there might be other conftest.py files as well on your PYTHONPATH or # sys.path. It is thus good practise for projects to either put conftest.py under # a package scope or to never import anything from a conftest.py file. from pathlib import Path import pytest from dotenv import dotenv_values from src.dirmanager import DirManager TIMEOUT = 5000 def pytest_addoption(parser): parser.addoption( "--env_file", action="store", ) parser.addoption( "--output_dir", action="store", ) parser.addoption( "--session_id", action="store", ) @pytest.fixture(scope="session", autouse=True) def DIR(request) -> DirManager: """Fixture holding test directories DIR.OUTPUT DIR.SESSION DIR.RECORDS DIR.STATES DIR.RESULTS DIR.PROGRESS""" output_dir = request.config.getoption("--output_dir") assert output_dir is not None, "required pytest command line argument not given" output_dir = Path(output_dir) session_id = request.config.getoption("--session_id") assert session_id is not None, "required pytest command line argument not given" dirmanager = DirManager(output_dir=output_dir, session_id=session_id) dirmanager.create_all_dirs() return dirmanager @pytest.fixture(scope="session", autouse=True) def dotenv_config(request) -> dict[str, str]: dotenv_path = request.config.getoption("--env_file") assert dotenv_path is not None, "required pytest command line argument not given" dotenv_path = Path(dotenv_path) assert dotenv_path.is_file() return dotenv_values(dotenv_path) # type: ignore @pytest.hookimpl(tryfirst=True, hookwrapper=True) def pytest_runtest_makereport(item, call): """saves traceback when test fails""" # execute all other hooks to obtain the report object outcome = yield rep = outcome.get_result() # we only look at actual failing test calls, not setup/teardown if rep.when == "call" and rep.failed: # saves traceback as .txt for failed test filename = f"failed-{item.nodeid}.txt" filename = filename.replace("/", "-") filename = filename.replace("::", "-") filepath = item.funcargs["DIR"].RESULTS / filename with open(filepath, "a") as f: f.write(rep.longreprtext + "\n")