AgentSkillsCN

testing

在产品详情页上进行变体与属性的选择。在修改变体选择器、调试“加入购物车”按钮的状态、理解选项的可用性,或为选项添加折扣徽章时使用。

SKILL.md
--- frontmatter
name: testing
description: Write fast, effective tests with Vitest. Use when adding tests for new features, debugging failing tests, or deciding what to test vs skip.

Testing

Source: Vitest Docs - Test framework documentation

When to Use

Use this skill when:

  • Adding tests for new features
  • Debugging failing tests
  • Deciding what to test vs skip

Framework

This project uses Vitest (not Jest):

bash
pnpm test          # Watch mode (fastest iteration)
pnpm test:run      # Single run (CI)

What to Test

PriorityWhatWhy
🔴 HighPure utility functionsFast, no mocking, high value
🔴 HighState machine logicComplex transitions, edge cases
🟡 MediumData transformationsGraphQL → UI mappings
🟢 LowerReact componentsSlow, requires DOM, often E2E covers
⚫ SkipThird-party integrationsMock at boundary instead

Developer Habits That Keep Tests Fast

PracticeWhy
Test pure functions, not componentsNo React rendering overhead
Mock network/timers at boundariesNo waiting for I/O
Small focused fixturesLess memory allocation
One assertion per conceptFaster failure diagnosis
describe.skip for slow suitesSkip during rapid iteration
Run filtered tests while codingpnpm test -- functionName

File Structure

code
src/ui/components/pdp/variant-selection/
├── utils.ts                    # Pure functions
├── utils.test.ts               # Tests next to source
└── __fixtures__/
    └── variants.ts             # Shared test data

Fixture Guidelines

typescript
// ✅ Good: Minimal, focused fixtures
export const tshirtVariants: SaleorVariant[] = [
  { id: "black-s", name: "Black / S", quantityAvailable: 10, ... },
  { id: "black-m", name: "Black / M", quantityAvailable: 10, ... },
];

// ❌ Bad: Copy-pasted production data (100+ variants)
export const allProducts = require("./huge-dump.json");

Speed Commands

bash
# During development (fastest)
pnpm test -- utils.test.ts           # Single file
pnpm test -- findMatchingVariant     # Pattern match
pnpm test -- -t "sparse"             # Test name filter
pnpm test -- --changed               # Only git-changed files

# CI
pnpm test:run                        # Full suite, single run

Test Patterns

Testing State Transitions

typescript
describe("getAdjustedSelections", () => {
	it("clears conflicting selections when variant doesn't exist", () => {
		// State: Blue/L selected
		const current = { color: "blue", size: "l" };

		// Action: Switch to Red (which only has S)
		const result = getAdjustedSelections(variants, current, "color", "red");

		// Result: Size cleared (Red/L doesn't exist)
		expect(result).toEqual({ color: "red" });
	});
});

Testing Edge Cases

typescript
describe("edge cases", () => {
	it("handles $0 price correctly (not treated as falsy)", () => {
		// 0 is falsy in JS - explicit typeof check needed
		const freeVariant = { pricing: { price: { gross: { amount: 0 } } } };
		expect(variantHasDiscount(freeVariant)).toBe(true);
	});

	it("handles null/undefined gracefully", () => {
		const result = findMatchingVariant([], {});
		expect(result).toBeUndefined();
	});
});

Vitest Config

typescript
// vitest.config.ts
export default defineConfig({
	test: {
		globals: true,
		environment: "node", // Fastest, no DOM
		include: ["src/**/*.test.ts"],
		testTimeout: 5000, // Fail fast on hangs
	},
	resolve: {
		alias: { "@": path.resolve(__dirname, "./src") },
	},
});

Anti-patterns

Don't test implementation details - Test behavior, not internal structure
Don't use sleep() or real timers - Use vi.useFakeTimers()
Don't test third-party code - Trust libraries, mock at boundaries
Don't write slow component tests - Prefer E2E for UI flows
Don't copy production data as fixtures - Create minimal focused data