pallets/flask
Testing is pytest-only, rooted at `tests/` with `testpaths = ["tests"]` and `filterwarnings = ["error"]` so any unexpected warning fails the suite — a notable constraint given 3.2's new deprecation warnings. 22 test modules totalling ~7.6k lines cover the framework, with `test_basic.py` (1974 lines, 95 tests), `test_blueprints.py` (1115) and `test_cli.py` (703) dominating. Fixtures in `conftest.py` provide `app`, `client`, `app_ctx`, `req_ctx`, plus two autouse guards: `_standard_os_environ` clears FLASK_* env vars, and `leak_detector` asserts no app context is left pushed at test end. Static typing is treated as a test surface of its own: `tests/type_check/` holds three assertion-free modules checked by strict mypy and pyright in a dedicated CI job. Coverage is configured with branch mode over `flask` and `tests`, but no coverage gate is enforced in any workflow.
- pytest config is minimal and strict: `testpaths = ["tests"]` with `filterwarnings = ["error"]`, so every warning — including the new `RequestContext`/`should_ignore_error` DeprecationWarnings — must be explicitly expected by a test.
- `tests/conftest.py` defines an autouse `leak_detector` that pops every still-pushed `app_ctx` after each test and asserts the leak list is empty — a hard guard against context-management regressions.
- The autouse `_standard_os_environ` fixture monkeypatch-deletes `FLASK_ENV_FILE`, `FLASK_APP`, `FLASK_DEBUG`, `FLASK_RUN_FROM_CLI` and `WERKZEUG_RUN_MAIN` so CLI tests can't leak environment state into each other.
- The shared `app` fixture builds `Flask("flask_test", root_path=os.path.dirname(__file__))` with `TESTING=True` and `SECRET_KEY="test key"`, which is why `tests/templates/` and `tests/static/` resolve as the app's template and static folders.
- Test weight is concentrated: `test_basic.py` 1974 lines / 95 test functions, `test_blueprints.py` 1115, `test_cli.py` 703 / 34 tests, `test_templating.py` 532 — versus 28 lines for `test_session_interface.py` and 21 for `test_subclassing.py`.
- CLI tests are backed by fixture apps under `tests/test_apps/`, including `cliapp/factory.py`, `cliapp/multiapp.py`, `cliapp/importerrorapp.py`, a nested `inner1/inner2/flask.py` shadowing case, and `helloworld/wsgi.py` for implicit discovery — plus checked-in `.env` and `.flaskenv` files.
- Async coverage is gated on the optional extra: `tests/test_async.py` begins with `pytest.importorskip("asgiref")` and exercises async views, async `View.dispatch_request`, async `MethodView` handlers and async error handlers across app and blueprint.
- Type checking is a first-class test target: `tests/type_check/` contains `typing_route.py`, `typing_app_decorators.py` and `typing_error_handler.py`, and both mypy (`strict = true`, `files = ["src", "tests/type_check"]`) and pyright run over them in the `typing` tox env and a dedicated CI job.
- The test matrix is unusually broad: CPython 3.10–3.15 including free-threaded `3.14t`, Windows and macOS runners, PyPy 3.11, a minimum-dependency env pinning exact lower bounds, and a dev env installing six Pallets libraries from git main tarballs.
- Coverage is configured (branch mode, `source = ["flask", "tests"]`, `exclude_also` for TYPE_CHECKING blocks and `raise NotImplementedError`) but no workflow runs coverage or enforces a threshold — the tox commands invoke plain `pytest -v --tb=short`.
- Example apps carry their own tests: `examples/tutorial/tests/` has four modules (auth, blog, db, factory) plus `data.sql` seed data, and `examples/javascript/tests/test_js_example.py` exists — but neither is in `testpaths`, so CI never runs them.
- Session security behaviour has direct tests — SameSite attribute variants and `SECRET_KEY_FALLBACKS` key rotation are asserted in `test_basic.py` around lines 342–420.
- Test harness code being tested is itself shipped: `FlaskClient.session_transaction` opens a real request context, mutates the session, saves it and re-injects `Set-Cookie` into the client jar, and `FlaskCliRunner.invoke` defaults `obj` to `ScriptInfo(create_app=lambda: self.app)`.
- Style enforcement runs via pre-commit (ruff check + ruff format, uv-lock, codespell, merge-conflict/debug-statement/whitespace hooks) with all revs pinned to frozen SHAs, executed both as the `style` tox env and the `pre-commit.yaml` workflow.