Skip to main content

Morphee — Testing Guide

Comprehensive testing documentation for Morphee backend and frontend.


📋 Testing Overview

Morphee uses a multi-layered testing approach across backend, frontend, and Tauri Rust:

Test Architecture

Rust Crates (cargo test)

  • morphee-core - Core pipeline, RL policy, compilation, federation (600 tests)
  • morphee-server - Axum HTTP/WS server, auth, CRUD handlers (153 tests)
  • bench-cli - Benchmarking CLI, optimizer, strategies (196 tests)
  • Tauri desktop - IPC commands, embeddings, LLM, git, vault (165 tests)
  • Tauri mobile-ml - Mobile ML inference (9 tests)

Frontend (TypeScript / Vitest + Playwright)

  • Unit Tests - Stores, hooks, and lib utilities (Vitest + jsdom)
  • E2E Tests - Full user flows in real browser (Playwright + Chromium)
  • Coverage - v8 provider via @vitest/coverage-v8

Current Test Counts

LayerFrameworkTestsCoverage
morphee-corecargo test600RL policy, compilation, federation
morphee-servercargo test153Auth, CRUD, knowledge, metrics
bench-clicargo test196Optimizer, strategies, pipeline
Tauri Rustcargo test174165 desktop + 9 mobile-ml
Frontend UnitVitest (jsdom)3,465155 test files, ~81% statements
Frontend E2EPlaywright (Chromium)63Auth, tasks, chat, mobile, conversations, search, settings, spaces
Total4,651

Coverage Goals

  • Frontend overall: >75% statements (currently ~81%), >65% branches (currently ~75%)
  • Frontend stores/hooks/lib: >80% (currently 85-100%)
  • Frontend components: unit tests + E2E coverage

Quick Start

Running All Tests

# Rust crates
cargo test -p morphee-core --features rl-policy
cargo test -p morphee-server
cargo test -p bench-cli

# Tauri desktop
cd frontend/src-tauri && cargo test

# Frontend
cd frontend && npx vitest run
cd frontend && npm run build

📁 Test Structure

backend/tests/
├── __init__.py
├── conftest.py # Shared fixtures
├── test_*.py # Unit tests (30 files)
├── integration/ # Integration tests
│ ├── __init__.py
│ ├── test_api_auth.py
│ ├── test_api_endpoints.py
│ ├── test_api_groups.py
│ ├── test_api_tasks_auth.py
│ ├── test_interface_system.py
│ └── test_websocket_auth.py
└── performance/ # Performance tests
└── test_load.py

🧪 Test Types

1. Unit Tests

Test individual components in isolation.

Location: backend/tests/test_*.py

Examples:

  • test_task_models.py - Task model validation
  • test_event_bus.py - Event bus pub/sub
  • test_interfaces.py - Interface definitions

Running:

pytest tests/test_task_models.py -v

2. Integration Tests

Test API endpoints and component interactions.

Location: backend/tests/integration/

What's Tested:

  • HTTP endpoint responses
  • Interface registration and execution
  • Event publishing
  • Error handling
  • WebSocket connections

Running:

pytest tests/integration/ -v

3. Performance Tests

Test system under load.

Location: backend/tests/performance/

What's Tested:

  • Concurrent request handling
  • Response times under load
  • Event bus throughput
  • Interface execution performance

Running:

pytest tests/performance/ -v --timeout=300

🎯 Testing Specific Features

Testing Interface System

# Test interface registration
pytest tests/integration/test_interface_system.py::TestInterfaceManager

# Test action execution
pytest tests/integration/test_interface_system.py::TestActionExecutor

# Test concurrent execution
pytest tests/integration/test_interface_system.py::TestConcurrentExecution

Testing API Endpoints

# Test health endpoint
pytest tests/integration/test_api_endpoints.py::TestHealthEndpoint

# Test interface endpoints
pytest tests/integration/test_api_endpoints.py::TestInterfaceEndpoints

# Test action execution
pytest tests/integration/test_api_endpoints.py::TestActionExecution

# Test error handling
pytest tests/integration/test_api_endpoints.py::TestErrorHandling

Testing Event System

# Test event bus
pytest tests/test_event_bus.py -v

# Test event publishing
pytest tests/test_task_processor.py::test_event_publishing -v

🔧 Test Configuration

pytest.ini

[pytest]
asyncio_mode = auto
testpaths = tests
python_files = test_*.py
python_classes = Test*
python_functions = test_*
addopts =
-v
--strict-markers
--tb=short
--cov-report=term-missing
markers =
slow: marks tests as slow (deselect with '-m "not slow"')
integration: marks tests as integration tests
performance: marks tests as performance tests

Coverage Configuration

Create .coveragerc:

[run]
source = .
omit =
tests/*
*/site-packages/*
*/__pycache__/*

[report]
exclude_lines =
pragma: no cover
def __repr__
raise AssertionError
raise NotImplementedError
if __name__ == .__main__.:

📊 Test Results

Viewing Coverage Reports

# Generate HTML coverage report
pytest --cov --cov-report=html

# Open in browser
open htmlcov/index.html

CI/CD Integration

Add to .github/workflows/ci.yml:

name: Tests

on: [push, pull_request]

jobs:
test:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.12'

- name: Install dependencies
run: |
cd backend
pip install -r requirements.txt

- name: Run tests
run: |
cd backend
pytest --cov --cov-report=xml

- name: Upload coverage
uses: codecov/codecov-action@v3

✅ Test Best Practices

1. Test Naming

  • Use descriptive names: test_execute_echo_action_returns_correct_result
  • Follow pattern: test_<what>_<expected_behavior>
  • Group related tests in classes

2. Test Independence

  • Tests should not depend on each other
  • Use fixtures for setup/teardown
  • Clean up resources after tests

3. Async Testing

@pytest.mark.asyncio
async def test_async_function():
result = await some_async_function()
assert result is not None

4. Fixtures

@pytest.fixture
async def test_interface():
"""Create test interface"""
interface = TestInterface()
await manager.register_interface(interface)
yield interface
await manager.unregister_interface(interface.name)

5. Parametrized Tests

@pytest.mark.parametrize("input,expected", [
("hello", "HELLO"),
("world", "WORLD"),
("test", "TEST"),
])
async def test_uppercase(input, expected):
result = await uppercase_function(input)
assert result == expected

🐛 Debugging Failed Tests

Run with Verbose Output

pytest -vv tests/integration/test_api_endpoints.py

Run with Print Statements

pytest -s tests/integration/test_api_endpoints.py

Run with Debugger

pytest --pdb tests/integration/test_api_endpoints.py

Stop on First Failure

pytest -x tests/integration/

📝 Writing New Tests

Template for Integration Test

"""
Test description
"""
import pytest
from httpx import AsyncClient, ASGITransport


@pytest.fixture
async def client():
from main import app
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as ac:
yield ac


@pytest.mark.asyncio
class TestFeature:
"""Test feature description"""

async def test_something(self, client):
"""Test should do something"""
response = await client.get("/endpoint")

assert response.status_code == 200
data = response.json()
assert data["field"] == "expected_value"

Template for Unit Test

"""
Test module description
"""
import pytest


@pytest.mark.asyncio
async def test_function():
"""Test should validate something"""
result = await function_to_test()

assert result is not None
assert result.status == "expected"

🎯 Test Checklist

Before committing code, ensure:

  • All tests pass locally
  • New features have tests
  • Bug fixes have regression tests
  • Tests are independent
  • Coverage remains >80%
  • No print statements in tests (use logging)
  • Async tests use @pytest.mark.asyncio
  • Fixtures clean up resources

📚 Additional Resources


🆘 Common Issues

Issue: Tests timeout

Solution: Increase timeout or mark as slow:

@pytest.mark.slow
@pytest.mark.timeout(300)
async def test_slow_operation():
...

Issue: Database connection errors

Solution: Ensure test database is running:

docker compose -f docker-compose.dev.yml up -d supabase-db

Issue: Import errors

Solution: Run tests from backend directory:

cd backend && pytest

Issue: Async tests not working

Solution: Add @pytest.mark.asyncio decorator:

@pytest.mark.asyncio
async def test_async_function():
...


🖥️ Frontend Testing

Framework Setup

  • Unit Tests: Vitest 4 + jsdom + @testing-library/react
  • E2E Tests: Playwright 1.58 + Chromium
  • Coverage: @vitest/coverage-v8
  • Config: frontend/vitest.config.ts, frontend/playwright.config.ts

Running Frontend Tests

cd frontend

# Unit tests (3016 tests)
npm run test

# Unit tests in watch mode
npm run test:watch

# Coverage report
npm run test:coverage

# E2E tests (60 tests, requires running backend)
npm run test:e2e

# E2E tests with UI
npm run test:e2e:ui

Frontend Test Structure

frontend/
├── src/
│ ├── store/__tests__/
│ │ ├── authStore.test.ts # 5 tests - auth state management
│ │ ├── taskStore.test.ts # 11 tests - task state management
│ │ ├── spaceStore.test.ts # 11 tests - space state management
│ │ ├── chatStore.test.ts # 29 tests - chat state + tool calls + approvals
│ │ ├── notificationStore.test.ts # 9 tests - notification state + unread count
│ │ └── componentStore.test.ts # 26 tests - component lifecycle + render/update/dismiss
│ ├── hooks/__tests__/
│ │ ├── useAuth.test.ts # 13 tests - auth hook + SSO
│ │ ├── useTasks.test.ts # 12 tests - task hook + WebSocket events
│ │ ├── useSpaces.test.ts # 5 tests - space hook
│ │ ├── useChat.test.ts # 38 tests - chat hook + streaming + tool callbacks + edit/regenerate
│ │ ├── useOnboarding.test.ts # 9 tests - onboarding hook + SSE
│ │ ├── useNotifications.test.ts # 8 tests - notification hook + WS events
│ │ └── use-toast.test.ts # 12 tests - toast hook
│ ├── lib/__tests__/
│ │ ├── auth.test.ts # 12 tests - token helpers
│ │ ├── api.test.ts # 86 tests - API client + interceptor + notifications + OAuth + push
│ │ ├── runtime.test.ts # 21 tests - Tauri runtime detection + mobile/desktop/hasLocalML
│ │ ├── memory-client.test.ts # 10 tests - memory client routing
│ │ ├── fs-client.test.ts # 12 tests - filesystem client routing
│ │ ├── component-events.test.ts # 21 tests - event tier classification + dispatch
│ │ ├── sse.test.ts # 16 tests - SSE client + streaming + reconnect
│ │ ├── websocket.test.ts # 19 tests - WebSocket client + auth + reconnect
│ │ └── utils.test.ts # 49 tests - humanizeToolCall + formatToolName + utilities
│ ├── components/auth/__tests__/
│ │ └── AuthForm.test.tsx # 13 tests - auth form rendering + SSO buttons
│ ├── components/chat/__tests__/
│ │ ├── ToolCallCard.test.tsx # 20 tests - tool call rendering + humanized display
│ │ ├── ApprovalCard.test.tsx # 9 tests - approval UI + callbacks + timeout
│ │ ├── ComponentRegistry.test.tsx # 9 tests - component registry
│ │ ├── InfoCard.test.tsx # 6 tests - info card rendering
│ │ ├── TaskListRenderer.test.tsx # 5 tests - task list rendering
│ │ ├── ChatBubble.test.tsx # 23 tests - message rendering + markdown + tool calls + edit/copy
│ │ ├── ConversationList.test.tsx # 9 tests - conversation list + CRUD + active state
│ │ ├── PinnedMessages.test.tsx # 10 tests - pinned messages display
│ │ ├── ConversationSettingsDialog.test.tsx # 8 tests - conversation settings
│ │ └── renderers.test.tsx # 70 tests - all 10 component renderers via ComponentRenderer
│ ├── components/layout/__tests__/
│ │ ├── Sidebar.test.tsx # 3 tests - sidebar rendering
│ │ ├── MobileSidebar.test.tsx # 3 tests - mobile sidebar
│ │ ├── Header.test.tsx # 7 tests - header rendering
│ │ ├── NotificationBell.test.tsx # 22 tests - notification bell + badge + dropdown
│ │ ├── FeatureTour.test.tsx # 11 tests - feature tour overlay
│ │ ├── Breadcrumbs.test.tsx # 6 tests - breadcrumb navigation
│ │ └── BottomNav.test.tsx # 4 tests - mobile bottom navigation
│ ├── components/settings/__tests__/
│ │ ├── GoogleConnect.test.tsx # 13 tests - OAuth connection flow
│ │ └── InterfaceConfigCard.test.tsx # 9 tests - interface config CRUD
│ ├── components/tasks/__tests__/
│ │ ├── TaskList.test.tsx # 9 tests - task list rendering
│ │ ├── TaskDetail.test.tsx # 31 tests - task detail view + inline editing
│ │ ├── CreateTaskDialog.test.tsx # 12 tests - task creation dialog
│ │ └── ConnectionStatus.test.tsx # 9 tests - WebSocket connection status
│ ├── components/spaces/__tests__/
│ │ ├── SpaceList.test.tsx # 7 tests - space list rendering
│ │ ├── SpaceDetail.test.tsx # 12 tests - space detail view
│ │ ├── SpaceCard.test.tsx # 3 tests - space card rendering
│ │ └── CreateSpaceDialog.test.tsx # 5 tests - space creation dialog
│ ├── components/ui/__tests__/
│ │ └── empty-state.test.tsx # 5 tests - empty state component
│ ├── components/search/__tests__/
│ │ └── SearchDialog.test.tsx # 10 tests - global search dialog
│ └── pages/__tests__/
│ ├── Dashboard.test.tsx # 15 tests - dashboard stats + recent tasks + conversations
│ ├── Login.test.tsx # 3 tests - login page
│ ├── AuthCallback.test.tsx # 8 tests - SSO callback + token extraction
│ ├── Settings.test.tsx # 24 tests - profile + notifications + integrations + oauth
│ ├── Chat.test.tsx # 15 tests - chat page + skeleton loaders + retry + search
│ ├── Tasks.test.tsx # 10 tests - task page + sorting
│ ├── Spaces.test.tsx # 8 tests - spaces page
│ ├── Onboarding.test.tsx # 9 tests - onboarding page
│ ├── AcceptInvite.test.tsx # 5 tests - invite acceptance
│ ├── ParentConsentPending.test.tsx # 7 tests - parent consent pending
│ └── ParentConsentVerify.test.tsx # 11 tests - parent consent verify
├── e2e/
│ ├── auth.spec.ts # 8 tests - signup, login, logout, onboarding flow
│ ├── tasks.spec.ts # 7 tests - create, detail, filter, dashboard
│ └── chat.spec.ts # 7 tests - empty state, send, streaming, error
└── vitest.config.ts # Vitest + coverage config

Frontend Coverage Report

Run: npm run test:coverage

File / AreaStmtsBranchFuncsLines
src/store/authStore.ts100%100%100%100%
src/store/taskStore.ts100%100%100%100%
src/store/spaceStore.ts100%100%100%100%
src/store/chatStore.ts100%100%100%100%
src/store/notificationStore.ts100%100%100%100%
src/store/componentStore.ts100%100%100%100%
src/types/index.ts100%100%100%100%
src/lib/auth.ts100%90%100%100%
src/hooks/useAuth.ts94%100%100%94%
src/hooks/useTasks.ts86%38%100%87%
src/hooks/useSpaces.ts~85%~40%100%~85%
src/hooks/useChat.ts~80%~50%100%~80%
src/lib/api.ts76%91%33%76%
Chat components~70%~50%100%~70%
Other Components / Pages0%0%0%0%

Strategy: Stores, hooks, and lib are well covered by unit tests. Chat components (ToolCallCard, ApprovalCard, ChatBubble, ConversationList, all 10 renderers) have dedicated unit tests. SSE and WebSocket clients have full unit test coverage. Other components and pages are covered by E2E tests (22 Playwright tests) which aren't reflected in the unit coverage numbers.


Last Updated: February 25, 2026