Topic: Understand pytest's default discovery rules (test*.py, *test.py) to know exactly which files get swept up without configuration

Date: 2026-05-29

Time: 11:36

Pytest Discovery Rules in ddia-implementations

How pytest finds tests (without configuration)

This repo has zero pytest configuration — no pytest.ini, no pyproject.toml, no setup.cfg, no conftest.py at any level. That means pytest runs entirely on its default discovery rules:

1. File collection: Starting from the invocation directory, pytest recursively finds files matching test*.py or *test.py.

2. Inside those files: it collects functions named test* and classes named Test* (with methods named test*).

3. Directories: it recurses into all subdirectories unless they match norecursedirs defaults (.git, _pycache_, .tox, etc.).

What actually gets swept up

This is where it gets interesting. The repo has two parallel sets of test files per module:

| Pattern | Example | Collected? |

|---------|---------|------------|

| test*.py | bloom-filter/testbloomfilter.py | Yes — matches test*.py |

| testertest*.py | bloom-filter/testertestbloomfilter.py | Notestertest does not match test* or *_test |

The testertest*.py files are invisible to default pytest discovery. The prefix tester breaks the test*.py glob — pytest requires the filename to *start with* test or *end with* test (before .py). testertestbloomfilter.py starts with tester, not test_.

Concrete inventory

Collected by default (the test_*.py files):

Not collected by default (the testertest*.py files):

The practical consequence

Running bare pytest from the repo root collects ~30 test items from the test*.py files. The testertest*.py files contain ~40+ additional test items — including the *only* tests for write-skew-detection — that silently don't run. The testertest_ files also tend to have broader coverage (e.g., bloom-filter's tester version has 11 tests vs. 5 in the default-discovered version, covering serialization, union, scalable filters, and counting filters).

To run the tester files, you'd need either explicit paths (pytest bloom-filter/testertestbloomfilter.py) or a pytest.ini with a custom pythonfiles glob like pythonfiles = test*.py testertest*.py.

Topics to Explore

Beliefs