All jobs

Write Tests for a Django App

Yes. An agent finds thin spots in a Django app's TestCase suite, writes tests for untested branches, runs manage.py test, and opens a PR.

Run this on RushIn a Project that has your repository.

What the agent does

The agent starts from the project's own test style instead of inventing a second framework. In a Django app like healthchecks/healthchecks it reads requirements.txt and finds Django[argon2]==6.1.2, psycopg==3.3.6 and the rest of the runtime pins, then opens manage.py, which sets DJANGO_SETTINGS_MODULE to hc.settings. Default DATABASES in hc/settings.py is SQLite at hc.sqlite with PRAGMA busy_timeout = 5000 and transaction_mode IMMEDIATE; DB=postgres switches the engine. Tests subclass django.test.TestCase or TransactionTestCase, and the shared helpers live in hc/api/tests/__init__.py as BaseTestCase with an Alice user, project and CSRF-aware client.

Next it compares production modules under hc/front and hc/api with the existing suites. hc/front/tests/ already holds dozens of files such as test_basics.py and test_add_check.py, and hc/api/tests/ covers notify paths with TransactionTestCase setup that builds a Check, Channel and Flip. The thinner spots are usually the management commands with no matching test file (hc/api/management/commands/pruneobjects.py, prunetokenbucket.py, settelegramwebhook.py, submitchallenge.py) and front commands like populate_searchdb.py and render_docs.py, plus branches in hc/front/validators.py (WebhookValidator, CronValidator, OnCalendarValidator) and API auth in hc/api/decorators.py (authorize, version sniffing for /api/v2/ and /api/v3/).

For each gap it writes a new test_*.py next to the matching suite, importing the same models (hc.accounts.models.Project, hc.api.models.Check, Channel, Flip) and asserting through self.client or the command's call_command the way neighbouring tests do. It does not rewrite production views or transports. When a branch needs settings, it uses @override_settings the way BasicsTestCase does for DEBUG, SECRET_KEY and REGISTRATION_OPEN.

Before opening the pull request it installs from requirements.txt and requirements-dev.txt (which pins django-stubs, mypy and time-machine) and runs python manage.py test against the SQLite test database. Failures stay in the sandbox until the new cases pass. The pull request lists which modules were thin, which test files were added, and that production code was left alone.

Start it with one API call

POST https://api.prix.dev/o/{org}/sessions with this body:

{
  "agent": "claude",
  "input": "Find the integration modules in hc/front and hc/api with the fewest tests, write Django TestCase tests for their untested branches, run python manage.py test, and open a pull request. Change no production code.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
  1. Get an API key. In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
  2. Send the request. POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
  3. Read what came back. Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

What comes back

What comes back is a pull request on a new branch. In a repository shaped like healthchecks/healthchecks it adds files under hc/front/tests/ and hc/api/tests/ (and sometimes hc/integrations/<kind>/tests/ when an integration's notify path is the thin spot), each subclassing TestCase or TransactionTestCase and following the Alice/project fixtures from BaseTestCase. Production modules under hc/front, hc/api and hc/integrations are untouched.

The pull request description names the modules that had the fewest tests, the branches each new case exercises, and the exact python manage.py test invocation that passed in the sandbox. The session trajectory keeps every command and its output, including database setup and any settings overrides.

Before merging, a reviewer checks that the new tests assert behaviour rather than private helpers, that they use the project's BaseTestCase patterns instead of a one-off harness, and that no production file slipped into the diff. Once merged, the same suite runs in the repository's existing Tests workflow.

Run it on every pull request labelled needs-tests

Add a GitHub repository webhook for pull_request events and, when the label needs-tests is applied, have your server POST this same body with that repository in resources and the open pull request's branch named in the prompt. Each labelled pull request gets its own sandbox run and its own follow-up commit or sibling pull request with the missing TestCase coverage.

Set a webhook URL on the API key so Rush POSTs run.completed or run.failed when the turn finishes. A key runs at most max_concurrent sessions at once (4 by default) and answers 429 past that, so a backfill across many open pull requests should space its starts.

The use case this job follows, with its automation and trigger: Write the missing tests.

Why run it on Rush?

Filling Django coverage on a laptop means installing the right Django and database pins, waiting on manage.py test, and iterating while your working tree holds half-written cases. On Rush the agent does that loop in its own sandbox with its own clone: it reads the real TestCase style, writes only test files, and keeps python manage.py test green before you see the pull request. Your machine and your branch stay clean.

The result is checkable rather than claimed. The new tests run in the sandbox with the project's SQLite (or Postgres when DB=postgres) settings, the trajectory keeps the command output, and the pull request is the only thing that reaches GitHub. The same request can land missing tests on several Django apps at once, each reviewed before merge.

Frequently asked questions

Will it change my views, models or transports?

The prompt says to change no production code, and the agent keeps the diff to test_*.py files under the existing test packages. If a test reveals a real bug, it stops and describes the failure in the pull request instead of silently patching the bug.

Does it use pytest or Django's test runner?

It follows the repository. In a Healthchecks-shaped app that means python manage.py test and django.test.TestCase, not a new pytest layout. If your app already uses pytest-django, it extends that layout instead of introducing a second runner.

What database does it run against?

Whatever hc/settings.py (or your settings module) uses for tests. Healthchecks defaults to SQLite at hc.sqlite and switches to Postgres when DB=postgres. The agent does not invent a second database configuration.

Can it cover management commands and validators?

Yes. Those are often the thinnest modules: commands under hc/*/management/commands/ with no matching test file, and validators in hc/front/validators.py. It calls them through call_command or form cleaning the way neighbouring tests already do.