ts-testing

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
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.
本技能将指导你为TypeScript代码构建实用、可维护的测试套件。重点关注行为覆盖、快速反馈,以及与项目现有工具链的适配。
目标用户为专注于TypeScript的开发者。他们通常关心代码正确性、重构安全性,以及避免陷入不稳定或脆弱的测试泥潭。

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.
在以下场景中使用本技能:
  • 用户需要添加或更新单元测试、集成测试或端到端测试
  • 用户报告了一个Bug,并需要编写回归测试
  • 用户正在重构代码,希望确保未破坏原有功能
  • 仓库已配置测试工具(或明显需要配置),且用户要求“添加测试”或“优化测试”
如果仓库已有测试栈,请不要自行引入新的测试栈。首先检测并遵循现有配置。

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
        vitest
        is present, use it. Else if
        jest
        is present, use that.
  • React / UI component tests
    • Use Testing Library with the existing runner:
      • @testing-library/react
        with Vitest or Jest
  • 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.
始终优先适配仓库现有配置(检查
package.json
devDependencies
、配置文件):
  • 如果仓库已使用某一测试框架(Jest、Vitest、Playwright、Cypress等),请坚持使用该框架
  • 仅当仓库无明确测试栈时,才建议引入新的测试库。
当你必须自行选择时,优先考虑:
  • 单元/集成测试
    • Node/后端/共享库:
      • 优先选择Vitest
        vitest
        )或Jest
        jest
      • 若已存在
        vitest
        则使用它,否则使用
        jest
  • React/UI组件测试
    • 结合现有运行器使用Testing Library
      • 搭配Vitest或Jest使用
        @testing-library/react
  • 端到端浏览器测试
    • 若已安装或从零开始搭建,优先选择Playwright
    • 若仓库已使用Cypress或用户明确要求,则使用Cypress
如果仓库使用较小众的测试栈(Mocha、Ava、Node内置测试运行器),请尊重该选择并适配。

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
遵循以下原则:
  • 测试行为,而非实现细节
    • React/UI场景:测试用户可见和可操作的内容(DOM、事件、ARIA属性),而非内部状态或私有方法
    • 服务端场景:测试公共API,而非私有辅助函数
  • 保持测试快速且聚焦
    • 优先编写小型、确定性强且运行快速的测试
    • 除非明确编写集成测试,否则避免不必要的网络、文件系统或数据库调用
  • 让失败原因清晰明了
    • 使用清晰的命名和断言,解释测试失败的原因
    • 必要时采用“给定/当/则”(given/when/then)风格的描述性测试名称
  • 最小化Mock,但在合理场景下使用
    • Mock外部服务、网络调用和慢速依赖
    • 除非有充分理由,否则避免Mock自身业务逻辑

Standard workflow

标准工作流程

When asked to add or improve tests, follow this workflow:
  1. Detect the existing stack
    • Inspect
      package.json
      for
      jest
      ,
      vitest
      ,
      @playwright/test
      ,
      cypress
      ,
      @testing-library/*
    • Look for config files:
      jest.config.*
      ,
      vitest.config.*
      ,
      playwright.config.*
      ,
      cypress.config.*
    • Check
      test
      ,
      unit
      , or
      e2e
      scripts in
      package.json
  2. Locate the right place for the test
    • Mirror existing patterns:
      • If tests live in
        __tests__
        directories, follow that
      • If they use
        *.test.ts
        or
        *.spec.ts
        , do the same
    • For UI: place tests near the component (e.g.
      Component.test.tsx
      ) if that’s the existing convention
  3. Write the test in a TS‑friendly way
    • Use
      .test.ts
      /
      .test.tsx
      (or
      .spec
      ) as per repo convention
    • Avoid
      any
      in tests when possible; use real types or minimal interfaces to keep tests robust
    • For async code: use
      await
      with async test functions, avoid dangling promises
  4. Follow library‑specific best practices
    Vitest / Jest
    • Use
      describe
      /
      it
      or
      test
      with 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-testid
      or semantics consistently as locators
  5. 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)")
      )
  6. 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.json
      scripts following existing style
当用户要求添加或优化测试时,请遵循以下流程:
  1. 检测现有测试栈
    • 检查
      package.json
      中的
      jest
      vitest
      @playwright/test
      cypress
      @testing-library/*
      依赖
    • 查找配置文件:
      jest.config.*
      vitest.config.*
      playwright.config.*
      cypress.config.*
    • 查看
      package.json
      中的
      test
      unit
      e2e
      脚本
  2. 确定测试文件的正确位置
    • 遵循现有模式:
      • 如果测试文件存放在
        __tests__
        目录中,保持该习惯
      • 如果使用
        *.test.ts
        *.spec.ts
        命名格式,遵循该格式
    • UI组件测试:若现有约定是将测试文件放在组件附近(如
      Component.test.tsx
      ),则遵循该约定
  3. 以TS友好的方式编写测试
    • 根据仓库约定使用
      .test.ts
      /
      .test.tsx
      (或
      .spec
      )后缀
    • 尽可能避免在测试中使用
      any
      类型;使用真实类型或最小化接口,保持测试的健壮性
    • 异步代码:在异步测试函数中使用
      await
      ,避免悬垂Promise
  4. 遵循各测试库的最佳实践
    Vitest / Jest
    • 使用
      describe
      /
      it
      test
      语法,并搭配清晰的命名
    • 优先使用
      vi.fn()
      /
      jest.fn()
      创建间谍函数和Mock
    • 模块Mock:使用
      vi.mock()
      /
      jest.mock()
      ,并将Mock代码放在文件顶部
    • 计时器:仅在必要时使用假计时器(
      vi.useFakeTimers()
      /
      jest.useFakeTimers()
    React Testing Library
    • 使用
      render
      screen
      和用户交互方法(
      userEvent
    • 以用户视角选择查询方式(优先使用
      getByRole
      getByLabelText
    • 除非没有合适的语义化替代方案,否则避免通过测试ID查询
    Playwright / Cypress
    • 使用现有夹具和辅助工具(如已认证会话、基准URL),而非重新实现
    • 保持测试独立,不要依赖测试执行顺序
    • 统一使用
      data-testid
      或语义化定位器
  5. 为已报告的Bug添加回归测试
    • 首先编写一个复现Bug的失败测试
    • 然后修改实现代码,使测试通过
    • 清晰命名回归测试(例如:
      it("当X为null时不会崩溃(回归#123)")
  6. 运行测试
    • 使用现有脚本,如
      npm test
      pnpm test
      npx vitest
      npx jest
      npx playwright test
    • 若添加新的测试命令,请遵循现有风格将其添加到
      package.json
      的scripts中

Patterns to prefer

推荐采用的模式

  • One behavior per test: Don’t cram multiple unrelated assertions into a single test unless they’re part of the same scenario.
  • Helper factories: Use small factory functions for building test data (
    makeUser
    ,
    makeOrder
    ) instead of duplicating setup.
  • Explicit async handling: Always
    await
    promises; avoid passing async callbacks to APIs that don’t expect them.
  • 每个测试对应一个行为:不要在单个测试中塞入多个不相关的断言,除非它们属于同一场景。
  • 辅助工厂函数:使用小型工厂函数构建测试数据(如
    makeUser
    makeOrder
    ),而非重复编写初始化代码。
  • 显式处理异步:始终使用
    await
    处理Promise;避免将异步回调传递给不支持的API。

Anti‑patterns to avoid

需要避免的反模式

  • Overuse of snapshots for complex objects or DOM – use targeted assertions instead
  • Testing private methods directly
  • Heavy mocking that makes tests mirror implementation wiring
  • Flaky tests that depend on real time, network, or global state without control
  • 对复杂对象或DOM过度使用快照测试——改用针对性的断言
  • 直接测试私有方法
  • 过度Mock,导致测试镜像实现细节
  • 依赖真实时间、网络或全局状态且未加控制的不稳定测试

TypeScript‑specific guidance

TypeScript专属指导

  • Use the project’s
    tsconfig
    for tests when possible (
    tsconfig.test.json
    if present)
  • Avoid silencing type errors just to “get tests compiling”
  • When stubbing data, create minimal typed helpers rather than using
    as any
If the user asks you to generate tests, prefer fewer, high‑value tests that mirror real usage over large, mechanical test suites.
  • 尽可能为测试使用项目的
    tsconfig
    (若存在
    tsconfig.test.json
    则优先使用)
  • 不要为了“让测试编译通过”而忽略类型错误
  • 当Stub数据时,创建最小化的类型化辅助函数,而非使用
    as any
如果用户要求你生成测试,请优先编写少量高价值、贴合真实使用场景的测试,而非大量机械生成的测试套件。",