Testing - FactoriaF5-Asturias/project-p5-digital-academy-team1-restaurant-frontend GitHub Wiki

Testing

Tools

  • Vitest — test runner integrated with Vite (globals: true, jsdom environment, configured in vite.config.js).
  • Vue Test Utils — mounting components and simulating user interaction.
  • jsdom — browser environment simulation.
  • @vitest/coverage-v8 — coverage reports (text in the terminal + html in coverage/).

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: call localStorage.clear() in beforeEach in any test that uses persisted stores — jsdom keeps it between tests of the same file.
  • Fresh Pinia per test: setActivePinia(createPinia()) in beforeEach, 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() and vi.advanceTimersByTimeAsync() for delayed behavior (navigation after confirming, polling every 10 s).
  • Only real libraries: check package.json before importing a testing helper.
  • Descriptive names in English: describe per component/module and it describing the expected behavior.