@app-studio/qa-seed

中文文档
0.11.6发布于 2026/11/06UNLICENSEDTypeScriptES Module近 30 天下载 2147

Seeds as per-feature modules composed in dependency order under a cross-process lock, plus the dependency-free HTTP verifier that doubles as the end-to-end readiness gate.

原始使用文档
文档目录7 节
  1. What a seed is for
  2. Discovered, not declared
  3. Three rules that are not style preferences
  4. The lock
  5. Verifying, over HTTP
  6. Exports
  7. Requirements

@app-studio/qa-seed

Seeds as per-feature modules, composed in dependency order under a lock — plus the dependency-free HTTP verifier that doubles as the end-to-end readiness gate.

What a seed is for

Not a foundation the system rests on. The world a given scenario needs, so it can be replayed in the same shape by anyone, forever. "An administrator invites someone who is already a member" needs a workspace, an administrator and that member; the seed for it is exactly that and nothing more.

Which is why seeds come after the API decisions, never before: data written before the API is data written against a guess.

Discovered, not declared

// src/features/identity/seed/index.ts
import type { SeedModule } from '@app-studio/qa-seed';

const seed: SeedModule<AppContext> = {
  key: 'identity',
  async run({ auth }) {
    const admin = await auth.signUp({ email: '[email protected]', password: 'password123456' });
    return [{ name: 'identity.adminId', value: admin.id }];
  },
};

export default seed;
const modules = await discoverSeedModules({ rootDir, pattern: 'src/features/*/seed/index.ts' });
await runSeed({ rootDir, modules, context });

Dropping the file into a feature makes it seed; deleting the feature deletes its seed. There is no central list, because a central list is the thing that silently goes wrong: a feature is removed, its entry stays, and the next person to read the list believes in a feature that no longer exists.

Three rules that are not style preferences

Call the real services, never SQL. An administrator inserted into a members table is a different administrator from one who accepted an invitation — no audit entry, no analytics event, no realtime publish. Every test that then relies on those side effects is testing a world the application cannot actually produce.

Declare the order; do not assume it. File order is not a dependency graph, and a seed that happens to work because of how a glob sorted its inputs breaks the day someone renames a feature. composeSeeds topologically sorts by dependsOn, names the cycle when there is one, and is deterministic so two runs of one registry produce one order.

Idempotence is the property that breaks. A seed run twice against a database somebody forgot to reset must produce the same world, not a second copy of it.

The lock

runSeed holds a cross-process lock for the duration. Not caution: two seed runs against one database interleave into a state neither of them describes, and the resulting failures look like application bugs — a row that exists twice, a unique constraint firing on data the code never wrote.

The lock is keyed by checkout, so two worktrees seed concurrently and two shells in the same checkout do not. A stale lock is reported with the holder's details and the exact command to clear it, never deleted automatically — two waiters can both observe a dead holder and both delete the file, and the second delete evicts a lock the first has just legitimately taken.

Verifying, over HTTP

import { expectNonEmpty, verifySeed, waitForSeed } from '@app-studio/qa-seed';

export const checks = [
  expectNonEmpty(
    'a workspace exists',
    '/api/workspaces',
    'Every journey signs in and lands in a workspace; with none seeded, they all fail on the first screen.',
  ),
];

Over HTTP and not over SQL, deliberately. In an end-to-end run the API often holds the only connection to the database — an embedded engine, a pooled connection, a container the test process cannot reach — so a SQL verifier would either fail to connect or, worse, connect to a different database and cheerfully report success.

Every check carries a proves line, and the report prints it. "Expected 1, got 0" sends somebody to read the check; "with none seeded, they all fail on the first screen" sends them to fix the seed.

The same function is the readiness gate. Nothing that drives a browser should start before it passes: a UI suite launched against an unseeded database fails somewhere in the middle of a screen, with a screenshot of an empty list and nothing saying the data was never there. qa e2e runs this between starting the API and starting anything a browser will talk to.

waitForSeed is the same checks with a deadline, for the boot window. Failure reports what was still wrong, not just that time ran out.

Exports

ExportPurpose
SeedModule, composeSeedsThe unit, and the dependency-ordered composition.
discoverSeedModulesFind them by looking.
runSeedRun them in order, under the lock, collecting published artifacts.
verifySeed, waitForSeed, formatVerifyReportProve the world is there.
expectNonEmpty, expectJsonThe commonest checks, written out.

Requirements

Node.js 20 or newer. No runtime dependencies beyond @app-studio/qa-core and a glob — the verifier in particular is dependency-free so it can run anywhere, including in a container that has nothing else installed.

版本与发布记录

@app-studio/qa-seed 共发布 33 个版本,首次发布于 2026/08/09;过去 12 个月发布了 33 个版本。

版本发布日期距今
0.11.6latest2026/11/061 天前
0.11.32026/11/017 天前
0.11.22026/10/2217 天前
0.11.12026/10/1622 天前
0.10.42026/10/0830 天前
0.10.3next2026/10/0830 天前

关于 @app-studio/qa-seed 的常见问题

@app-studio/qa-seed 是什么?

Seeds as per-feature modules composed in dependency order under a cross-process lock, plus the dependency-free HTTP verifier that doubles as the end-to-end readiness gate.

如何安装 @app-studio/qa-seed?

在项目目录运行 npm install @app-studio/qa-seed,或使用 pnpm add / yarn add / bun add。

@app-studio/qa-seed 支持 TypeScript 吗?

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

@app-studio/qa-seed 支持 ESM 还是 CommonJS?

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

@app-studio/qa-seed 需要什么版本的 Node.js?

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

@app-studio/qa-seed 可以商用吗?

@app-studio/qa-seed 使用 UNLICENSED 许可。作者声明为 UNLICENSED,即不授予公开使用许可(与公共领域的 Unlicense 不同)。使用前需获得作者授权。以上为概括,不构成法律意见,请以许可原文为准。

@app-studio/qa-seed 的下载量有多少?

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

@app-studio/qa-seed 还在维护吗?

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