This document describes the testing infrastructure and how to run tests for the Curio application.
Curio includes comprehensive test suites for both backend (Python/FastAPI) and frontend (TypeScript/React):
- Backend: pytest-based unit and integration tests
- Frontend: Vitest and React Testing Library tests
- Coverage: Both suites include code coverage reporting
The backend uses pytest with the following dependencies:
pytest- Test frameworkpytest-asyncio- Async test supportpytest-cov- Coverage reportingpytest-mock- Mocking utilitieshttpx- HTTP client for testingfaker- Test data generation
backend/tests/
├── conftest.py # Test fixtures and configuration
├── test_auth.py # Authentication tests
├── test_llm_processor.py # LLM service tests
├── test_rss_fetcher.py # RSS fetcher tests
├── test_api_articles.py # Articles API tests
├── test_api_endpoints.py # Other API endpoint tests
└── test_integration.py # End-to-end integration tests
# Run all tests
cd backend
pytest
# Run with coverage
pytest --cov=app --cov-report=html
# Run specific test file
pytest tests/test_auth.py
# Run specific test
pytest tests/test_auth.py::TestAuthentication::test_create_access_token
# Run only unit tests
pytest -m unit
# Run only integration tests
pytest -m integration
# Run with verbose output
pytest -v
# Run and show print statements
pytest -sKey fixtures available in conftest.py:
db_session- SQLAlchemy database session (in-memory SQLite)client- FastAPI TestClientauthenticated_client- Authenticated TestClient with auth cookietest_user- Sample User objecttest_category- Sample Category objecttest_feed- Sample Feed objecttest_article- Sample Article objectmultiple_articles- List of sample articles
After running tests with coverage, view the HTML report:
cd backend
pytest --cov=app --cov-report=html
open htmlcov/index.htmlThe frontend uses Vitest with React Testing Library:
vitest- Test framework (Vite-native)@testing-library/react- React component testing@testing-library/jest-dom- DOM matchers@testing-library/user-event- User interaction simulationmsw- API mocking
frontend/src/
├── test/
│ ├── setup.ts # Test environment setup
│ ├── mockData.ts # Mock data for tests
│ └── handlers.ts # MSW API handlers
└── __tests__/
├── hooks/
│ ├── useArticleActions.test.tsx
│ └── useArticleFilters.test.tsx
└── utils/
└── api.test.ts
# Run all tests
cd frontend
npm test
# Run with UI
npm run test:ui
# Run with coverage
npm run test:coverage
# Run in watch mode (during development)
npm test -- --watch
# Run specific test file
npm test useArticleActions.test.tsxExample component test:
import { describe, it, expect } from "vitest";
import { render, screen } from "@testing-library/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import MyComponent from "./MyComponent";
describe("MyComponent", () => {
it("renders correctly", () => {
const queryClient = new QueryClient();
render(
<QueryClientProvider client={queryClient}>
<MyComponent />
</QueryClientProvider>
);
expect(screen.getByText("Hello")).toBeInTheDocument();
});
});The backend includes integration tests that cover complete workflows:
- Article Workflow: Feed fetch → LLM processing → Reading
- Newspaper Generation: Processed articles → Newspaper
- Duplicate Detection: Similar articles → Deduplication
- User Isolation: Multi-user data separation
Run integration tests specifically:
cd backend
pytest -m integrationTests run automatically on:
- Push to
mainordevelopbranches - Pull requests to
mainordevelop - Manual workflow dispatch
The CI pipeline:
- Sets up Python and Node.js environments
- Installs dependencies
- Runs backend tests with PostgreSQL
- Runs frontend tests
- Uploads coverage reports to Codecov
- Runs linting checks
Run tests like CI does:
# Backend
cd backend
pytest --cov=app --cov-report=xml
# Frontend
cd frontend
npm test -- --run --coverageUse the Makefile for common test tasks:
# Run all tests
make test
# Run backend tests only
make test-backend
# Run frontend tests only
make test-frontend
# Run with coverage
make test-coverage
# Clean test artifacts
make clean-test- Use fixtures for common setup
- Mock external services (OpenAI, HTTP requests)
- Use in-memory database for speed
- Test both success and error cases
- Mark tests as
unitorintegration
- Use React Testing Library's user-centric queries
- Mock API calls with MSW
- Test user interactions, not implementation details
- Use
waitForfor async operations - Keep tests isolated and independent
- Write descriptive test names
- One assertion per test when possible
- Keep tests fast
- Maintain test data fixtures
- Update tests when changing code
Database connection errors:
# Make sure PostgreSQL is running (for integration tests)
docker-compose up -d postgres
# Or use SQLite (default for unit tests)
pytest # Uses in-memory SQLite by defaultImport errors:
# Install test dependencies
cd backend
pip install -r requirements.txtModule not found:
# Install dependencies
cd frontend
npm installTimeout errors:
# Increase timeout in vitest.config.ts
test: {
testTimeout: 10000
}- Backend: Aim for 80%+ coverage
- Frontend: Aim for 70%+ coverage
- Critical paths: 90%+ coverage (auth, data processing)
View current coverage:
# Backend
cd backend
pytest --cov=app --cov-report=term-missing
# Frontend
cd frontend
npm run test:coverage