Testing Infrastructure
Relevant source files
- .claude/commands/release/beta.md
- .claude/commands/release/changelog.md
- .claude/commands/release/release-check.md
- .claude/commands/release/release.md
- .github/workflows/claude-issue-triage.yml
- .github/workflows/test.yml
- justfile
- plugins/codex/hooks/test_codex_pre_compact.py
- plugins/codex/hooks/test_codex_session_start.py
- scripts/edit-issue-labels.sh
- scripts/update_versions.py
- src/basic_memory/api/container.py
- src/basic_memory/api/v2/routers/prompt_router.py
- src/basic_memory/deps/__init__.py
- src/basic_memory/deps/config.py
- src/basic_memory/deps/db.py
- src/basic_memory/deps/importers.py
- src/basic_memory/deps/projects.py
- src/basic_memory/deps/repositories.py
- test-int/conftest.py
- test-int/semantic/conftest.py
- test-int/semantic/corpus.py
- test-int/semantic/metrics.py
- test-int/semantic/test_embedding_provider_reuse.py
- test-int/semantic/test_real_fastembed_reranker.py
- test-int/semantic/test_reranker_latency.py
- test-int/semantic/test_reranker_quality.py
- tests/api/v2/conftest.py
- tests/cli/conftest.py
- tests/mcp/conftest.py
- tests/test_claude_issue_triage.py
- tests/test_claude_plugin_hooks.py
- tests/test_deps.py
- tests/test_update_versions.py
Basic Memory employs a robust, three-tier testing strategy designed to ensure reliability across its local-first architecture. The suite covers everything from isolated unit logic to end-to-end MCP tool execution, supporting both SQLite and PostgreSQL backends.
Three-Tier Test Suite
The codebase organizes tests into three distinct directories based on their scope and execution speed justfile38-45:
Integration Test Data Flow
Integration tests utilize an ASGITransport to bridge the MCP server and the FastAPI application within a single process, avoiding the overhead of real network sockets test-int/conftest.py13 test-int/conftest.py71 This allows testing the full API stack, including middleware and dependency injection, without requiring a live network interface.
Flow Diagram: Integration Test Execution
Sources: test-int/conftest.py12-17 test-int/conftest.py71 test-int/conftest.py87-88 tests/mcp/conftest.py69-72
Database Backends & Testcontainers
Basic Memory supports dual backends justfile19-21 By default, tests run against SQLite for speed justfile42 To test PostgreSQL parity, the suite uses testcontainers to manage ephemeral Docker instances.
PostgreSQL Testing Lifecycle
- Detection: Tests check
BASIC_MEMORY_TEST_POSTGRES=1to toggle the backend test-int/conftest.py108-109 - Provisioning:
postgres_containerfixture spins uppgvector/pgvector:pg16to support vector search extensions test-int/conftest.py125-127 - External Overrides: If
BASIC_MEMORY_TEST_POSTGRES_URLis set, the suite uses the provided server instead of spinning up a container test-int/conftest.py180-190 - Cleanup: Ephemeral tables such as
search_vector_embeddingsandsearch_vector_indexare cleared between runs test-int/conftest.py171-175
Sources: justfile19-29 test-int/conftest.py108-127 test-int/conftest.py180-190
Pytest Fixtures and conftest Patterns
Global Fixtures
db_backend: Determines the target database engine (sqlite vs postgres) test-int/conftest.py102-110postgres_container: Manages the Docker lifecycle for Postgres usingPostgresContainertest-int/conftest.py113-127cleanup_global_db_after_test: Anautousefixture that callsdb.shutdown_db()to prevent non-daemonaiosqliteworkers from hanging after tests finish test-int/conftest.py129-141
Specialized Fixtures
- CLI Isolation:
isolated_homeprevents tests from polluting the user's actual~/.basic-memorydirectory by mockingHOMEandBASIC_MEMORY_HOMEtests/cli/conftest.py15-37 - Routing Isolation:
clean_routing_envensures environment variables likeBASIC_MEMORY_FORCE_LOCALdo not leak between test cases test-int/conftest.py144-153 - FastAPI Dependency Overrides: The
appfixture in MCP tests appliesdependency_overridesforget_app_configandget_engine_factoryto inject test-specific configuration tests/mcp/conftest.py50-65 - Search Indexing:
init_search_indexexplicitly callsSearchService.init_search_indexto prepare FTS5 or pgvector tables for search-dependent tests tests/mcp/conftest.py89-92
Sources: test-int/conftest.py129-153 tests/cli/conftest.py15-37 tests/mcp/conftest.py50-92
Testmon and Performance Optimization
To maintain a fast developer loop, the project uses pytest-testmon to track which tests are affected by code changes .github/workflows/test.yml19-23
- CI Selection: In GitHub Actions,
BASIC_MEMORY_TESTMON_FLAGSselects only impacted tests for branch builds using--testmon --testmon-forceselect, while running the full suite onmainwith--testmon-noselect.github/workflows/test.yml23 - CI Sharding: The Postgres unit suite is sharded across parallel jobs in CI using
pytest-splitto reduce wall-clock time .github/workflows/test.yml220-226 - Local Caching: The
testmon-seedandtestmon-refreshrecipes in thejustfilemanage the synchronization of the.testmondatacache justfile87-97
Entity Mapping: Test Orchestration
Sources: .github/workflows/test.yml19-23 .github/workflows/test.yml220-226 justfile87-97 test-int/conftest.py71
Running Tests
Tests are executed using pytest, typically via the just command runner justfile17-36
Common Commands
- Run all tests:
just test(Runs both SQLite and Postgres suites) justfile39 - SQLite Unit Tests:
just test-unit-sqlitejustfile48-49 - Postgres Unit Tests:
just test-unit-postgres(Uses testcontainers) justfile53-56 - Impacted Tests Only:
just fast-testorjust testmonjustfile79-85 - MCP Smoke Test:
just test-smokefor a fast end-to-end validation justfile103-104 - Read Cache Tests:
just test-read-cacheruns semantic read-cache suite against Redis justfile108-109
Environment Variables
BASIC_MEMORY_TEST_POSTGRES=1: Switches the test backend to Postgres justfile56BASIC_MEMORY_TEST_POSTGRES_URL: Overrides the auto-provisioned Postgres container with a specific URL for CI test-int/conftest.py180-182
Sources: justfile38-109 test-int/conftest.py108-110 test-int/conftest.py180-190
Refresh this wiki
