envlist = {3.7,3.8,3.9,3.10}
isolated_build = True
+# Retry flakey tests by re-running the failed tests up to 3 times.
+#
+# - `--lfnf=none` makes pytest running no test (instead of all) if the previous
+# run had no failure
+# - `--no-collect-ok` changes the exit value from 5 to 0 if not test was
+# collected (because the previous run was successful)
+# - the `-` in front of the first two commands in toxmakes it ignore failures,
+# so that only the exit stastus of the last command is considered.
+#
+# This is *slightly* more complicated than what I'd hoped, but, ok.
+
[testenv]
changedir = ..
commands =
- python -bb -m pytest {posargs}
+ -python -bb -m pytest {posargs}
+ -python -bb -m pytest --lf --lfnf=none --no-collect-ok {posargs}
+ python -bb -m pytest --lf --lfnf=none --no-collect-ok {posargs}
passenv = PG* PSYCOPG_TEST_DSN PYTEST_ADDOPTS PSYCOPG_IMPL
extras = test
deps =
[testenv:dns]
changedir = ..
commands =
- python -bb -m pytest {posargs}
+ -python -bb -m pytest {posargs}
+ -python -bb -m pytest --lf --lfnf=none --no-collect-ok {posargs}
+ python -bb -m pytest --lf --lfnf=none --no-collect-ok {posargs}
passenv = PG* PSYCOPG_TEST_DSN PYTEST_ADDOPTS PSYCOPG_IMPL
extras = test
deps =
[testenv:postgis]
changedir = ..
commands =
- python -bb -m pytest {posargs}
+ -python -bb -m pytest {posargs}
+ -python -bb -m pytest --lf --lfnf=none --no-collect-ok {posargs}
+ python -bb -m pytest --lf --lfnf=none --no-collect-ok {posargs}
passenv = PG* PSYCOPG_TEST_DSN PYTEST_ADDOPTS PSYCOPG_IMPL
extras = test
deps =
[testenv]
changedir = ..
commands =
- python -bb -m pytest {posargs}
+ -python -bb -m pytest {posargs}
+ -python -bb -m pytest --lf --lfnf=none --no-collect-ok {posargs}
+ python -bb -m pytest --lf --lfnf=none --no-collect-ok {posargs}
passenv = PG* PSYCOPG_TEST_DSN PYTEST_ADDOPTS PSYCOPG_IMPL
deps =
-e {toxinidir}/../psycopg[test]
help="The asyncio loop to use for async tests.",
)
+ parser.addoption(
+ "--no-collect-ok",
+ action="store_true",
+ help="If no test is collected, exit with 0 instead of 5"
+ " (useful with --lfnf=none).",
+ )
+
def pytest_report_header(config):
loop = config.getoption("--loop")
if sys.platform == "win32":
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
+
+
+def pytest_sessionfinish(session, exitstatus):
+ no_collect_ok = session.config.getoption("--no-collect-ok")
+ if exitstatus == pytest.ExitCode.NO_TESTS_COLLECTED and no_collect_ok:
+ session.exitstatus = pytest.ExitCode.OK