Integration Tests
Dockerized integration tests for the tbd server.
Quick Start
Run the full test suite (builds the app, starts it, runs tests):
cd integration-test
docker-compose up --abort-on-container-exit
Manual Run (app already running)
If your tbd app is running locally on port 3000:
cd integration-test
docker run --rm -v "$(pwd)/integration_test.bb:/integration_test.bb:ro" babashka/babashka:latest bb /integration_test.bb http://host.docker.internal:3000
Or run directly on a host with babashka installed:
cd integration-test
bb integration_test.bb http://localhost:3000
Or from the repo root, via the script:
script/integration-test
Options
| Flag | Default | Description |
|---|---|---|
[base-url] (positional) |
http://localhost:3000 |
Server to test against |
--watch |
off | Re-run the suite on a timer instead of exiting after one run |
--interval <ms> |
5000 |
Delay between runs in watch mode |
Example — watch a local server every 2 seconds:
bb integration-test/integration_test.bb http://localhost:3000 --watch --interval 2000
What's Tested
| # | Test | Checks |
|---|---|---|
| 1 | GET / returns 200 |
HTTP status code |
| 2 | Content-Type header |
text/html |
| 3 | Response body | The HTML shell: mount point and /js/main.js script tag |
| 4 | GET /js/main.js |
200, JavaScript, non-empty, contains the UI's /api/add call |
| 5 | HEAD / works |
HTTP 200 |
| 6 | GET /api/ping |
200, body pong |
| 7 | GET /swagger.json |
200, JSON, references /api/ping |
| 8 | GET /api-docs |
200, text/html |
| 9 | GET /api/add?x=2&y=3 |
200, EDN {:result 5} |
| 10 | GET /api/add with bad params |
400 for a missing or non-numeric param |
| 11 | GET /auth/login |
302 to Gitea's authorize URL with the client id and a state; HttpOnly cookie |
| 12 | GET /auth/callback with no login in progress |
400 |
| 13 | GET /auth/me without a session |
401 |
| 14 | POST /nrepl without a session |
401, even with an invalid body |
The app container gets dummy Gitea settings from docker-compose.yml, so tests 11-14 cover the
unauthenticated surface only; completing a login needs a real Gitea (the unit tests stub one).
Test 4 needs the compiled UI, which the Docker image includes (script/integration-test
builds it). Against a locally running server, run script/ui-build first.
Line Coverage
Line coverage is measured with Cloverage for the unit tests, the integration tests, and both combined. From the repo root:
| Task | What it does | Output |
|---|---|---|
script/unit-coverage |
Runs test/ under Cloverage |
target/coverage/unit/ |
script/integration-coverage |
Runs the integration suite against a Cloverage-instrumented tbd-app container |
target/coverage/integration/ |
script/coverage-report |
Merges the two lcov.info files, prints a per-file table |
target/coverage/merged/ |
script/coverage |
All three, in order (the full suite with a joint report) | all of the above |
Each directory contains an index.html (open it in a browser) and an lcov.info. In the
merged report a line counts as covered if either suite hit it; the HTML shows per-line hit
counts per suite (u: unit, i: integration).
How the integration numbers are collected: docker-compose.coverage.yml starts the app via
tbd.integration.coverage, which lets Cloverage instrument src/ and then serves real
traffic until it receives SIGTERM. script/integration-coverage stops the container
(docker compose stop) so the report gets written, then copies it out with docker compose cp.
Plain script/integration-test / script/test are unchanged and run the uninstrumented app.