Vitest Testing
What we are testing
Snappycart is a reusable cart library. Vitest gives us the cheapest and fastest confidence for internal cart logic and the public React contract before browser-level tests run.
This page covers two Vitest layers:
- reducer unit tests
- provider and hook integration tests
It does not replace browser-level component coverage, and it does not replace demo-level end-to-end coverage.
For the full inventory and recommended test counts across all layers, read the Cart testing plan.
Scope of Vitest Testing
Vitest is the right place for:
- reducer-only cart logic
- quantity normalisation rules
- derived values such as total item count and subtotal
CartProviderstate updatesuseCartcontract behaviour- guard behaviour when hooks are used outside the provider
Vitest is not the main place for:
- browser rendering behaviour
- focus management
- overlay clicks
- keyboard interaction in the DOM
- visual component transitions
Those belong in Cypress/Playwright Component Testing or browser-level end-to-end testing.
Where Vitest tests live
Vitest tests should live close to the source they validate.
Use files such as:
packages/snappycart/src/cart/context/cartReducer.test.ts
packages/snappycart/src/cart/context/CartProvider.test.tsx
Test ID contract
We use VT-* as the stable test ID contract for Vitest coverage.
Examples:
VT-01VT-02VT-16
This keeps Vitest coverage separate from Cypress Component Testing IDs such as CT-01.
Unit test harness guidance
Reducer tests should stay focused on pure business logic.
Recommended fixture style:
const apple = {
id: 'apple',
name: 'Apple',
price: 1.5,
image: '/apple.png',
};
Use stable, explicit fixtures and assert one main behaviour per test.
Vitest unit coverage matrix
Use this table to decide what belongs in reducer unit tests.
| ID | Area | Level | Framework | What is covered | What to assert in Vitest |
|---|---|---|---|---|---|
| VT-01 | Cart reducer | Unit | Vitest | add new item | New line is inserted with the expected quantity and values |
| VT-02 | Cart reducer | Unit | Vitest | add existing item and merge quantity | Duplicate add increases quantity instead of creating a second line |
| VT-03 | Cart reducer | Unit | Vitest | add item with invalid quantity and normalise it | Invalid quantity is converted to a safe stored value |
| VT-04 | Cart reducer | Unit | Vitest | add item with decimal quantity and floor it | Decimal quantity is normalised before storage |
| VT-05 | Cart reducer | Unit | Vitest | remove item | Matching line is removed from the reducer state |
| VT-06 | Cart reducer | Unit | Vitest | increment item | Quantity increases by one |
| VT-07 | Cart reducer | Unit | Vitest | decrement item above one | Quantity decreases without removing the line |
| VT-08 | Cart reducer | Unit | Vitest | decrement item from one and remove the line | Item disappears when quantity reaches the removal boundary |
| VT-09 | Cart reducer | Unit | Vitest | set positive quantity | Quantity updates directly to the requested value |
| VT-10 | Cart reducer | Unit | Vitest | set decimal quantity and floor it | Decimal quantity is normalised before storage |
| VT-11 | Cart reducer | Unit | Vitest | set quantity to zero and remove the line | Zero quantity removes the line from state |
| VT-12 | Cart reducer | Unit | Vitest | set negative quantity and remove the line | Invalid negative quantity does not remain in state |
| VT-13 | Cart reducer | Unit | Vitest | clear cart | State resets to an empty cart |
| VT-14 | Cart reducer | Unit | Vitest | calculate total items | Derived total item count is correct |
| VT-15 | Cart reducer | Unit | Vitest | calculate subtotal | Derived subtotal is correct |
Vitest integration coverage matrix
Use this table to decide what belongs in provider and hook integration tests.
| ID | Area | Level | Framework | What is covered | What to assert in Vitest |
|---|---|---|---|---|---|
| VT-16 | Cart provider and hook contract | Integration | Vitest | throws outside provider | useCart fails when used without CartProvider |
| VT-17 | Cart provider and hook contract | Integration | Vitest | exposes empty initial state | Empty cart contract is available on first render |
| VT-18 | Cart provider and hook contract | Integration | Vitest | add item updates items, totalItems, and subtotal | Public cart state updates correctly through hook usage |
| VT-19 | Cart provider and hook contract | Integration | Vitest | remove item updates derived values | Removing a line updates totals correctly |
| VT-20 | Cart provider and hook contract | Integration | Vitest | increment and decrement update derived values | Quantity changes keep derived state in sync |
| VT-21 | Cart provider and hook contract | Integration | Vitest | clear resets state | Public cart state returns to empty after clear |
| VT-22 | Cart provider and hook contract | Integration | Vitest | add item with explicit quantity | Extra scenario: Additional integration coverage kept outside the canonical VT-* baseline |
The canonical Vitest baseline currently maps to VT-01 through VT-21.
The current suite contain additional Vitest scenarios beyond that baseline when they provide useful extra confidence. Those rows should be marked as extra coverage with a new canonical VT-* ID.
How to use these matrices
When adding or reviewing a Vitest test:
- identify whether the behaviour belongs to reducer logic or the provider and hook contract
- map the test to one
VT-*entry - keep one meaningful behaviour per test
- prefer public behaviour over implementation details
Every new Vitest contribution should map to at least one row in the matrices above.
Coverage guidance for contributors
Prioritise these rows first:
- add new item
- merge quantity for existing item
- decrement to removal
- clear cart
- total item calculation
- subtotal calculation
- hook guard outside provider
- empty initial provider state
- add item through provider
- remove item through provider
Avoid spreading the same behaviour across reducer tests and provider tests unless the duplication is intentional and valuable.
Related pages