Writing a suite
A suite is a directory under projects/<project>/<suite>/ (any nesting depth)
containing a suite.yml and plain pytest test_*.py files. The suite id is the path
relative to projects/ — e.g. bikecrm/backend.
Adding a suite
Section titled “Adding a suite”- Copy
projects/_template/toprojects/<project>/<suite>/. - Edit
suite.yml(name, schedule, required env vars) and setenabled: true. - Write
test_*.pypytest tests. Fast (<60s), independent, idempotent. - Add the suite’s env vars to
.env.example(documented, with placeholders) and the server’s.env(real values). uv run talaia run <project>/<suite>to verify, then redeploy.
suite.yml reference
Section titled “suite.yml reference”All keys except schedule have defaults (shown below):
name: Template suite # display name in the UI (default: suite id)enabled: false # disabled suites are skipped by `run --all`, crontab and the UIschedule: "*/15 * * * *" # cron expression consumed by `talaia crontab` (supercronic)timeout_seconds: 300 # hard kill for the whole pytest runretries: 1 # in-run retries before the run counts as failedretry_delay_seconds: 30alert: cooldown_minutes: 60 # min gap between repeat alerts while the suite stays down
env: required: [] # env vars that must be set; missing -> run recorded as "error" # - MYPROJECT_BASE_URL # - MYPROJECT_USERNAME # - MYPROJECT_PASSWORD
# heartbeat_env: HC_URL_MYPROJECT # env var holding a healthchecks.io ping URL (dead-man switch)# version_url: https://api.example.com/api/version/ # GET'd after each run; tagged on runs/alertsTwo optional extras:
heartbeat_envnames an env var holding a healthchecks.io ping URL. Talaia pings it after every run — the plain URL on a pass, the/failendpoint on a failure — so healthchecks.io alerts you both when the suite goes red and when Talaia stops running at all.version_urlis fetched (GET) after each run; aversion/releasefield from a JSON response (or the plain response body) is recorded on the run and included in alerts, so an alert can answer “which deploy caused this?”.
Conventions
Section titled “Conventions”- A suite is a leaf directory. Never put a
suite.ymlin an ancestor of another suite — the parent’s pytest run would collect the child’s tests. - Black box only. Suites run with cwd = the suite directory and must not import anything from the monitored project. API and browser access only.
- Fast, independent, idempotent. Keep the whole suite under ~60 seconds; the entire
run is killed at
timeout_seconds. - Env var naming:
<PROJECT>_<THING>(e.g.BIKECRM_BASE_URL). Declare them inenv.requiredso a misconfigured server shows up as an expliciterrorrun instead of a confusing failure. - Stagger schedules between suites of the same project (e.g.
*/10vs5-59/15) so they do not hammer the app at the same instant.
Safety rules (these tests hit production)
Section titled “Safety rules (these tests hit production)”- Test accounts only. Every suite authenticates against a dedicated test account/tenant. Never point a suite at a real customer account.
- Prefix and clean up. Any entity a test creates must be named with a
SMOKE-prefix and deleted by the same test when possible. - Gate every write flow. Before exercising any write against production, assert the expected sandbox conditions explicitly (for example: the test business slug is the expected one and irreversible modes are disabled). A suite must refuse to run against anything else.
- Quarantine irreversible flows. Flows that leave undeletable data belong in low-frequency (e.g. daily) suites, never in the every-10-minutes ones.
- No secrets in the repo. Credentials come from env (
.envon the server, gitignored). Document every new var in.env.examplewith a placeholder.