Skip to content

Testing Conventions

Vector Companion has a comprehensive test suite with 4565 tests across 190+ files in 17 subdirectories. The full suite runs in ~30 seconds with mocked dependencies. All tests must pass before committing.

Running Tests

pytest tests/ -v                          # Full suite
pytest tests/test_security/ -v            # Subpackage tests
pytest tests/ -v -k "tool_host"           # By keyword
pytest tests/test_X/test_file.py::test_foo  # Single test
python -m pytest tests/ -v                # Module form

Test Structure

Tests mirror the core/ directory structure:

tests/
├── conftest.py                          # Session-wide mocks for heavy C-extension modules
├── testkit/                             # Shared fake implementations
│   ├── fake_orchestrator.py
│   ├── fake_metrics_collector.py
│   ├── fake_local_store.py
│   └── ...
├── test_agent/                          # Tests for core/agent/
├── test_security/                       # Tests for core/security/
├── test_data/                           # Tests for core/data/
...
└── test_background_production.py        # Production integration tests (real Ollama)

Cross-cutting tests that import from 3+ subpackages stay at the root as integration tests.

Conftest Auto-Fixtures

conftest.py provides session-wide mocks for expensive dependencies:

Fixture Purpose
_MockPackageFinder Blocks 29 heavy C-extension imports (torch, chromadb, ollama, etc.) session-wide
mock_ollama() Configurable stream of yield chunks for LLM generation simulation
mock_chromadb() Pre-configured PersistentClient mock for vector DB operations
mock_tts() ChatterboxTTS mock with numpy wave output
mock_toast() Auto-use fixture, patches windows_toasts + agent_images

Fake Implementations (testkit/)

The testkit provides production-ready fake implementations of all 22 service Protocols, plus utility modules for e2e testing:

Fake Implements Use Case
FakeOrchestrator OrchestratorProtocol Testing agent turns without real LLM
FakeMetricsCollector MetricsCollectorProtocol Testing telemetry without real collection
FakeLocalStore LocalStoreProtocol Testing CRUD operations in-memory
FakeToolHost ToolHost Configurable tool execution results
FakeEventBus EventBusProtocol Capturing published events for inspection
FakeStreamingCoordinator Bounded queue without TTS/audio
FakeWorkerPool WorkerPoolProtocol Deterministic worker results
FakeIsolationManager ProcessIsolationProtocol Allow/deny isolation decisions
FakeBackgroundTaskQueue In-memory task queue
FakeApprovalWorkflow ApprovalWorkflow Configurable approval decisions
FakeAuditLog AuditLog In-memory audit event capture
FakeAutonomyPolicy AutonomyPolicy Deterministic autonomy tier behavior
FakeAudioBackend Mock STT transcription output
FakeTtsBackend Mock TTS synthesis output
FakeMemoryStore In-memory vector store mock
FakeModelBackend ModelBackendProtocol Deterministic LLM responses
FakeOnboardingManager Configurable onboarding state
FakeSecretStore In-memory secrets storage
FakeSettingsStore In-memory settings persistence
FakeVadBackend Deterministic VAD detection
FakeVisionBackend Mock image captioning output

Plus utility modules: contract_tests.py, e2e_helpers.py (FakeBackendEvent, FakeEventStream, FakeSSEServer), integration_harness.py.

Building Test Doubles

Prefer composition over inheritance. Use frozen dataclasses for immutable test data. Check tests/testkit/ before writing new fakes — one may already exist.

Core Conventions

1. Mock External Dependencies

All tests mock external services. Never call real Ollama, ChromaDB, network endpoints, or GPU hardware in unit tests. Use auto-fixtures from conftest.py or build targeted mocks per test.

2. Test Isolation

  • Singleton cleanup: ModeRegistry and SharedState are singletons. Use _clean_mode_registry() and _clean_shared_state() autouse fixtures.
  • No shared state: Each test creates its own instances. Never reuse objects across test functions.
  • Async tests: Use pytest.mark.asyncio decorator. All async functions must be awaited.

3. Naming Conventions

  • Test files: test_<module_name>.py matching the source module
  • Test functions: test_<function_or_behavior>_<condition>()
  • Fixtures: descriptive names (mode_registry, shared_state, mock_ollama)

4. Coverage Expectations

When adding or modifying a module, write tests for: - Public API surface — every function/method has at least one test - Error paths — exceptions, type errors, edge cases - Async behavior — timeouts, cancellations, concurrent access - Protocol conformance — verify isinstance(instance, Protocol) for all Protocols

5. Path Resolution

When computing project roots from test files in subdirectories:

_PROJECT_ROOT = Path(__file__).parent.parent.parent  # tests/test_X/ -> root
Do NOT use .parent.parent — that resolves to tests/, not the repo root.

Production Integration Tests

tests/test_background_production.py contains 4 tests requiring real Ollama: - Real web search protocol (search → fetch → synthesize) - Consecutive search guard quality - Synthesis output quality - Prompt content validation

Marked for skip in CI. Run manually:

pytest tests/test_background_production.py -v

Persona Quality Tests

tests/persona_integration/run_all — real-Ollama persona evaluation against automated constraints:

python -m tests.persona_integration.run_all --agents axiom axis

Outputs structured JSON to tests/persona_integration/results/. Checks sentence count, markdown absence, stock phrase avoidance, and audio attribution.

See Also

  • Runtimeskip_heavy=True for CI/test mode initialization
  • Event System — Protocol conformance and fake implementations
  • Custom Agents — persona integration test suite