๐งช Testing Framework
/200---2026-01-15/testing-framework
2026-01-15/testing-framework" parent: "200---2026-01-15" order: 8
Comprehensive TDD framework implementing London School patterns with behavior verification, shared fixtures, and mock services.
Philosophy: London School TDD
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ LONDON SCHOOL TDD โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 1. ARRANGE - Set up mocks BEFORE acting โ
โ 2. ACT - Execute the behavior under test โ
โ 3. ASSERT - Verify behavior (interactions), not state โ
โ โ
โ "Test behavior, not implementation" โ
โ "Mock external dependencies, test interactions" โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโQuick Start
typescript
import {
setupV3Tests,
createMockApplication,
agentConfigs,
swarmConfigs,
waitFor,
} from '@claude-flow/testing';
// Configure test environment
setupV3Tests();
describe('MyModule', () => {
const app = createMockApplication();
beforeEach(() => {
vi.clearAllMocks();
});
it('should spawn an agent', async () => {
const result = await app.agentLifecycle.spawn(agentConfigs.queenCoordinator);
expect(result.success).toBe(true);
expect(result.agent.type).toBe('queen-coordinator');
});
});Fixtures
Agent Fixtures
typescript
import {
agentConfigs,
createAgentConfig,
createV3SwarmAgentConfigs,
createMockAgent,
} from '@claude-flow/testing';
// Pre-defined configs
const queen = agentConfigs.queenCoordinator;
const coder = agentConfigs.coder;
// Create with overrides
const customAgent = createAgentConfig('coder', {
name: 'Custom Coder',
priority: 90,
});
// Full V3 15-agent swarm
const swarmAgents = createV3SwarmAgentConfigs();
// Mock agents with vitest mocks
const mockAgent = createMockAgent('security-architect');
mockAgent.execute.mockResolvedValue({ success: true });Memory Fixtures
typescript
import {
memoryEntries,
createMemoryEntry,
generateMockEmbedding,
createMemoryBatch,
} from '@claude-flow/testing';
// Pre-defined entries
const pattern = memoryEntries.agentPattern;
const securityRule = memoryEntries.securityRule;
// Generate embeddings
const embedding = generateMockEmbedding(384, 'my-seed');
// Create batch for performance testing
const batch = createMemoryBatch(10000, 'semantic');Swarm Fixtures
typescript
import {
swarmConfigs,
createSwarmConfig,
createSwarmTask,
createMockSwarmCoordinator,
} from '@claude-flow/testing';
// Pre-defined configs
const v3Config = swarmConfigs.v3Default;
const minimalConfig = swarmConfigs.minimal;
// Create with overrides
const customConfig = createSwarmConfig('v3Default', {
maxAgents: 20,
coordination: {
consensusProtocol: 'pbft',
heartbeatInterval: 500,
},
});
// Mock coordinator
const coordinator = createMockSwarmCoordinator();
await coordinator.initialize(v3Config);MCP Fixtures
typescript
import {
mcpTools,
createMCPTool,
createMockMCPClient,
} from '@claude-flow/testing';
// Pre-defined tools
const swarmInit = mcpTools.swarmInit;
const agentSpawn = mcpTools.agentSpawn;
// Mock client
const client = createMockMCPClient();
await client.connect();
const result = await client.callTool('swarm_init', { topology: 'mesh' });Mock Factory
typescript
import {
createMockApplication,
createMockEventBus,
createMockTaskManager,
createMockSecurityService,
createMockSwarmCoordinator,
} from '@claude-flow/testing';
// Full application with all mocks
const app = createMockApplication();
// Use in tests
await app.taskManager.create({ name: 'Test', type: 'coding', payload: {} });
expect(app.taskManager.create).toHaveBeenCalled();
// Access tracked state
expect(app.eventBus.publishedEvents).toHaveLength(1);
expect(app.taskManager.tasks.size).toBe(1);Async Utilities
typescript
import {
waitFor,
waitUntilChanged,
retry,
withTimeout,
parallelLimit,
} from '@claude-flow/testing';
// Wait for condition
await waitFor(() => element.isVisible(), { timeout: 5000 });
// Wait for value to change
await waitUntilChanged(() => counter.value, { from: 0 });
// Retry with exponential backoff
const result = await retry(
async () => await fetchData(),
{ maxAttempts: 3, backoff: 100 }
);
// Timeout wrapper
await withTimeout(async () => await longOp(), 5000);
// Parallel with concurrency limit
const results = await parallelLimit(
items.map(item => () => processItem(item)),
5 // max 5 concurrent
);Assertions
typescript
import {
assertEventPublished,
assertEventOrder,
assertMocksCalledInOrder,
assertV3PerformanceTargets,
assertNoSensitiveData,
} from '@claude-flow/testing';
// Event assertions
assertEventPublished(mockEventBus, 'UserCreated', { userId: '123' });
assertEventOrder(mockEventBus.publish, ['UserCreated', 'EmailSent']);
// Mock order
assertMocksCalledInOrder([mockValidate, mockSave, mockNotify]);
// Performance targets
assertV3PerformanceTargets({
searchSpeedup: 160,
flashAttentionSpeedup: 3.5,
memoryReduction: 0.55,
});
// Security
assertNoSensitiveData(mockLogger.logs, ['password', 'token', 'secret']);Performance Testing
typescript
import { createPerformanceTestHelper, TEST_CONFIG } from '@claude-flow/testing';
const perf = createPerformanceTestHelper();
perf.startMeasurement('search');
await search(query);
const duration = perf.endMeasurement('search');
// Get statistics
const stats = perf.getStats('search');
console.log(`Avg: ${stats.avg}ms, P95: ${stats.p95}ms`);
// V3 targets
console.log(TEST_CONFIG.FLASH_ATTENTION_SPEEDUP_MIN); // 2.49
console.log(TEST_CONFIG.AGENTDB_SEARCH_IMPROVEMENT_MAX); // 12500Best Practices
| Practice | Do | Don't |
|---|---|---|
| Mock Dependencies | mockRepo.findById.mockResolvedValue(user) | Call real database |
| Use Fixtures | agentConfigs.queenCoordinator | Inline object literals |
| Test Behavior | expect(mockNotifier.notify).toHaveBeenCalled() | expect(service._queue.length).toBe(1) |
| Isolate Tests | vi.clearAllMocks() in beforeEach | Share state between tests |
| Verify Interactions | expect(save).toHaveBeenCalledBefore(notify) | Assert implementation details |