Repository navigation
Testing Strategy
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Conclusion
- Appendices
This document defines a comprehensive testing strategy for PersonalLearningPro. It outlines the testing pyramid implementation across unit, integration, and component (UI) tests, details Vitest configuration and utilities, and documents backend testing approaches including database integration and API validation. It also covers best practices for React components, async operations, and WebSocket interactions, along with coverage expectations, CI testing, performance testing, debugging techniques, test data management, and automated workflows.
The repository follows a frontend/backend split with a clear separation of concerns:
- Frontend (React + Vite): Located under client/. Includes UI components, pages, hooks, contexts, and tests.
- Backend (Express + TypeScript): Located under server/. Includes routes, storage abstraction, libraries for external integrations, and database helpers.
- Shared schemas/types: Located under shared/.
- Scripts: Utility scripts for local development and testing (e.g., database connectivity checks).
graph TB
subgraph "Frontend (client)"
FE_Vite["Vite Config<br/>vite.config.ts"]
FE_Tests["Unit Tests<br/>client/src/tests/*"]
FE_Components["Components & Pages"]
end
subgraph "Backend (server)"
BE_Routes["Routes<br/>server/routes.ts"]
BE_Storage["Storage Abstraction<br/>server/storage.ts"]
BE_Cassandra["Cassandra Helpers<br/>server/lib/cassandra.ts"]
BE_Scripts["DB Test Script<br/>scripts/test-db.ts"]
end
FE_Vite --> FE_Tests
FE_Components --> BE_Routes
BE_Storage --> BE_Cassandra
BE_Scripts --> BE_Cassandra
Diagram sources
- vite.config.ts
- client/src/tests/LoginPage.test.tsx
- server/routes.ts
- server/storage.ts
- server/lib/cassandra.ts
- scripts/test-db.ts
Section sources
- vite.config.ts
- package.json
- Frontend testing framework: Vitest with React Testing Library and user-event for UI interactions.
- Backend testing: HTTP route tests against a real storage layer with optional Cassandra integration.
- Storage abstraction: Provides a unified interface for MongoDB and Cassandra-backed operations.
- Cassandra helpers: Initialize and validate the Cassandra connection and schema.
Key testing capabilities present:
- Unit tests for UI components using Vitest and Testing Library.
- Backend route tests validating request/response flows and authorization logic.
- Database connectivity and CRUD validation via a dedicated script.
Section sources
- client/src/tests/LoginPage.test.tsx
- server/routes.ts
- server/storage.ts
- server/lib/cassandra.ts
- scripts/test-db.ts
The testing architecture aligns with the application’s layered design:
- UI layer: React components tested via Vitest and Testing Library.
- Service/Storage layer: Unified interface abstracting MongoDB and Cassandra.
- API layer: Express routes enforcing authentication, authorization, and data validation.
- External integrations: OCR, AI evaluation, and uploads handled by service libraries.
graph TB
UI["React Components<br/>client/src/components/*"]
Hooks["Hooks & Contexts<br/>client/src/hooks/*"]
Tests["Vitest + RTL<br/>client/src/tests/*"]
Routes["Express Routes<br/>server/routes.ts"]
Storage["Storage Abstraction<br/>server/storage.ts"]
Cassandra["Cassandra Client<br/>server/lib/cassandra.ts"]
UI --> Hooks
UI --> Tests
Hooks --> Routes
Routes --> Storage
Storage --> Cassandra
Diagram sources
- client/src/tests/LoginPage.test.tsx
- server/routes.ts
- server/storage.ts
- server/lib/cassandra.ts
- Test runner: Vitest configured for React projects.
- Utilities:
- @testing-library/react for DOM queries and assertions.
- @testing-library/user-event for realistic user interactions.
- jest-dom matchers for accessibility and DOM assertions.
- Example patterns:
- Rendering components and asserting presence of roles/labels.
- Simulating user input and verifying controlled component updates.
- Triggering form submission and asserting handler invocations.
- Async validations and error message assertions.
sequenceDiagram
participant T as "Vitest Runner"
participant R as "React Testing Library"
participant U as "User Event"
participant C as "LoginPage Component"
T->>R : "render(<LoginPage/>)"
R-->>T : "screen instance"
T->>U : "user.type(input, value)"
U-->>C : "onChange handlers"
T->>R : "expect(input).toHaveValue(value)"
T->>U : "user.click(button)"
U-->>C : "onSubmit handlers"
T->>R : "waitFor(() => expect(handler).toHaveBeenCalledWith(...))"
Diagram sources
- client/src/tests/LoginPage.test.tsx
Section sources
- client/src/tests/LoginPage.test.tsx
- package.json
- Route-level tests: Validate authentication, authorization, input validation, and response shapes.
- Storage integration: Tests exercise the storage layer to ensure CRUD operations and cross-database fallbacks.
- Cassandra integration: Optional Astra DB integration with schema initialization and message operations.
sequenceDiagram
participant C as "Client"
participant S as "Express Server"
participant ST as "Storage Layer"
participant CA as "Cassandra Client"
C->>S : "POST /api/auth/register {userData}"
S->>ST : "getUserByUsername / getUserByEmail"
ST->>CA : "optional Cassandra ops"
S->>ST : "createUser(userData)"
ST-->>S : "User record"
S-->>C : "201 JSON userWithoutPassword"
Diagram sources
- server/routes.ts
- server/storage.ts
- server/lib/cassandra.ts
Section sources
- server/routes.ts
- server/storage.ts
- server/lib/cassandra.ts
- Dedicated script validates Cassandra connectivity and performs basic CRUD operations against the messages table.
- The script initializes Cassandra, creates a test message, retrieves messages for a channel, and asserts content correctness.
flowchart TD
Start(["Run test-db.ts"]) --> Init["Initialize Cassandra Client"]
Init --> CreateMsg["Create Test Message"]
CreateMsg --> Retrieve["Retrieve Messages by Channel"]
Retrieve --> Compare{"Content Matches?"}
Compare --> |Yes| Success["Log SUCCESS"]
Compare --> |No| Failure["Log FAILURE"]
Success --> End(["Exit"])
Failure --> End
Diagram sources
- scripts/test-db.ts
- server/lib/cassandra.ts
Section sources
- scripts/test-db.ts
- server/lib/cassandra.ts
- WebSocket handling is present in the frontend and backend chat modules. For testing:
- Use Vitest spies to mock WebSocket connections and verify event emissions.
- For async operations, wrap assertions with waitFor and use fake timers where appropriate.
- Validate optimistic UI updates and subsequent reconciliation after API responses.
[No sources needed since this section provides general guidance]
- Use Vitest mocks for:
- External APIs and services (e.g., chat API, OCR).
- Firebase authentication dialogs and contexts.
- WebSocket hooks to simulate connection events and message broadcasts.
- Prefer mocking at the module boundary (e.g., lib/chat-api.ts) to isolate component logic.
[No sources needed since this section provides general guidance]
- Frontend depends on Vitest, React Testing Library, and user-event for UI tests.
- Backend routes depend on the storage abstraction and external libraries for OCR and AI evaluation.
- Storage abstraction conditionally delegates to Cassandra when a client is available, otherwise falls back to MongoDB.
graph LR
FE_Tests["client/src/tests/*"] --> FE_Pkg["package.json devDependencies"]
FE_Pkg --> Vitest["@vitejs/plugin-react + vitest"]
FE_Pkg --> RTL["@testing-library/react"]
FE_Pkg --> UserEvent["@testing-library/user-event"]
BE_Routes["server/routes.ts"] --> BE_Storage["server/storage.ts"]
BE_Storage --> BE_Cassandra["server/lib/cassandra.ts"]
Diagram sources
- package.json
- server/routes.ts
- server/storage.ts
- server/lib/cassandra.ts
Section sources
- package.json
- server/routes.ts
- server/storage.ts
- server/lib/cassandra.ts
- UI rendering performance: Prefer lightweight renders in unit tests; avoid unnecessary re-renders by passing minimal props.
- API latency: Mock network requests to eliminate flakiness and speed up tests.
- Database load: Use in-memory stores or test containers for integration tests; avoid hitting production databases.
- Asynchronous operations: Use fake timers to deterministically advance time in tests involving timeouts or polling.
[No sources needed since this section provides general guidance]
Common issues and resolutions:
- Missing environment variables for Cassandra:
- Ensure ASTRA_DB_SECURE_BUNDLE_PATH, ASTRA_DB_APPLICATION_TOKEN, and ASTRA_DB_KEYSPACE are set for database tests.
- Session-based authentication failures:
- Verify session store initialization and that tests set req.session appropriately when simulating authenticated requests.
- CORS or origin mismatches:
- Configure Vite proxy or adjust test environment to match backend origins.
- WebSocket test flakiness:
- Stub WebSocket connections and dispatch synthetic events to validate component behavior.
Section sources
- server/lib/cassandra.ts
- server/routes.ts
PersonalLearningPro currently implements a solid foundation for frontend unit testing with Vitest and React Testing Library, and backend route-level tests leveraging a unified storage abstraction. Extending the strategy involves adding component tests for complex UI flows, expanding backend integration tests with test fixtures, formalizing coverage thresholds, and incorporating performance and end-to-end testing. The existing storage abstraction and Cassandra helpers provide a strong base for database-focused tests.
[No sources needed since this section summarizes without analyzing specific files]
- Unit tests (frontend):
- Focus on pure functions, hooks, and small component units.
- Use mocks for external services and rely on React Testing Library for DOM queries.
- Component tests (frontend):
- Render components with realistic props and contexts.
- Validate user interactions, async flows, and accessibility attributes.
- Integration tests (backend):
- Validate routes with representative payloads and session states.
- Exercise storage layer operations and cross-database fallbacks.
- End-to-end tests (recommended):
- Use Playwright or Cypress to automate browser workflows across registration, login, messaging, and test creation.
[No sources needed since this section provides general guidance]
- Target: Maintain at least 80% statement and branch coverage for critical modules (routes, storage, core hooks).
- Thresholds: Configure Vitest coverage thresholds to fail builds below targets.
- Reporting: Integrate coverage reports into CI artifacts.
[No sources needed since this section provides general guidance]
- Workflows:
- Run unit and integration tests on pull requests.
- Execute database connectivity checks using the provided script.
- Publish coverage reports and enforce minimum thresholds.
- Secrets:
- Store database credentials and third-party API keys as encrypted secrets.
[No sources needed since this section provides general guidance]
- Pre-commit: Lint and run fast unit tests.
- CI: Full matrix of unit, integration, and database tests; optionally run E2E tests.
- Canary: Nightly runs against staging environments.
[No sources needed since this section provides general guidance]