ts-testing
from johnlindquist/claude-workshop-skills
No description
npx skills add https://github.com/johnlindquist/claude-workshop-skills --skill ts-testingSKILL.md
This skill guides you to build pragmatic, maintainable test suites for TypeScript code. Focus on behavioral coverage, fast feedback, and alignment with the project's existing tooling.
The user is a TypeScript‑focused developer. They likely care about correctness, refactoring safety, and not drowning in flaky or brittle tests.
When to use this skill
Use this skill when:
- The user is adding or updating unit, integration, or end‑to‑end tests
- The user reports a bug and wants a regression test
- The user is refactoring and wants confidence they didn’t break behavior
- The repo has test tooling configured (or clearly needs one) and you’re asked to “add tests” or “improve tests”
Do not invent a new test stack if the repo already has one. First detect and follow the existing setup.
Library preferences
Always align with the repo first (check package.json, devDependencies, config files):
- If the repo already uses a framework (Jest, Vitest, Playwright, Cypress, etc.), stick with it.
- Only suggest new libraries if there is no obvious testing stack yet.
When you must choose, prefer:
- Unit / integration tests
- Node / backend / shared libraries:
- Prefer Vitest (
vitest) or Jest (jest) - If
vitestis present, use it. Else ifjestis present, use that.
- Prefer Vitest (
- Node / backend / shared libraries:
- React / UI component tests
- Use Testing Library with the existing runner:
@testing-library/reactwith Vitest or Jest
- Use Testing Library with the existing runner:
- End‑to‑end browser tests
- Prefer Playwright if installed or if starting from scratch
- Use Cypress if the repo already uses it or the user asks for it explicitly
If the repo uses a less common stack (Mocha, Ava, Node’s built‑in test runner), respect that choice and adapt.
Core testing philosophy
Follow these principles:
- Test behavior, not implementation details
- For React/UI: test what the user sees and does (DOM, events, ARIA), not internal state or private methods
- For services: test public APIs, not private helpers
- Keep tests fast and focused
- Prefer small, deterministic tests that run quickly
- Avoid unnecessary network, filesystem, or database calls unless you are explicitly writing integration tests
- Make failures obvious
- Clear naming and assertions that explain why a test failed
- Use descriptive test names following “given/when/then” style where helpful
- Minimize mocking, but use it where it makes sense
- Mock external services, network calls, and slow dependencies
- Avoid mocking your own business logic unless there’s a strong reason
Standard workflow
When asked to add or improve tests, follow this workflow:
-
Detect the existing stack
- Inspect
package.jsonforjest,vitest,@playwright/test,cypress,@testing-library/* - Look for config files:
jest.config.*,vitest.config.*,playwright.config.*,cypress.config.* - Check
test,unit, ore2escripts inpackage.json
- Inspect
-
Locate the right place for the test
- Mirror existing patterns:
- If tests live in
__tests__directories, follow that - If they use
*.test.tsor*.spec.ts, do the same
- If tests live in
- For UI: place tests near the component (e.g.
Component.test.tsx) if that’s the existing convention
- Mirror existing patterns:
-
Write the test in a TS‑friendly way
- Use
.test.ts/.test.tsx(or.spec) as per repo convention - Avoid
anyin tests when possible; use real types or minimal interfaces to keep tests robust - For async code: use
awaitwith async test functions, avoid dangling promises
- Use
-
Follow library‑specific best practices
Vitest / Jest
- Use
describe/itortestwith clear names - Prefer
vi.fn()/jest.fn()for spies and mocks - For modules: use
vi.mock()/jest.mock()and keep mocks at the top of the file - For timers: use fake timers only when necessary (
vi.useFakeTimers()/jest.useFakeTimers())
React Testing Library
- Use
render,screen, and user interactions (userEvent) - Query by role, label, text as a user would (prefer
getByRole,getByLabelText) - Avoid querying by test IDs unless there’s no good semantic alternative
Playwright / Cypress
- Use existing fixtures and helpers (e.g. authenticated sessions, base URL) instead of re‑inventing them
- Keep tests independent; don’t rely on order
- Use
data-testidor semantics consistently as locators
- Use
-
Add regression tests for reported bugs
- Reproduce the bug in a failing test first
- Only then change the implementation to make the test pass
- Name regression tests clearly (e.g.
it("does not crash when X is null (regression #123)"))
-
Running tests
- Use existing scripts, e.g.
npm test,pnpm test,npx vitest,npx jest,npx playwright test - If adding a new test command, wire it into
package.jsonscripts following existing style
- Use existing scripts, e.g.
Patterns to prefer
- One behavior per test: Don’t cram multi
...