Testing Guide¶
This guide covers testing strategies, IDE setup, and debugging for the Freeze Design webshop.
Test Pyramid¶
┌───────────┐
│ E2E │ ← Few, slow, high confidence
├───────────┤
│Integration│ ← Medium number
├───────────┤
│ Unit │ ← Many, fast, focused
└───────────┘
Backend Testing (Django)¶
Run Tests¶
cd backend
python manage.py test
# Run specific app tests
python manage.py test apps.payments
python manage.py test apps.invoices
python manage.py test apps.orders
# Run specific test modules
python manage.py test apps.payments.tests.test_webhook
python manage.py test apps.payments.tests.test_refund_service
python manage.py test apps.invoices.tests.test_invoice_service
# Run with verbosity
python manage.py test --verbosity=2
With Coverage¶
Test Structure¶
# tests/test_products.py
from django.test import TestCase
from rest_framework.test import APITestCase
class ProductAPITests(APITestCase):
def setUp(self):
self.product = Product.objects.create(
name='Test Product',
base_price=29.95
)
def test_list_products(self):
response = self.client.get('/api/products/')
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data['results']), 1)
def test_product_detail(self):
response = self.client.get(f'/api/products/{self.product.slug}/')
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['name'], 'Test Product')
Frontend Testing¶
Unit Tests (Jest)¶
cd frontend
npm run test
npm run test:coverage
npm run test:watch # Watch mode (auto-rerun)
npm test TeamOrderContext # Specific test file
Test Structure¶
// Component.test.tsx
import { render, screen, fireEvent } from '@testing-library/react';
import { QuantitySelector } from './QuantitySelector';
describe('QuantitySelector', () => {
it('increments quantity when plus clicked', () => {
const onChange = jest.fn();
render(<QuantitySelector quantity={1} onQuantityChange={onChange} />);
fireEvent.click(screen.getByLabelText('Verhoog aantal'));
expect(onChange).toHaveBeenCalledWith(2);
});
it('disables decrement at minimum', () => {
render(<QuantitySelector quantity={1} onQuantityChange={() => {}} min={1} />);
expect(screen.getByLabelText('Verlaag aantal')).toBeDisabled();
});
});
Running Specific Tests¶
# Single test file
npm test TeamOrderContext.test.tsx
# Single test case
npm test -- -t "should save team order to context"
# All tests matching pattern
npm test -- --testPathPattern=contexts
E2E Testing (Playwright)¶
Run Tests¶
cd frontend
npm run test:e2e # All E2E tests (headless)
npm run test:e2e:headed # See browser while testing
npm run test:e2e:ui # Interactive Playwright UI
Running Specific E2E Tests¶
# Single test file
npx playwright test team-order-designer-flow.spec.ts
# Single test case
npx playwright test -g "should preserve team order"
# By tag
npx playwright test --grep="@smoke"
npx playwright test --grep="@regression"
# Specific browser
npx playwright test --project=chromium
npx playwright test --project=firefox
npx playwright test --project=webkit
Test Structure¶
// e2e/checkout.spec.ts
import { test, expect } from '@playwright/test';
test.describe('Checkout Flow', () => {
test('complete order', async ({ page }) => {
await page.goto('/products/classic-t-shirt');
await page.click('[data-testid="color-swatch-1"]');
await page.click('[data-testid="size-option-3"]');
await page.click('[data-testid="add-to-cart"]');
await page.click('[data-testid="checkout-button"]');
await page.fill('[name="email"]', 'test@example.com');
await page.click('[data-testid="submit-order"]');
await expect(page.locator('.order-confirmation')).toBeVisible();
});
});
Viewing E2E Results¶
- HTML Report: Auto-opens after test run, or manually:
npx playwright show-report - Trace Viewer: For failed tests:
npx playwright show-trace trace.zip
VS Code Setup¶
Recommended Extensions¶
| Extension | ID | Purpose |
|---|---|---|
| Jest | Orta.vscode-jest |
Inline test results, coverage, run/debug tests |
| Playwright Test | ms-playwright.playwright |
Run/debug E2E tests, record tests, trace viewer |
Install via terminal:
Configure Jest Extension¶
Add to .vscode/settings.json:
VS Code Shortcuts¶
Unit Tests (Jest):
- Hover over test and click play button to run
- Right-click test for "Debug Test"
- Cmd+Shift+P then "Jest: Toggle Coverage"
E2E Tests (Playwright):
- Click play button in gutter next to test
- Right-click for "Debug Test"
- Cmd+Shift+P then "Test: Record New"
Debugging Tests¶
Debug Unit Tests (Jest)¶
Debug E2E Tests (Playwright)¶
CI/CD Integration¶
Tests run automatically on every push via GitHub Actions. See .github/workflows/ci.yml.
Required Checks¶
- Backend tests pass
- Frontend tests pass
- E2E tests pass
- Linting passes
- Type checking passes
- Seed data export/import round-trip
E2E Strategy in CI¶
| Trigger | Tests Run | Browsers |
|---|---|---|
| Pull requests | Smoke tests (@smoke tag only) |
Chromium |
Push to main |
Full E2E suite | All scenarios |
Pre-push Hook¶
A pre-push git hook runs backend and frontend tests before pushing. If tests fail, the push is blocked.
Test File Locations¶
backend/
├── apps/
│ ├── payments/tests/ # Payment tests
│ │ ├── test_models.py # Payment, Refund, AuditLog model tests
│ │ ├── test_services.py # PaymentService unit tests
│ │ ├── test_views.py # API endpoint tests
│ │ ├── test_webhook.py # Mollie webhook handler tests
│ │ ├── test_refund_service.py # Refund creation/validation
│ │ ├── test_refund_webhook.py # Refund webhook processing
│ │ ├── test_retry.py # Payment retry tests
│ │ └── test_audit.py # Audit logging tests
│ ├── invoices/tests/ # Invoice tests
│ │ ├── test_invoice_service.py # Generation, numbering, idempotency
│ │ └── test_invoice_views.py # Download authorization tests
│ └── orders/tests/
│ └── test_refund_admin.py # Admin refund action tests
frontend/
├── __tests__/ # Unit tests
│ ├── contexts/
│ │ └── TeamOrderContext.test.tsx
│ └── README.md
├── e2e/ # E2E tests
│ ├── flows/
│ │ └── customer-journey.spec.ts # Full payment journey
│ ├── team-order-designer-flow.spec.ts
│ ├── anonymous-team-order.spec.ts
│ └── ...
├── coverage/ # Coverage reports (generated)
├── playwright-report/ # E2E reports (generated)
└── test-results/ # E2E artifacts (generated)
Troubleshooting¶
"Cannot find module '@testing-library/react'"¶
"Playwright browsers not installed"¶
Tests timing out¶
Increase timeout in test file:
Port 3000 already in use (E2E tests)¶
Coverage not showing¶
Quick Reference¶
| Task | Command |
|---|---|
| Backend | |
| All backend tests | cd backend && python manage.py test |
| Payment tests | python manage.py test apps.payments |
| Invoice tests | python manage.py test apps.invoices |
| Webhook tests | python manage.py test apps.payments.tests.test_webhook |
| Frontend (Jest) | |
| All unit tests | npm test |
| Watch mode | npm run test:watch |
| With coverage | npm run test:coverage |
| Frontend (Playwright) | |
| All E2E tests | npm run test:e2e |
| Headed mode | npm run test:e2e:headed |
| Interactive UI | npm run test:e2e:ui |
| Debug E2E | npx playwright test --debug |
| Smoke tests only | npx playwright test --grep="@smoke" |
| View report | npx playwright show-report |