unit-testing
Write unit tests for JavaScript files using Node.js native test runner. Use when creating new scripts, fixing bugs, or when prompted about missing tests.
When & Why to Use This Skill
This Claude skill automates the creation and maintenance of unit tests for JavaScript files using the native Node.js test runner. It streamlines the development lifecycle by ensuring every new script, bug fix, or refactoring effort is accompanied by robust validation logic, including happy paths, error handling, and edge case coverage without requiring external dependencies.
Use Cases
- Automated Test Generation: Automatically create comprehensive test suites for new JavaScript scripts in the .claude/scripts/ directory to ensure immediate reliability.
- Bug Regression Testing: Generate specific test cases to reproduce reported bugs and verify that fixes work as intended before deployment.
- CLI Tool Validation: Test command-line interfaces by simulating execution with various flags and arguments, asserting expected output patterns and exit codes.
- Refactoring Assurance: Verify existing functionality remains intact during code cleanups or architectural changes by running native test suites and checking coverage.
- Edge Case Identification: Systematically test boundary conditions and invalid inputs to ensure the application handles errors gracefully and prevents crashes.
| name | unit-testing |
|---|---|
| description | Write unit tests for JavaScript files using Node.js native test runner. Use when creating new scripts, fixing bugs, or when prompted about missing tests. |
| allowed-tools | Read, Write, Edit, Bash, Glob, Grep |
Unit Testing Skill
Write and maintain unit tests for JavaScript files using Node.js native test runner.
When Tests Are Required
| Scenario | Test Required | Notes |
|---|---|---|
New script in .claude/scripts/ |
Yes | Every new script needs tests |
| Bug fix | Yes | Test should reproduce and verify fix |
| Refactoring | Verify existing | Ensure tests still pass |
Components in src/ |
Optional | Encouraged but not enforced |
Test File Convention
.claude/scripts/foo-bar.js → .claude/test/validators/foo-bar.test.js
.claude/scripts/health-check.js → .claude/test/validators/health-check.test.js
Quick Start Template
import { describe, it } from 'node:test';
import assert from 'node:assert';
import { execSync } from 'node:child_process';
import { resolve } from 'node:path';
const projectRoot = resolve(import.meta.dirname, '../..');
describe('Script Name', () => {
describe('Valid Cases', () => {
it('should pass for valid input', () => {
// Test implementation
assert.strictEqual(result, expected);
});
});
describe('Invalid Cases', () => {
it('should fail for invalid input', () => {
// Test implementation
assert.ok(result.includes('error'));
});
});
});
Node.js Test Runner Basics
Imports
import { describe, it, before, after, beforeEach, afterEach } from 'node:test';
import assert from 'node:assert';
Assertions
| Method | Use Case |
|---|---|
assert.strictEqual(a, b) |
Exact equality |
assert.ok(value) |
Truthy check |
assert.match(str, /regex/) |
Pattern matching |
assert.throws(fn) |
Exception expected |
assert.rejects(promise) |
Async rejection expected |
assert.deepStrictEqual(a, b) |
Object/array equality |
Running Tests
npm test # Run all tests
npm run test:all # Run with native runner
node --test .claude/test/validators/foo.test.js # Single file
npm run test:coverage # Check test coverage
Minimum Test Requirements
Every script test file should include:
- Happy path test - Normal operation succeeds
- Error handling test - Invalid input handled gracefully
- Edge case test - Boundary conditions covered
Test Organization
describe('Script Name', () => {
// Setup/teardown if needed
before(() => { /* one-time setup */ });
after(() => { /* one-time cleanup */ });
describe('Feature A', () => {
it('should do X when Y', () => {});
it('should handle Z gracefully', () => {});
});
describe('Feature B', () => {
it('should produce expected output', () => {});
});
});
CLI Tool Testing Pattern
Most scripts are CLI tools. Test them by executing with execSync:
function runScript(args = '') {
try {
const output = execSync(
`node .claude/scripts/my-script.js ${args}`,
{ cwd: projectRoot, encoding: 'utf-8' }
);
return { success: true, output };
} catch (error) {
return {
success: false,
output: error.stdout || '',
error: error.stderr || ''
};
}
}
it('should show help with --help flag', () => {
const result = runScript('--help');
assert.ok(result.success);
assert.match(result.output, /Usage:/);
});
Fixtures
- Valid fixtures:
.claude/test/fixtures/valid/ - Invalid fixtures:
.claude/test/fixtures/invalid/<validator-name>/
See FIXTURES.md for fixture organization patterns.
Related Documentation
- PATTERNS.md - Common test patterns
- FIXTURES.md - Fixture organization
- javascript-author skill - Code style
Related Skills
- javascript-author - Write vanilla JavaScript for Web Components with function...
- backend-testing - Write tests for backend services, APIs, and database access
- dependency-wrapper - Wrap third-party libraries for testability and replaceabi...
- vitest - Write and run tests with Vitest for Vite-based projects