Design Token Testing
Design Token Testing
Design token testing ensures tokens function correctly across the system, maintaining reliability as tokens evolve. Testing catches issues like invalid values, broken references, accessibility failures, and visual regressions before they reach production. Comprehensive token testing builds confidence in the token system’s integrity.
What Is Design Token Testing
Design token testing encompasses various verification methods applied to design tokens and their outputs. This includes structural validation of token definitions, functional testing of transformed outputs, visual testing of token application, and accessibility verification of token combinations.
Testing operates at multiple levels: token files themselves, generated platform outputs, and applications consuming tokens.
How Design Token Testing Works
Unit testing validates individual tokens:
describe('Color tokens', () => {
test('primary color is valid hex', () => {
expect(tokens.color.primary).toMatch(/^#[A-Fa-f0-9]{6}$/);
});
test('text color contrasts with background', () => {
const contrast = getContrastRatio(
tokens.color.text.primary,
tokens.color.background.default
);
expect(contrast).toBeGreaterThanOrEqual(4.5);
});
});
Reference testing verifies alias resolution:
describe('Token references', () => {
test('all references resolve', () => {
const unresolved = findUnresolvedReferences(tokens);
expect(unresolved).toHaveLength(0);
});
test('no circular references exist', () => {
const circular = findCircularReferences(tokens);
expect(circular).toHaveLength(0);
});
});
Output testing validates generated files:
describe('CSS output', () => {
test('CSS is syntactically valid', () => {
const css = fs.readFileSync('dist/tokens.css', 'utf8');
expect(() => postcss.parse(css)).not.toThrow();
});
test('all tokens present in output', () => {
const css = fs.readFileSync('dist/tokens.css', 'utf8');
expect(css).toContain('--color-primary');
expect(css).toContain('--spacing-md');
});
});
Visual regression testing captures token application:
// Using Storybook + Chromatic or Percy
export const TokenShowcase = () => (
<div>
<ColorSwatches tokens={colorTokens} />
<TypographySpecimen tokens={typographyTokens} />
<SpacingDemonstration tokens={spacingTokens} />
</div>
);
Key Considerations
- Test coverage should match token criticality
- Automated tests run in CI pipelines
- Visual tests catch issues that unit tests miss
- Accessibility tests should be mandatory for color pairs
- Performance testing validates build times at scale
- Cross-platform output testing ensures consistency
- Test maintenance is part of token maintenance
- Snapshot tests aid regression detection
Common Questions
What testing tools work for tokens?
Structural validation:
- JSON Schema for token file validation
- Custom scripts for naming convention checks
- ajv or similar for schema validation in Node
Unit testing:
- Jest, Vitest, or Mocha for JavaScript tests
- Custom matchers for token-specific assertions
Visual regression:
- Chromatic with Storybook
- Percy for visual snapshots
- BackstopJS for visual comparison
Accessibility:
- axe-core for automated accessibility checks
- Color contrast calculators in test assertions
- Pa11y for page-level accessibility
Integration:
- Cypress or Playwright for application-level testing
- Build process integration tests
How should accessibility be tested?
Accessibility testing for tokens focuses on color combinations.
Contrast ratio validation:
function validateContrast(textToken, bgToken, level = 'AA') {
const ratio = getContrastRatio(textToken, bgToken);
const required = level === 'AAA' ? 7 : 4.5;
return ratio >= required;
}
test('primary text on primary background meets AA', () => {
expect(
validateContrast(
tokens.color.text.primary,
tokens.color.background.primary
)
).toBe(true);
});
Automated pair testing:
const colorPairs = [
{ text: 'color.text.primary', bg: 'color.background.default' },
{ text: 'color.text.secondary', bg: 'color.background.default' },
{ text: 'color.text.onPrimary', bg: 'color.background.primary' },
// ... all intended pairs
];
colorPairs.forEach(({ text, bg }) => {
test(`${text} on ${bg} meets contrast`, () => {
expect(validateContrast(getToken(text), getToken(bg))).toBe(true);
});
});
Theme-specific testing: Each theme variant needs separate accessibility validation. Dark mode text/background pairs may have different contrast characteristics.
How should visual regression tests be structured?
Visual regression captures how tokens appear when applied.
Token showcase pages:
// Dedicated test page showing all tokens
export const AllColors = () => (
<ColorGrid>
{Object.entries(colorTokens).map(([name, value]) => (
<ColorSwatch key={name} name={name} value={value} />
))}
</ColorGrid>
);
Component variations:
// Components in various token-affected states
export const ButtonStates = () => (
<>
<Button>Default</Button>
<Button disabled>Disabled</Button>
<Button variant="primary">Primary</Button>
<Button variant="destructive">Destructive</Button>
</>
);
Theme comparisons:
export const ThemeComparison = () => (
<SplitView>
<ThemeProvider theme="light">
<ComponentShowcase />
</ThemeProvider>
<ThemeProvider theme="dark">
<ComponentShowcase />
</ThemeProvider>
</SplitView>
);
Baseline screenshots establish expected appearance. Changes produce diffs for review.
Summary
Design token testing validates token correctness through unit tests for individual values, reference tests for alias resolution, output tests for generated files, visual regression tests for application appearance, and accessibility tests for color compliance. Testing tools span structural validators, JavaScript test frameworks, visual regression platforms, and accessibility checkers. Comprehensive testing builds confidence in token system reliability.
Buoy scans your codebase for design system inconsistencies before they ship
Detect Design Drift Free