Skip to content

Testing and Quality Assurance Unit Testing

github-actions[bot] edited this page Aug 3, 2026 · 3 revisions

Unit Testing

Referenced Files in This Document

Table of Contents

  1. Introduction
  2. Project Structure
  3. Core Components
  4. Architecture Overview
  5. Detailed Component Analysis
  6. Dependency Analysis
  7. Performance Considerations
  8. Troubleshooting Guide
  9. Conclusion
  10. Appendices

Introduction

This document explains unit testing practices for Kairos MCP, focusing on how to write effective tests for functions, classes, and modules; how to mock external dependencies (databases, HTTP clients, file systems); what testing utilities are available; how to cover business logic, utilities, and internal services; coverage requirements and reporting; asynchronous code and error handling; and guidelines for high-quality tests with strong assertions and descriptive names.

Project Structure

Kairos MCP uses a layered test layout:

  • Unit tests under tests/unit for pure logic and isolated components
  • Integration tests under tests/integration that exercise HTTP APIs, MCP flows, and storage backends
  • Shared test utilities and mocks under tests/utils and tests/mocks
  • Test configuration via Jest and Vitest, plus TypeScript settings for tests
graph TB
subgraph "Tests"
U["tests/unit"]
I["tests/integration"]
UT["tests/utils"]
M["tests/mocks"]
R["tests/reporters"]
end
subgraph "Config"
JCFG["jest.config.js"]
VCFG["vitest.config.ts"]
TSCFG["tsconfig.tests.json"]
PKG["package.json"]
end
U --> JCFG
I --> JCFG
U --> VCFG
I --> VCFG
U --> TSCFG
I --> TSCFG
PKG --> JCFG
PKG --> VCFG
Loading

Diagram sources

Section sources

Core Components

Section sources

Architecture Overview

The testing architecture separates concerns by scope:

  • Unit tests validate deterministic logic without real I/O
  • Integration tests run the HTTP server and interact with real or containerized backends (e.g., Qdrant, Redis, Keycloak)
  • Shared harnesses bootstrap servers, databases, and fixtures for integration suites
graph TB
subgraph "Unit Tests"
U1["tests/unit/*"]
end
subgraph "Integration Tests"
I1["tests/integration/*"]
H["tests/integration/harness/*"]
end
subgraph "External Dependencies"
Q["Qdrant"]
R["Redis"]
K["Keycloak"]
end
U1 --> |"Mocked"| Q
U1 --> |"Mocked"| R
I1 --> H
H --> |"Starts"| S["HTTP Server"]
S --> Q
S --> R
S --> K
Loading

[No sources needed since this diagram shows conceptual workflow, not actual code structure]

Detailed Component Analysis

Writing Effective Unit Tests

  • Scope and isolation
    • Keep each test focused on a single function, class, or module behavior.
    • Avoid real network calls, disk writes, or database access; use mocks or in-memory implementations.
  • Naming and organization
    • Use descriptive names that state the scenario and expected outcome.
    • Group related tests using nested describe blocks.
  • Assertions
    • Prefer explicit equality checks and structured matchers over vague truthiness.
    • Assert both happy paths and error branches.
  • Asynchronous code
    • Return promises from test functions or use async/await.
    • For timers, prefer controlled time utilities rather than sleeping.
  • Edge cases
    • Cover empty inputs, boundary values, invalid schemas, and unexpected types.
  • Examples in the repository

Section sources

Mocking External Dependencies

  • Databases and vector stores
    • Replace real Qdrant client with a mock implementation or an in-memory adapter when testing memory operations.
    • Example pattern: see tests/unit/memory-store.test.ts.
  • HTTP clients
    • Intercept or stub HTTP requests using your preferred strategy (e.g., node-fetch mocking, undici interceptors) to avoid real network calls.
  • File system
    • Use temporary directories or in-memory filesystem abstractions to isolate file-based logic.
  • Caching and background services
    • Stub Redis cache and metrics collectors to prevent side effects.
  • Example service interfaces used across tests

Section sources

Testing Internal Services and Business Logic

sequenceDiagram
participant Test as "Test Case"
participant Service as "Service Under Test"
participant Q as "Qdrant Client (mock)"
participant Cache as "Redis Cache (stub)"
Test->>Service : "invoke method()"
Service->>Cache : "check/read cache"
Cache-->>Service : "miss"
Service->>Q : "query/search"
Q-->>Service : "results"
Service->>Cache : "write cache"
Service-->>Test : "result"
Loading

Diagram sources

Section sources

Testing HTTP APIs and MCP Flows

sequenceDiagram
participant IT as "Integration Test"
participant Harness as "Server Harness"
participant API as "HTTP Server"
participant DB as "Database/Qdrant"
IT->>Harness : "start server"
Harness->>API : "listen"
IT->>API : "HTTP request"
API->>DB : "read/write"
DB-->>API : "data"
API-->>IT : "response"
IT->>Harness : "stop server"
Loading

Diagram sources

Section sources

Testing Utilities and Helpers

Section sources

Error Handling Scenarios and Edge Cases

Section sources

Test Coverage Requirements and Reporting

Section sources

Guidelines for High-Quality Unit Tests

  • Deterministic and fast
  • Isolated and repeatable
    • Reset or seed state between tests; do not share mutable state across tests.
  • Clear expectations
    • Use precise assertions and include context in failure messages.
  • Descriptive names
    • Follow “should when ” naming style.
  • Minimal coupling
    • Mock only what is necessary; keep mocks close to the tested component.

[No sources needed since this section provides general guidance]

Dependency Analysis

The following diagram maps key test dependencies and their relationships to production services.

graph LR
U["Unit Tests<br/>tests/unit/*"] --> |Mock| QD["Qdrant Service<br/>src/services/qdrant/service.ts"]
U --> |Stub| RC["Redis Cache<br/>src/services/redis-cache.ts"]
I["Integration Tests<br/>tests/integration/*"] --> HS["HTTP Server<br/>src/http/http-server.ts"]
HS --> QD
HS --> RC
Loading

Diagram sources

Section sources

Performance Considerations

  • Keep unit tests fast by avoiding real I/O and heavy initialization.
  • Parallelize independent tests; limit concurrency where shared resources are involved.
  • Reuse expensive fixtures within a suite rather than recreating them per test.
  • Use targeted mocks to reduce overhead in hot paths.

[No sources needed since this section provides general guidance]

Troubleshooting Guide

Section sources

Conclusion

Adopting these practices ensures reliable, maintainable tests across unit and integration layers. By isolating logic, mocking external dependencies, leveraging shared utilities, and enforcing clear assertions and naming, you can achieve robust coverage and faster feedback loops.

Appendices

Quick Start Checklist

  • Choose the right runner: Jest for Node tests, Vitest for UI tests.
  • Place unit tests under tests/unit and integration tests under tests/integration.
  • Use shared helpers from tests/utils for timeouts, auth, and MCP interactions.
  • Mock Qdrant and Redis in unit tests; use harnesses for integration tests.
  • Add descriptive test names and explicit assertions.
  • Configure coverage thresholds and enable reporting.

[No sources needed since this section provides general guidance]

KAIROS MCP

Clone this wiki locally