Testing

Test Framework

  • Use Vitest for unit and integration tests.
  • Use Playwright for end-to-end tests.
  • Use Testing Library for component testing.

Test Organisation

  • Use describe blocks for test suites.
  • Use descriptive test names that explain what’s being tested.
  • Follow Arrange-Act-Assert pattern.
  • Group related tests together.

Test Naming Convention

  • *.test.ts - Unit tests
  • *.int.spec.ts - Integration tests
  • *.e2e.spec.ts - End-to-end tests

Writing Tests

Example:

 1import { describe, test, expect } from 'vitest'
 2import { ListingParams, SKIP_FILTER } from './ListingParams'
 3
 4describe('ListingParams', () => {
 5	const params: ListingParamArgs = {
 6		manufacturers: [1],
 7		models: [10],
 8		parts: [99],
 9		eras: [2010],
10		searchTerm: 'test-search',
11	}
12
13	test('serialises params to query string', () => {
14		const qs = ListingParams.toSearchParams(params).toString()
15		expect(qs).toContain('manufacturers=1')
16		expect(qs).toContain('models=10')
17	})
18
19	test('parses query string back to params', () => {
20		const qs = 'manufacturers=1&models=10&parts=99'
21		const parsed = ListingParams.fromQueryString(qs)
22		expect(parsed.manufacturers).toEqual([1])
23	})
24
25	test('round-trip with SKIP_FILTER values', () => {
26		const original: ListingParamArgs = {
27			manufacturers: [5],
28			models: [SKIP_FILTER],
29		}
30
31		const qs = ListingParams.toSearchParams(original).toString()
32		const parsed = ListingParams.fromQueryString(qs)
33
34		expect(parsed.manufacturers).toEqual([5])
35		expect(parsed.models).toEqual([SKIP_FILTER])
36	})
37
38	test('handles missing params gracefully', () => {
39		const minimal: ListingParamArgs = { vehicleId: 1 }
40		const qs = ListingParams.toSearchParams(minimal).toString()
41		expect(qs).toContain('vehicle=1')
42		expect(qs).not.toContain('models=')
43	})
44})

Best Practices

  • Test behaviour, not implementation details.
  • Use meaningful test names.
  • Keep tests simple and focused.
  • Avoid test interdependencies.
  • Test edge cases and error conditions.
  • Use round-trip testing for serialisation/deserialisation logic.
Last modified: 27/10/2025 2022-2025 ©ainsley.dev, All rights reserved.