Testing Guide
Coherent.js components are plain JavaScript objects rendered to strings, which makes them unusually easy to test: call the component function, render it, and assert on the HTML.
Setup
Install Vitest (projects scaffolded with
coherent create already include it):
pnpm add -D vitestAdd a test script to package.json:
{
"scripts": {
"test": "vitest run"
}
}No special configuration is needed — the published packages resolve out of the box under Vitest's default settings.
Testing with render
The simplest tests use render from @coherent.js/core directly:
import { describe, it, expect } from 'vitest';
import { render } from '@coherent.js/core';
import { HomePage } from '../src/components/HomePage.js';
describe('HomePage', () => {
it('renders the title', () => {
const html = render(HomePage({ title: 'Hello' }));
expect(html).toContain('Hello');
});
it('escapes user content', () => {
const html = render({ div: { text: '<script>alert(1)</script>' } });
expect(html).not.toContain('<script>alert(1)</script>');
});
});Testing with @coherent.js/tooling/testing
The tooling package ships a richer test harness. renderComponent returns a
result object with the rendered HTML plus query helpers:
import { describe, it, expect } from 'vitest';
import { renderComponent } from '@coherent.js/tooling/testing';
import { HomePage } from '../src/components/HomePage.js';
describe('HomePage', () => {
it('renders without errors', () => {
const { html } = renderComponent(HomePage({}));
expect(html).toBeTypeOf('string');
expect(html).toContain('Welcome');
});
});Reusable smoke tests
A pattern that scales well — one helper asserting any component renders:
import { describe, it, expect } from 'vitest';
import { renderComponent } from '@coherent.js/tooling/testing';
export function testComponent(Component, props = {}) {
describe(Component.name || 'Component', () => {
it('renders without errors', () => {
const { html } = renderComponent(Component(props));
expect(html).toBeTypeOf('string');
expect(html.length).toBeGreaterThan(0);
});
});
}What to test
- Output, not structure: assert on the rendered HTML string, not the component object shape — refactors then don't break tests.
- Props drive branches: render once per interesting prop combination.
- Escaping: if you interpolate user data, assert it arrives escaped.