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:

Backend (Python / pytest)

  • Unit Tests - Individual components in isolation
  • Integration Tests - API endpoints and system integration
  • Performance Tests - Load and stress testing

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
Backendpytest + pytest-asyncio201484% overall
Tauri Rustcargo test140embeddings, vector, git, vault, fs, tokenizer, llm, model_manager (140 desktop + 9 mobile-ml)
Frontend UnitVitest (jsdom)3016105 test files, 75% statements, 68% branches, 77% functions
Frontend E2EPlaywright (Chromium)60Auth, tasks, chat, mobile, conversations, search, settings, spaces
Total5230

Coverage Goals

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

🚀 Quick Start

Running All Tests

# Run all tests
cd backend
pytest

# Run with coverage
pytest --cov=. --cov-report=html

# Run specific test file
pytest tests/integration/test_api_endpoints.py

# Run specific test class
pytest tests/integration/test_api_endpoints.py::TestHealthEndpoint

# Run specific test
pytest tests/integration/test_api_endpoints.py::TestHealthEndpoint::test_health_check_returns_200

Running Tests in Docker

# Run tests in Docker container
docker compose -f docker-compose.dev.yml exec backend pytest

# With coverage
docker compose -f docker-compose.dev.yml exec backend pytest --cov

# Watch mode — requires pytest-watch (not in default requirements)
# docker compose -f docker-compose.dev.yml exec backend ptw

📁 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 14, 2026