Testing
This page describes the testing strategy for Med-SEAL Suite and how to run tests for each service.
Overview
Component |
Test Type |
Tool |
|---|---|---|
AI Service |
Unit + integration |
Jest + Supertest |
Patient Portal Native |
Component + E2E |
Jest + Detox |
AI Frontend |
Component |
Vitest + React Testing Library |
FHIR integration |
Integration |
Medplum test server |
Full stack |
Smoke tests |
Docker Compose |
AI Service Tests
Run All Tests
cd apps/ai-service
npm test
Run with Coverage
npm run test:coverage
Unit Tests
Unit tests live in apps/ai-service/src/**/__tests__/. They mock FHIR calls and the LLM client:
// handler.test.ts
import { myFeatureHandler } from '../handlers/my-feature';
jest.mock('../lib/medplum', () => ({
medplum: {
search: jest.fn().mockResolvedValue({ entry: [] }),
},
}));
jest.mock('../lib/llm', () => ({
callLLM: jest.fn().mockResolvedValue('Test response'),
}));
describe('myFeatureHandler', () => {
it('returns a structured response', async () => {
const result = await myFeatureHandler('patient-123', {});
expect(result).toHaveProperty('result');
expect(result.guardDecision).toBe('PASS');
});
});
Integration Tests
Integration tests in apps/ai-service/src/__integration__/ run against the full Docker stack. They require the stack to be running:
# Start the stack first
docker compose up -d
# Then run integration tests
npm run test:integration
Patient Portal Native Tests
Unit and Component Tests
cd apps/patient-portal-native
npm test
Component tests use Jest and React Native Testing Library:
import { render, fireEvent } from '@testing-library/react-native';
import { MedicationCard } from '../components/MedicationCard';
it('calls onConfirm when tapped', () => {
const onConfirm = jest.fn();
const { getByText } = render(
<MedicationCard medication={mockMed} onConfirm={onConfirm} />
);
fireEvent.press(getByText('Mark as Taken'));
expect(onConfirm).toHaveBeenCalledTimes(1);
});
E2E Tests (Detox)
E2E tests require a running simulator:
# Build the test app
npx detox build --configuration ios.sim.debug
# Run E2E tests
npx detox test --configuration ios.sim.debug
Testing FHIR Integrations
For isolated FHIR testing, use Medplum’s in-memory test client:
import { MockClient } from '@medplum/mock';
const medplum = new MockClient();
// Seed test data
await medplum.createResource({
resourceType: 'Patient',
id: 'test-patient',
name: [{ family: 'Doe', given: ['John'] }],
});
// Your code under test
const result = await fetchPatientMedications(medplum, 'test-patient');
expect(result).toHaveLength(0);
@medplum/mock is an in-memory FHIR server that requires no external services.
Smoke Testing the Full Stack
After docker compose up -d, run the built-in smoke check:
node scripts/smoke-test.js
This script checks:
Medplum FHIR API responds at
localhost:8103OpenEMR is reachable at
localhost:8081AI Service
/healthreturnsokSSO database is accessible
A test patient can be created and retrieved via FHIR
Continuous Integration
The repository uses GitHub Actions for CI. The workflow runs on every pull request:
# .github/workflows/ci.yml
- npm install && npm test # AI Service
- npm install && npm test # AI Frontend
- npm install && npm test # Patient Portal Native
All tests must pass before a PR can be merged.