The test suite lives in tests/ and uses pytest.
TimeDB stores everything in ClickHouse, so ClickHouse is the only service the
tests need.
pip install -e ".[test]"# Bash/Zsh
export TIMEDB_CH_URL='http://default:devpassword@localhost:8123/default'# Fish
set -x TIMEDB_CH_URL http://default:devpassword@localhost:8123/defaultA local instance is one command away — see DEVELOPMENT.md
for the local-db/ Docker stack.
Use a database you don't mind losing. The live tests create and drop
series_values / run_series.
Live tests skip silently. Without
TIMEDB_CH_URL, every test that needs ClickHouse is skipped, not failed — a green run does not mean the suite passed. Always read the summary line (N passed, M skipped) and treat a non-zero skip count as "the databases weren't reachable".
pytest # everything
pytest -v # verbose
pytest tests/test_integration.py # one file
pytest tests/test_integration.py::test_write_read_roundtrip # one test
pytest --cov=timedb --cov-report=html # coverage → htmlcov/index.html| File | Covers |
|---|---|
test_integration.py |
End-to-end write/read against live ClickHouse: bitemporal reads, retention tiers, skip_unchanged, relative reads |
test_write_validation.py |
Input validation and the skip_unchanged comparison keys — mostly offline |
test_write_concurrency.py |
Concurrent inserts on one client, and the parallel-insert split for large batches |
test_client_sessionless.py |
The clients are sessionless, so independent queries can overlap on one client |
test_imports.py |
The public API surface imports cleanly |
There is no conftest.py: modules that need ClickHouse skip themselves at
import time with pytest.skip(..., allow_module_level=True), and the few
shared helpers (e.g. a td client fixture, per-test series_id generation)
are defined locally in the file that uses them. Tests are independent and can
run in any order.
- Gate on the service if the test needs ClickHouse — follow the
module-level skip in
test_integration.py. Prefer offline tests where the logic allows it. - Allocate fresh
series_ids per test. TimeDB owns no catalog: the caller picksseries_id, so collisions between tests are your responsibility, not the database's. - Use timezone-aware UTC datetimes. Naive timestamps raise.
- Anchor timestamps relative to
now(), not to a literal date. Theshorttier has a 180-day TTL, so a fixed literal silently rots once it ages past the TTL — see theBASE_VTcomment intest_integration.py. - Assert through the public API (
write/read/read_relative) rather than raw ClickHouse queries, unless the point of the test is storage layout.
Everything is skipped — TIMEDB_CH_URL is unset, or ClickHouse is not
reachable at that URL. Check with curl http://localhost:8123/ping.
Permission errors — the ClickHouse user needs CREATE/DROP on tables in the target database.
Import errors for pytest — pip install -e ".[test]".