Running now
Native browser suite
The import map above resolves local ES modules and basic.js executes directly—without a bundle or transform.
Current run
Running example tests…
Waiting for the suite result.
- 1 + 2 equals 3
- The result is a number
- Invalid boolean input throws TypeError
Basic assertions
This is the complete module running at the top of this page. Its small run() helper guarantees that each test is decided and closed.
// basic.js
import VanillaTest from 'vanilla-test';
const test = new VanillaTest();
function run(description, assertion) {
test.expects(description);
try {
assertion();
test.pass();
} catch (error) {
console.error(error);
test.fail();
}
test.done();
}
run('1 + 2 equals 3', () => test.compare(1 + 2, 3));
run('the result is a number', () => test.is.number(1 + 2));
run('invalid boolean input throws TypeError', () => {
try {
test.is.boolean([]);
} catch (error) {
test.is.typeError(error);
return;
}
throw new Error('Expected a TypeError');
});
const result = test.report();
const status = document.querySelector('[data-status]');
const details = document.querySelector('[data-details]');
status.textContent = result.ok ? 'All example tests passed' : 'Example tests failed';
status.dataset.ok = String(result.ok);
details.textContent = `${result.total} tests · ${result.passed.length} passed · ${result.failureCount} failed`;The page summary comes from the frozen result object. DevTools contains the detailed runtime output.
Async assertion
Await application work inside the active test. The lifecycle remains explicit before and after the promise settles.
// async.js
import VanillaTest from 'vanilla-test';
async function loadUser() {
return Promise.resolve({ id: 7, name: 'Ada' });
}
const test = new VanillaTest();
test.expects('loadUser resolves a valid user');
try {
const user = await loadUser();
test.is.object(user);
test.is.number(user.id);
test.compare(user.name, 'Ada');
test.pass();
} catch (error) {
console.error(error);
test.fail();
}
test.done();
const result = test.report();
console.log({ ok: result.ok, total: result.total });The final report is created only after the promise resolves and the active test calls done().
Intentional failure
This complete Node module shows the failure path and intentionally exits with status 1.
// intentional-failure.js
import VanillaTest from 'vanilla-test';
const test = new VanillaTest();
test.expects('the API returns HTTP 200');
try {
const response = { status: 503 };
test.compare(response.status, 200);
test.pass();
} catch (error) {
console.error('Expected failure:', error);
test.fail();
}
test.done();
const result = test.report();
console.log({ ok: result.ok, failures: result.failureCount });
process.exitCode = result.ok ? 0 : 1;You should see the comparison error, one failed test, and { ok: false, failures: 1 }. In Node.js this console is the terminal.
node ./intentional-failure.jsAn exit status of 1 is expected for this deliberate failure.
Type checks
The is helpers throw on mismatch while strict mode is enabled. Catch the error and fail the active test.
// types.js
import VanillaTest from 'vanilla-test';
const test = new VanillaTest();
const payload = {
tags: ['docs', 'esm'],
publish: () => true
};
test.expects('payload has the required shapes');
try {
test.is.object(payload);
test.is.array(payload.tags);
test.is.function(payload.publish);
test.is.string(payload.tags[0]);
test.pass();
} catch (error) {
console.error(error);
test.fail();
}
test.done();
const result = test.report();
process.exitCode = result.ok ? 0 : 1;The example passes. Change payload.tags to a string to inspect a strict type mismatch and failed result.
node ./types.jsThe terminal shows the expectation, decision, and final report.
CLI and npm commands
Run both collectors, one collector, or supply a machine-specific Chrome path without changing committed configuration.
npx vanilla-test coverage all
npx vanilla-test coverage node
npx vanilla-test coverage chrome
npx vanilla-test coverage chrome --chrome-path "/opt/google/chrome/google-chrome"The suite report and collector errors appear there. Use the exit status for automation and open the configured report directory for coverage details.
The repository's npm scripts provide shorter commands for common work:
npm test
npm run test:core
npm run test:tooling
npm run coverage
npm run coverage:node
npm run coverage:chrome
npm startnpm start prints the documentation URL. Test and coverage scripts print results and exit nonzero when a required gate fails.
Append CLI options to an npm script after --:
npm run coverage -- --timeout-ms 60000
npm run coverage:chrome -- --headed
npm run coverage:chrome -- --chrome-path "C:\Program Files\Google\Chrome\Application\chrome.exe"Confirm the suite result and final exit status, then inspect the configured report directory for the runtime's coverage files.