Confidence in Code That Runs Unattended
Last updated:
Unattended code needs different testing
A web application has users who report problems. A service running overnight has nobody watching, which means its failure handling matters more than its normal operation.
The question is not whether it works with good input. It is what happens with the record that has a null where a date should be, at three in the morning.
What to test
- Transformations — the logic that turns input into output
- Boundaries — what happens with empty, huge, malformed input
- Failure paths — external service down, timeout, bad response
- Idempotency — running the same thing twice
- Reconciliation — the counts add up
Test against real data shapes
- Use anonymised production samples, including the awkward ones
- Include the record that broke it last time
- Test with an empty input set
- Test with a volume larger than you expect
- Test with a deliberately corrupted input
Synthetic clean test data tests the code you wrote against the assumptions you made, which is the least useful thing to verify.
Mock the boundary, not the logic
| Mock | Do not mock |
|---|---|
| External API calls | Your own transformations |
| Time, where behaviour depends on it | Database queries in integration tests |
| Randomness | The logic under test |
| Slow third-party services | Anything you actually want verified |
Run them automatically
Tests that require someone to remember stop being run. They should execute on every push, with a visible result, blocking a merge on failure.
That is a day of setup and it is what turns a test suite into a working safety net rather than a good intention.
Frequently asked questions
How much coverage is enough?
Should tests hit a real database?
How do we test external integrations?
What about testing machine learning code?
Service that runs overnight and sometimes does not?
Its failure paths are probably untested. That is where the tests are worth writing.
Related services
What we build for problems like this one