You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 7e46715
Browse filesBrowse the repository at this point in the historyBrowse files
- Key fixtures from `tests/unit/conftest.py`: `patch_central_database`, `sqlite_instance`
30
+
- Key memory fixtures from `tests/unit/conftest.py`:
31
+
- Use `patch_central_database` for tests that access `CentralMemory` or construct targets, scorers, or attacks. Declare it explicitly even in constructor, validation, or identifier tests that do not directly query memory.
32
+
- Use `sqlite_instance` when the test needs to interact with the real isolated SQLite backend.
33
+
- Do not rely on memory or singleton state left behind by another test. Each test must declare its own memory dependency.
34
+
- When changing shared memory fixtures, install all optional dependencies with `uv sync --extra all` and run `make unit-test`. Optional component tests must also exercise fixture isolation.
31
35
- No network calls should ever happen in unit tests, but file access is okay
32
36
- Unit tests should be fast and can be run in parallel.
Copy file name to clipboardExpand all lines: doc/contributing/5_unit_tests.md
+13-1Lines changed: 13 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,11 +6,23 @@ Testing is an art to get right! But here are some best practices in terms of uni
6
6
7
7
- Make a test that checks one thing and one thing only.
8
8
- Use `fixtures` generally, and specifically, if you're using something across classes, use `unit.mocks` or `integration.mocks`.
9
-
- Memory isolation: Use the `patch_central_database` fixture for test database isolation and reset.
9
+
- Memory isolation: Use `sqlite_instance`for a real, isolated SQLite database, or `patch_central_database` when patching CentralMemory access.
10
10
- Code coverage and functionality should be checked with unit tests. Notebooks and integration tests should not be relied on for coverage.
11
11
-`MagicMock` and `AsyncMock`: these are the preferred way to mock calls.
12
12
-`with patch` is acceptable to patch external calls.
13
13
- Don't write to the actual database, use a `MagicMock` for the memory object or use `patch_central_database` as the database connection.
14
14
15
15
16
16
Not all of our current tests follow these practices (we're working on it!) But for some good examples, see [test_tts_send_prompt_file_save_async](../../tests/unit/prompt_target/target/test_tts_target.py), which has many of these best practices incorporated in the test.
17
+
18
+
## SQLite memory fixtures
19
+
20
+
`sqlite_instance` stays function-scoped. Each test gets a fresh in-memory database and results directory, and its SQLite singleton and CentralMemory registrations are restored afterward. The fixture owns disposal of its memory instance instead of registering process-exit cleanup callbacks for every test.
21
+
22
+
Declare the memory fixture explicitly even in constructor or identity tests that create targets, scorers, or attacks. Do not rely on another test leaving CentralMemory initialized.
23
+
24
+
Run `uv sync --extra all` before validating fixture changes with `make unit-test` so optional target tests also exercise memory isolation.
25
+
26
+
To avoid replaying the migration history for every ordinary test, `sqlite_template` runs the real Alembic migrations and schema check once per pytest session (once in each xdist worker). SQLite's backup API copies that private, read-only template into each test's database. Rows, schema changes, temporary tables, and result files are not shared between tests.
27
+
28
+
Tests of initialization, upgrades, downgrades, schema checks, and `reset_database()` must still call those production paths explicitly. The fixture does not replace or patch migration or reset APIs.
0 commit comments