Skip to content

Test Coverage (/test-coverage)

In plain terms

Runs the test suite and shows where test coverage is thin, then helps improve it — for both front-end and back-end.

What this skill does

Runs the frontend and backend test suites, reviews coverage, and helps add tests for under-covered code. Use when the user asks to add tests, check or improve coverage, write unit tests, or test an endpoint.

[!TIP] Use this to check the current test state, run the full suite, and identify gaps.

[!NOTE] This single skill adapts to the backend stack. Detect it first: Python/FastAPI if backend/pyproject.toml or backend/requirements.txt exists (tests via pytest); Node/Express if backend/package.json exists (tests via Jest + Supertest). Run only the branch that matches. The frontend uses Vitest + React Testing Library in both cases.

Trigger Conditions

  • Keywords: "Add tests", "Check coverage", "Write unit tests", "Test this endpoint", "Coverage report"

1. Current Test Stack

Python / FastAPI backend:

Layer Framework Location
Backend — all tests pytest backend/tests/
Frontend Vitest + React Testing Library frontend/src/tests/

Node / Express backend:

Layer Framework Location
Backend — all tests Jest + Supertest backend/tests/
Backend — smoke only Jest + Supertest backend/tests/smoke/
Backend — latency Jest + Supertest backend/tests/performance/
Frontend Vitest + React Testing Library tests/

2. Run Tests

Python / FastAPI backend:

cd backend && pytest --tb=short -q                                 # all tests
cd backend && pytest --cov=app --cov-report=term-missing --tb=short -q   # with coverage
cd backend && python -m mypy app/                                  # type check

Node / Express backend:

cd backend && npm run test           # all tests
cd backend && npm run test:smoke     # smoke only (fast; runs on pre-commit via husky)
cd backend && npm run test:latency   # latency (flags endpoints > 500ms)
cd backend && npm run type-check     # type check

Frontend (both stacks) — run from the frontend directory (frontend/ in a split repo, else root):

npm run test -- --run             # all tests
npm run test -- --run --coverage  # with coverage report
npm run type-check                # (or `npm run check`)

3. Backend Test Patterns

Python / FastAPI (pytest) — tests in backend/tests/:

import pytest
from httpx import AsyncClient

@pytest.mark.asyncio
async def test_get_resource_success(client: AsyncClient, auth_headers: dict):
    response = await client.get("/api/[resource]", headers=auth_headers)
    assert response.status_code == 200

@pytest.mark.asyncio
async def test_get_resource_unauthorized(client: AsyncClient):
    response = await client.get("/api/[resource]")
    assert response.status_code == 401

Node / Express (Jest + Supertest) — tests in backend/tests/:

import request from 'supertest';
import { app } from '../../src/server.js';

describe('GET /api/[resource]', () => {
    it('returns 200 with valid auth', async () => {
        const res = await request(app).get('/api/[resource]')
            .set('Authorization', `Bearer ${testToken}`);
        expect(res.status).toBe(200);
    });
    it('returns 401 without auth', async () => {
        const res = await request(app).get('/api/[resource]');
        expect(res.status).toBe(401);
    });
});

For each new route, test: success path (200/201 with valid data + auth); auth rejection (401); validation error (422 for FastAPI/Pydantic, 400 for Express/Zod); not found (404).

4. Frontend Test Patterns (Vitest)

Tests live in frontend/src/tests/ (split repo) or tests/ (root). Mock the data layer the project uses — apiRequest from lib/queryClient, or the default export of services/apiClient:

import { renderHook } from '@testing-library/react';
import { useResource } from '../../hooks/useResource';

vi.mock('../../lib/queryClient', () => ({ apiRequest: vi.fn().mockResolvedValue(mockData) }));

describe('useResource', () => {
    it('returns data on success', async () => {
        const { result } = renderHook(() => useResource(), { wrapper: QueryClientWrapper });
        await waitFor(() => expect(result.current.isLoading).toBe(false));
        expect(result.current.data).toHaveLength(2);
    });
});

5. Coverage Review

  • [ ] Backend coverage:
  • FastAPI: cd backend && pytest --cov=app --cov-report=html → open backend/htmlcov/index.html
  • Express: covered by npm run test:coverage (frontend) / Jest coverage
  • [ ] Frontend: npm run test -- --run --coverage (or npm run test:coverage) → open coverage/index.html
  • [ ] Identify files/routes with 0% or < 50% coverage
  • [ ] Prioritize: auth flows (login, token validation, RBAC); mutation handlers (create/update/delete); input validation (Pydantic for FastAPI, Zod for Express); critical business logic.

6. Latency Review

  • Any endpoint averaging > 500 ms is a regression risk.
  • Investigate N+1 query patterns — SQLModel queries (FastAPI) or Drizzle queries (Express).
  • Check caching is working (e.g. the Express authenticate cache, 60s TTL).
  • Express projects can measure directly: cd backend && npm run test:latency.

7. Interpret Results

  • Failing backend test: read the traceback, fix the code (not the test, unless the test is wrong).
  • Failing frontend test: decide if it's a real regression or a stale mock — fix the source, not the assertion.
  • Low coverage on new code: add targeted tests for the uncovered branches before shipping.

8. Report

Summarize: total tests run / passed / failed; coverage % for backend and frontend (if measured); any areas flagged as under-covered.