Overview
The ClarkOS SDK includes a comprehensive Jest test framework with 179 tests across 7 test suites, providing full coverage of core functionality.Test Suite
See the complete test suite on GitHub
Quick Start
Test Coverage
| Module | Tests | Description |
|---|---|---|
core/tick | 25 | Routine calculation, health drift, tick execution, tick runner |
core/config | 22 | Configuration validation, environment loading, Zod schemas |
memory/deduplication | 34 | 3-tier dedup strategy, type thresholds, similarity |
backend/memory | 22 | In-memory backend, state management, CRUD operations |
plugins/loader | 26 | Plugin validation, dependency sorting, cycle detection |
llm/embeddings | 32 | Cosine similarity, find similar, provider configurations |
services/news | 21 | Service lifecycle, caching, deduplication |
| Total | 179 | All passing |
Test Structure
Writing Tests
Basic Test Structure
Using MemoryBackend for Tests
TheMemoryBackend is ideal for testing without a real Convex deployment:
Testing Plugins
Mocking External APIs
For tests that call external APIs (LLM, embeddings), mock the fetch function:Test Configuration
The framework uses Jest with ESM support:Running Specific Tests
Coverage Reports
After runningnpm run test:coverage:
coverage/lcov-report/index.html- HTML report (open in browser)coverage/lcov.info- LCOV format for CI integration- Terminal output shows summary
What’s Tested
Tick System
- Routine boundaries (6am, 12pm, 6pm, 12am)
- Health drift calculations with mean reversion toward 75
- Cryo mode behavior
- Plugin hook execution
- Error handling and recovery
Deduplication
- All 5 memory type thresholds:
- Episodic: 0.92
- Semantic: 0.95
- Emotional: 0.88
- Procedural: 0.97
- Reflection: 0.90
- 3-tier strategy:
- Exact content match
- Jaccard similarity (word overlap > 0.85)
- Embedding similarity (type-specific)
Plugin System
- Plugin validation rules
- Dependency resolution (topological sort)
- Circular dependency detection
- Lifecycle hooks (init, cleanup, onTick)
Embeddings
- Cosine similarity calculations
- Provider configuration (Gemini, OpenAI, custom)
- Batch embedding support
- Error handling for API failures
Best Practices
Isolate tests
Isolate tests
Each test should be independent. Use
beforeEach to reset state and afterEach for cleanup.Test behavior, not implementation
Test behavior, not implementation
Focus on what the function does, not how it does it. This makes tests more resilient to refactoring.
Use descriptive names
Use descriptive names
Test names should describe the expected behavior: “returns error when agent is in cryo mode” not “test cryo”.
Keep tests fast
Keep tests fast
Mock external dependencies. Use
MemoryBackend instead of real Convex connections.Test edge cases
Test edge cases
Include tests for error conditions, empty inputs, and boundary values.