test-automator — Claude Code skill for writing tests
Writes unit, integration and E2E tests, sets up a framework and reports coverage. Useful when a project has few tests or they have drifted.
npx skills add zhaono1/agent-playbook --skill test-automator -a claude-codeWhat test-automator does
The skill activates when you ask for tests, mention test automation, or want coverage improved. It ships with the testing pyramid and worked examples for Jest, Supertest and Playwright, plus naming conventions and a list of things to avoid: testing implementation details, testing third-party libraries, committing commented-out tests.
Two scripts come with it. scripts/generate_test.py builds a boilerplate plan from a feature name, and scripts/coverage_report.py produces a coverage report from a service name. Both run through python3, so Python has to be on the machine first — otherwise those steps do nothing. Coverage targets are given as a table: lines and functions above 80%, branches above 75%.
The metadata declares an after_complete hook with the session-logger trigger in auto mode, which logs test creation. If you already run your own session logger, check whether the two will write duplicate entries.
What it helps with
- write unit tests for a new service
- add integration tests for HTTP routes
- script a Playwright login flow
- measure branch coverage and see the gaps
- pick a test framework and run command for the project language
Example prompts for the agent
- write tests for UserService, cover creation and email validation
- add an integration test for POST /api/users
- measure coverage and show me which branches are missing
How to install test-automator
1Skills CLI (Vercel)
npx skills add zhaono1/agent-playbook --skill test-automator -a claude-code2Manually: put the files in place
~/.claude/skills/test-automator/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/test-automator/
1Skills CLI (Vercel)
npx skills add zhaono1/agent-playbook --skill test-automator -a codex2Manually: put the files in place
.agents/skills/test-automator/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add zhaono1/agent-playbook --skill test-automator -a cursor2Manually: put the files in place
.cursor/skills/test-automator/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install zhaono1/agent-playbook test-automator2Manually: put the files in place
.github/skills/test-automator/SKILL.md1Skills CLI (Vercel)
npx skills add zhaono1/agent-playbook --skill test-automator -a gemini-cli2Platform CLI
gemini skills install https://github.com/zhaono1/agent-playbook --path skills/test-automatorManually: put the files in place
.devin/skills/test-automator/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add zhaono1/agent-playbook --skill test-automator -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about test-automator
How do I install test-automator in Claude?
Run npx skills add zhaono1/agent-playbook --skill test-automator -a claude-code. The skill then lands at ~/.claude/skills/test-automator/SKILL.md.
What does test-automator do?
It helps create and maintain automated tests: it lays out the testing pyramid, gives examples for Jest, Supertest and Playwright, tracks coverage, and generates test boilerplate with its scripts.
What do the skill's scripts need to run?
scripts/generate_test.py and scripts/coverage_report.py are invoked through python3, so Python must be installed. The rest of the material is reference docs and examples that run nothing.
Source text
SKILL.md · MIT
---
name: test-automator
description: Test automation framework expert for creating and maintaining automated tests. Use when user asks to write tests, automate testing, or improve test coverage.
allowed-tools: Read, Write, Edit, Bash, Grep, Glob
metadata:
hooks:
after_complete:
- trigger: session-logger
mode: auto
reason: "Log test creation"
---
# Test Automator
Expert in creating and maintaining automated tests for various frameworks and languages.
## When This Skill Activates
Activates when you:
- Ask to write tests
- Mention test automation
- Request test coverage improvement
- Need to set up testing framework
## Testing Pyramid
```
/\
/E2E\ - Few, expensive, slow
/------\
/ Integration \ - Moderate number
/--------------\
/ Unit Tests \ - Many, cheap, fast
/------------------\
```
## Unit Testing
### Principles
1. **Test behavior, not implementation**
2. **One assertion per test** (generally)
3. **Arrange-Act-Assert** pattern
4. **Descriptive test names**
### Example (Jest)
```typescript
describe('UserService', () => {
describe('createUser', () => {
it('should create a user with valid data', async () => {
// Arrange
const userData = {
name: 'John Doe',
email: '[email protected]'
};
// Act
const user = await userService.create(userData);
// Assert
expect(user.id).toBeDefined();
expect(user.email).toBe(userData.email);
});
it('should throw error for invalid email', async () => {
// Arrange
const userData = { email: 'invalid' };
// Act & Assert
await expect(userService.create(userData))
.rejects.toThrow('Invalid email');
});
});
});
```
## Integration Testing
### Principles
1. **Test component interactions**
2. **Use test doubles for external services**
3. **Clean up test data**
4. **Run in isolation**
### Example (Supertest)
```typescript
describe('POST /api/users', () => {
it('should create a user', async () => {
const response = await request(app)
.post('/api/users')
.send({
name: 'John Doe',
email: '[email protected]'
})
.expect(201)
.expect((res) => {
expect(res.body.id).toBeDefined();
expect(res.body.email).toBe('[email protected]');
});
});
});
```
## E2E Testing
### Principles
1. **Test critical user flows**
2. **Use realistic test data**
3. **Handle async operations properly**
4. **Clean up after tests**
### Example (Playwright)
```typescript
test('user can login', async ({ page }) => {
await page.goto('/login');
await page.fill('[name="email"]', '[email protected]');
await page.fill('[name="password"]', 'password123');
await page.click('button[type="submit"]');
await expect(page).toHaveURL('/dashboard');
await expect(page.locator('h1')).toContainText('Welcome');
});
```
## Test Coverage
### Coverage Goals
| Type | Target |
|------|--------|
| Lines | > 80% |
| Branches | > 75% |
| Functions | > 80% |
| Statements | > 80% |
### Coverage Reports
```bash
# Jest
npm test -- --coverage
# Python (pytest-cov)
pytest --cov=src --cov-report=html
# Go
go test -coverprofile=coverage.out
go tool cover -html=coverage.out
```
## Testing Best Practices
### DO's
- Write tests before fixing bugs (TDD)
- Test edge cases
- Keep tests independent
- Use descriptive test names
- Mock external dependencies
- Clean up test data
### DON'Ts
- Don't test implementation details
- Don't write brittle tests
- Don't skip tests without a reason
- Don't commit commented-out tests
- Don't test third-party libraries
## Test Naming Conventions
```typescript
// Good: Describes what is being tested
it('should reject invalid email addresses')
// Good: Describes the scenario and outcome
it('returns 401 when user provides invalid credentials')
// Bad: Vague
it('works correctly')
```
## Common Testing Frameworks
| Language | Framework | Command |
|----------|-----------|---------|
| TypeScript/JS | Jest, Vitest | `npm test` |
| Python | pytest | `pytest` |
| Go | testing | `go test` |
| Java | JUnit | `mvn test` |
| Rust | built-in | `cargo test` |
## Scripts
Generate test boilerplate:
```bash
python3 scripts/generate_test.py --name <feature> --output tests/test-plan.md
```
Check test coverage:
```bash
python3 scripts/coverage_report.py --name <service-name> --output coverage-report.md
```
## References
- `references/best-practices.md` - Testing best practices
- `references/examples/` - Framework-specific examples
- `references/mocking.md` - Mocking guidelines
© zhaono1 · MIT · zhaono1/agent-playbook