# Running tests via make Every test workflow has a `make` target, so commands stay short and identical across machines and CI. See also [Test framework and rules](/docs/testing-framework.html) and [Load testing with Locust](/docs/testing-locust.html). ## Setup Install the package with its development extras (`pytest`, Playwright, coverage) and the browser binary once: ```bash make install # pip install -e . AND playwright install chromium pip install -e ".[dev]" # test dependencies (pytest, coverage, requests) ``` ## Correctness suite | Target | What it does | |--------|--------------| | `make test` | Full suite headless, serial (one test at a time), fail-fast (`-x`). The everyday command. | | `make test-headed` | The same suite in a visible browser, for watching or debugging an E2E test. | | `make test-unit` | Only `tests/unit/` - pure in-process tests, no server, fastest. | | `make test-api` | Only `tests/api/` - HTTP integration tests against the live server, no browser. | | `make test-e2e` | Only `tests/e2e/` - the Playwright browser tests, headless. | | `make coverage` | Full suite under coverage, then prints a coverage report. | | `make coverage-headed` | Coverage run with a visible browser. | | `make coverage-html` | Runs `coverage`, then writes the browsable HTML report to `htmlcov/index.html`. | `make test` sets `PLAYWRIGHT_HEADLESS=1`; `make test-headed` sets it to `0`. The whole suite runs in a single process: serial execution is enforced in `pyproject.toml` (`addopts = "--tb=line -p no:xdist"`), so there are no parallel workers and the coverage targets collect everything in one process, as CI runs it. Tests are split into `tests/unit/`, `tests/api/`, and `tests/e2e/` as a directory tree that mirrors the path (api/e2e by endpoint, for example `tests/e2e/admin/aiusage.py`; unit by source module); see [Test framework and rules](/docs/testing-framework.html) for the naming convention. To run one test instead of the suite, call pytest directly: ```bash python -m pytest tests/e2e/feed.py::test_name -v --tb=line -x ``` ## Load testing | Target | What it does | |--------|--------------| | `make locust` | Starts a dedicated server and opens the Locust web UI. | | `make locust-headless` | Runs Locust unattended with preset users and run-time, writing an HTML report. | Both manage their own server and throwaway database. Tuning variables are in [Load testing with Locust](/docs/testing-locust.html). ## Housekeeping ```bash make clean # remove __pycache__, *.pyc, the egg-info, and .venv ``` ## What CI runs `.gitea/workflows/test.yaml` mirrors these targets: it installs `".[dev]"` and Chromium, runs the serial suite under coverage (`coverage run -m pytest tests/`), publishes the coverage HTML, and on failure uploads the screenshots from `/tmp/devplace_test_screenshots/`. Running `make coverage` locally reproduces the CI result before you push.