| name | test-runner |
| description | Run tests with Jest, Vitest, or Playwright, fix failing tests, and generate missing test coverage. Use when user says "run tests", "test this", "fix failing tests", "write tests", or when tests need to be executed or created. |
| allowed-tools | Bash, Read, Edit, Write, Glob |
Test Runner
When to Use
Activate this skill when:
- User requests to "run tests" or "test this"
- User says "fix failing tests" or "debug test"
- User mentions "jest", "vitest", "playwright", or "testing"
- User asks to "write tests" or "add test coverage"
- User says "check tests" or "verify tests pass"
- CI/CD pipeline shows test failures
- User wants to "test a component" or "test a function"
- User requests "coverage report" or "test coverage"
Instructions
Step 1: Detect Test Framework
- Check package.json for test frameworks:
cat package.json | grep -E '"(jest|vitest|playwright|mocha|jasmine|cypress)"'
- Look for test configuration files:
ls -la jest.config.* vitest.config.* playwright.config.* 2>/dev/null
- Check for test scripts:
cat package.json | grep -E '"(test|test:unit|test:e2e|test:watch)"'
Step 2: Identify Test Type
Determine what kind of tests to run:
- Unit Tests: Test individual functions/components (Jest/Vitest)
- Integration Tests: Test component interactions (Jest/Vitest)
- E2E Tests: Test full user flows (Playwright/Cypress)
- Component Tests: Test React/Vue components (Testing Library)
Step 3: Run Tests
Run All Tests
npm test
npm run test
npm run test:unit
Run Specific Test File
npm test -- path/to/test.spec.ts
npx jest path/to/test.spec.ts
npx vitest path/to/test.spec.ts
npx playwright test path/to/test.spec.ts
Run Tests in Watch Mode
npm test -- --watch
npx jest --watch
npx vitest --watch
Run Tests with Coverage
npm test -- --coverage
npx jest --coverage
npx vitest --coverage
Step 4: Analyze Test Results
-
Review output for:
- Passing tests (✓)
- Failing tests (✗)
- Error messages
- Stack traces
- Coverage percentages
-
Identify failure patterns:
- Assertion failures
- Timeout errors
- Missing mocks
- Import errors
- Type errors
Step 5: Fix Failing Tests
Common Fixes:
-
Assertion Failures:
- Review expected vs. actual values
- Update assertions if behavior changed intentionally
- Fix implementation if test is correct
-
Timeout Errors:
- Increase timeout for slow operations
- Add proper async/await handling
- Mock slow operations
-
Missing Mocks:
- Mock external dependencies
- Mock API calls
- Mock database operations
-
Import Errors:
- Fix import paths
- Update moduleNameMapper in jest.config.js
- Install missing dependencies
Step 6: Write New Tests (if requested)
-
Identify what needs testing
-
Choose appropriate test type
-
Create test file following naming convention:
*.test.ts or *.spec.ts for unit tests
*.test.tsx or *.spec.tsx for component tests
*.e2e.ts for E2E tests
-
Write test using framework's syntax
Step 7: Verify All Tests Pass
npm test
Ensure:
- All tests pass (✓)
- No console errors
- Coverage meets requirements (if applicable)
Examples
Example 1: Run All Unit Tests
cat package.json | grep '"test"'
npm test
Example 2: Fix Failing Test
npm test
cat src/user.test.ts
cat src/user.ts
npm test
Example 3: Write New Component Test
import { render, screen, fireEvent } from '@testing-library/react';
import { Button } from './Button';
describe('Button', () => {
it('should render button text', () => {
render(<Button>Click me</Button>);
expect(screen.getByText('Click me')).toBeInTheDocument();
});
it('should call onClick when clicked', () => {
const handleClick = jest.fn();
render(<Button onClick={handleClick}>Click me</Button>);
fireEvent.click(screen.getByText('Click me'));
expect(handleClick).toHaveBeenCalledTimes(1);
});
it('should be disabled when disabled prop is true', () => {
render(<Button disabled>Click me</Button>);
(screen.()).();
});
});
npm test -- Button.test.tsx
Example 4: Run E2E Tests with Playwright
npx playwright test
npx playwright test tests/login.spec.ts
npx playwright test --headed
npx playwright test --debug tests/login.spec.ts
npx playwright show-report
Example 5: Generate Coverage Report
npm test -- --coverage
npm test -- --coverage
Best Practices
✅ DO:
- Run tests before committing changes
- Write tests for new features immediately
- Fix failing tests before adding new ones
- Use descriptive test names (should/it statements)
- Test edge cases and error conditions
- Mock external dependencies (APIs, databases)
- Use setup/teardown (beforeEach/afterEach) for common code
- Keep tests focused and isolated
- Aim for high coverage on critical code
- Run full test suite before pushing
❌ DON'T:
- Don't skip failing tests (use .skip sparingly)
- Don't write flaky tests (tests that randomly fail)
- Don't test implementation details
- Don't make tests dependent on each other
- Don't hardcode dates/times without mocking
- Don't forget to clean up after tests
- Don't test third-party library code
- Don't write overly complex tests
- Don't ignore console warnings in tests
Test Structure (AAA Pattern):
test('should do something', () => {
const input = 'test';
const expected = 'TEST';
const result = toUpperCase(input);
expect(result).toBe(expected);
});
Common Jest/Vitest Matchers:
expect(value).toBe(expected);
expect(value).toEqual(expected);
expect(value).not.toBe(expected);
expect(value).toBeTruthy();
expect(value).toBeFalsy();
expect(value).toBeNull();
expect(value).toBeUndefined();
expect(value).toBeDefined();
expect(value).toBeGreaterThan(3);
expect(value).toBeGreaterThanOrEqual(3.5);
expect(value).toBeLessThan(5);
expect(value).toBeLessThanOrEqual(4.5);
expect(value).toBeCloseTo(0.3);
expect(value).toMatch(/pattern/);
expect(value).toContain('substring');
expect(array).toContain(item);
expect(array).toHaveLength();
(obj).();
(obj).({ : });
(fn).();
(fn).();
(fn).();
(fn).(arg1, arg2);
(fn).();
Async Testing:
test('should fetch user data', async () => {
const user = await fetchUser(1);
expect(user.name).toBe('John');
});
test('should fetch user data', () => {
return fetchUser(1).then(user => {
expect(user.name).toBe('John');
});
});
test('should handle error', async () => {
await expect(fetchUser(-1)).rejects.toThrow('Invalid ID');
});
Mocking:
const mockFn = jest.fn();
mockFn.mockReturnValue(42);
mockFn.mockResolvedValue('async value');
jest.mock('./api', () => ({
fetchUser: jest.fn().mockResolvedValue({ name: 'John' })
}));
const spy = jest.spyOn(object, 'method');
Test Checklist
Before running tests:
When writing tests:
After running tests:
Troubleshooting
Issue: Tests timeout
Solution: Increase timeout with jest.setTimeout(10000) or add --testTimeout=10000 flag. Check for missing awaits.
Issue: "Cannot find module" error
Solution: Check import paths, install missing dependencies, or update moduleNameMapper in jest.config.js.
Issue: Mock not working
Solution: Ensure mock is defined before import. Use jest.mock() at top of file. Clear mocks between tests with jest.clearAllMocks().
Issue: Tests pass locally but fail in CI
Solution: Check for environment-specific issues (timezone, file paths, env variables). Ensure same Node version.
Issue: Flaky tests (random failures)
Solution: Look for race conditions, missing awaits, or tests depending on execution order. Add proper waits.
Issue: Low coverage
Solution: Identify uncovered lines with --coverage. Write tests for critical paths first. Use coverage thresholds.
Issue: Tests too slow
Solution: Use --maxWorkers=50% to limit parallel workers. Mock expensive operations. Split into unit vs integration tests.
Framework-Specific Commands
Jest
npm test
npx jest path/to/test.spec.ts
npx jest --testNamePattern="should fetch user"
npx jest --watch
npx jest --coverage
npx jest --updateSnapshot
npx jest --clearCache
Vitest
npx vitest
npx vitest path/to/test.spec.ts
npx vitest
npx vitest run
npx vitest --coverage
npx vitest --ui
Playwright
npx playwright test
npx playwright test tests/login.spec.ts
npx playwright test --headed
npx playwright test --debug
npx playwright test --project=chromium
npx playwright codegen
npx playwright show-report
npx playwright install
CI/CD Integration
- name: Run tests
run: npm test
- name: Run tests with coverage
run: npm test -- --coverage
- name: Upload coverage
uses: codecov/codecov-action@v3
with:
files: ./coverage/coverage-final.json
Coverage Thresholds
jest.config.js:
module.exports = {
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80
}
}
};