@env-hopper/test-kit

中文文档
2.9.3发布于 2026/11/13MITTypeScriptES Module构建来源已验证近 30 天下载 2798

Integration test harness for Env Hopper: mock backend, mock network and page objects

原始使用文档
文档目录9 节
  1. Using it
  2. Writing a scenario in TypeScript
  3. Writing one in Gherkin
  4. Bringing your own catalog
  5. Running the app locally
  6. Against a real backend
  7. Against the mock backend
  8. Replaying a captured catalog
  9. What it does not cover

@env-hopper/test-kit

Integration test harness for Env Hopper. renderApp() mounts the real App — real router, real client DB, real query client — against a mock backend served over msw, and hands back page objects to drive it with.

It exists so that behaviour can be pinned down independently of the UI that implements it. A scenario says "an environment and a resource resolve to one jump url"; only the page objects in src/tools know which element that is. Replacing the UI then means re-pointing the page objects, not rewriting the scenarios.

Using it

// vite.config.ts
import { quickpickle } from 'quickpickle'

export default defineConfig({
  plugins: [viteReact(), svgr(), quickpickle()],
  resolve: {
    // Resolve the cores from source, so nothing needs building first.
    conditions: ['my-custom-condition'],
    alias: { '~': path.resolve(__dirname, '../frontend-core/src') },
  },
  test: {
    environment: 'jsdom',
    environmentOptions: { jsdom: { url: 'http://localhost:3000' } },
    include: ['**/*.feature', '**/*.test.ts', '**/*.test.tsx'],
    setupFiles: ['@env-hopper/test-kit/setup', '@env-hopper/test-kit/cucumber'],
  },
})

Three entry points:

importwhat it is
@env-hopper/test-kitrenderApp, the fixture DSL, the page objects
@env-hopper/test-kit/setupvitest setupFile: jsdom gaps, storage, per-test cleanup
@env-hopper/test-kit/cucumbervitest setupFile: the step definitions

Writing a scenario in TypeScript

const { ui } = await renderApp({ server, initialLink: '/env/dev/app/app1' })

expect(ui.resourceJump.jumps.getUrl('App1')).toBe('http://localhost:4000/env/dev/app/app1')

Writing one in Gherkin

Given the "car shop" catalog opened at "/env/dev/app/parts-inventory"
Then the "Parts Inventory" jump goes to "http://localhost:4000/env/dev/app/parts-inventory"

Bringing your own catalog

The fixtures here are invented sample data. A downstream repo reuses the step definitions verbatim against its own, by registering a fixture under a name its .feature files then ask for:

import { registerCatalog } from '@env-hopper/test-kit/cucumber'

registerCatalog('production', {
  envs: [{ slug: 'dev' }, { slug: 'prod' }],
  apps: [{ slug: 'billing', resourceJumps: '2-pager' }],
})
Given the "production" catalog opened at "/env/prod/app/billing"

Name the environments and the apps; the mapper expands them into every backend shape the frontend reads. A 2-pager also gets a second page whose url needs a value typed in, which is how the late-resolvable parameter path gets covered.

Running the app locally

Anything about appearance needs a real browser, which rules out the harness: jsdom cannot see styling, and msw answers fetches inside the test process, so a browser's own never reach it either. Two ways to get the real UI in front of you at localhost, neither of which needs a deploy.

Against a real backend

The best data is the data a backend actually produces. Start a downstream backend locally, then point the frontend at it through the dev server's proxy:

EH_API_PORT=4002 VITE_EH_API_URL=/api/trpc pnpm run dev:x

A relative VITE_EH_API_URL keeps the request same-origin, so the proxy forwards it — which means a backend sending no CORS headers, normal for one that expects to sit behind its own static server, works unchanged.

Against the mock backend

src/dev-server/serveMockBackend.ts puts the same BackendData the msw handlers serve on a port instead, so nothing needs a database or a backend at all:

pnpm run dev:local     # from the repository root

That starts the mock backend on :4000 and the frontend dev server on :3999. Either way, editing a component is a page reload, not a deploy.

Replaying a captured catalog

The sample fixture is three apps, which is enough for a scenario and not enough to see a layout hold up. capture-fixture.mjs records the two payloads from any running backend — a local one is the obvious choice — and the mock backend replays them, so the loop keeps working offline:

EH_ORIGIN=http://localhost:4002 EH_FIXTURE_DIR=~/eh-fixture \
  node packages/test-kit/scripts/capture-fixture.mjs

EH_FIXTURE_DIR=~/eh-fixture pnpm run dev:local

The capture replaces every secret-looking value with REDACTED in the same pass as the download — the raw response is never written to disk — and prints how many keys it redacted. The key stays, so a credentials panel still renders.

Keep EH_FIXTURE_DIR outside this repository. A real catalog names that backend's own hosts and environments, and this repository is public. Unset, dev:local serves the sample fixture, so the default costs nothing.

variabledefaultwhat it does
EH_FIXTURE_DIRunsetdirectory with the two captured payloads
EH_API_PORT4000port the dev server proxies /api to
VITE_EH_API_URLhttp://localhost:4000/trpcwhere the frontend looks for tRPC

What it does not cover

jsdom has no layout engine and no CSS, so nothing here can see styling.

版本与发布记录

@env-hopper/test-kit 共发布 21 个版本,首次发布于 2026/09/30;过去 12 个月发布了 21 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
2.9.3latest2026/11/13今天
2.9.22026/11/113 天前
2.9.12026/11/104 天前
2.9.02026/11/104 天前
2.8.32026/11/0410 天前
2.8.22026/11/0410 天前

其他发布通道:alpha → 2.1.0-alpha-20261014235627。

关于 @env-hopper/test-kit 的常见问题

@env-hopper/test-kit 是什么?

Integration test harness for Env Hopper: mock backend, mock network and page objects

如何安装 @env-hopper/test-kit?

在项目目录运行 npm install @env-hopper/test-kit,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:jsdom(>=25)、react(19.1.2)、vitest(3.2.2)、react-dom(19.1.2)、@env-hopper/backend-core(^2.9.3)、@env-hopper/frontend-core(^2.9.3)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@env-hopper/test-kit 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@env-hopper/test-kit 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@env-hopper/test-kit 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=16。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@env-hopper/test-kit 可以商用吗?

@env-hopper/test-kit 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@env-hopper/test-kit 的下载量有多少?

根据 npm 官方下载统计,@env-hopper/test-kit 在 2026/10/14 – 2026/11/12 这 30 天内被下载 2,798 次,日均约 93 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@env-hopper/test-kit 还在维护吗?

最新版本 2.9.3 发布于 2026/11/13(今天);至今共发布 21 个版本,其中过去 12 个月发布了 21 个;首次发布于 2026/09/30。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。