Testing - FactoriaF5-Asturias/project-p5-digital-academy-team1-restaurant-frontend GitHub Wiki
Testing
Tools
- Vitest — test runner integrated with Vite (
globals: true,jsdomenvironment, configured invite.config.js). - Vue Test Utils — mounting components and simulating user interaction.
- jsdom — browser environment simulation.
- @vitest/coverage-v8 — coverage reports (
textin the terminal +htmlincoverage/).
Running the tests
npm run test # run the whole suite once
npm run test:watch # watch mode while developing
npm run test:coverage # coverage report (terminal + coverage/index.html)
Coverage threshold
The project requires a minimum of 70% in lines, functions, branches and statements. The threshold is configured in vite.config.js, so npm run test:coverage fails if any metric drops below it:
coverage: {
provider: 'v8',
reporter: ['text', 'html'],
thresholds: { lines: 70, functions: 70, branches: 70, statements: 70 },
},
Coverage measurement was set up at the beginning of Sprint 1, so every story was delivered with its own tests.
| Statements | Branches | Functions | Lines |
|---|---|---|---|
| 92.18% | 89.08% | 88.52% | 92.78% |
Continuous Integration
.github/workflows/tests.yml runs on every Pull Request to dev or main:
- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'npm'
- run: npm ci
- run: npm run test:coverage
A Pull Request that breaks a test or lowers coverage below 70% is marked as failed.
What we test
| Layer | What is tested | Example |
|---|---|---|
| Stores | Actions, getters and business rules | Removing a line when quantity reaches 0; VAT and discount totals |
| Services | URL, method and payload sent; response mapping | POST /orders payload with mapped enums |
api.js |
Interceptors | Refresh on 401, queued requests, 403 handler |
| Router | Access rules and redirects | Guest → Login; wrong role → Acceso denegado |
| Composables | Loading, success and error states | useProducts sets error when the request fails |
| Constants & utils | Mappings, formatting and validation | getBackendPaymentMethod('cashier') → CASH_ONSITE |
| Components | Rendering, interaction, accessibility, responsive | "Confirm" disabled without payment method; role="status" message |
| Views | Composition and conditional rendering by session | Order history only visible when logged in |
Services are mocked with vi.mock / vi.spyOn in component tests, so tests never depend on the real backend.
Conventions and lessons learned
- Test next to the file:
Component.vue→Component.test.js. - Isolate
localStorage: calllocalStorage.clear()inbeforeEachin any test that uses persisted stores — jsdom keeps it between tests of the same file. - Fresh Pinia per test:
setActivePinia(createPinia())inbeforeEach, and get store instances after mounting the component, so spies apply to the same instance the component uses. - Wait for re-renders:
await flushPromises()/await nextTick()after changing state, before asserting on the DOM. - Timers:
vi.useFakeTimers()andvi.advanceTimersByTimeAsync()for delayed behavior (navigation after confirming, polling every 10 s). - Only real libraries: check
package.jsonbefore importing a testing helper. - Descriptive names in English:
describeper component/module anditdescribing the expected behavior.