meteor-testing
Use when setting up, designing, writing, or repairing tests and test harnesses in a Meteor 3 app. Triggers on meteortesting:mocha, --driver-package, TEST_WATCH, TEST_BROWSER_DRIVER, MOCHA_GREP, meteor.testModule, focused tests, .only, Meteor.server.method_handlers, Meteor.server.publish_handlers, DDP.connect, --full-app integration mode, sinon, async test signatures, Playwright/Cypress E2E. Use this skill when the user asks about test runners, asks about testing publications, or asks about Jest vs Mocha in Meteor. For a failing, hanging, or flaky test whose failing layer or root cause is unknown, use meteor-debugging before changing the test or app.
- License 许可
- MIT
- 最近更新
- 2026-11-13
- Stars
- ★ 11
- Forks
- 3
01 前言 Front Matter
- name
- meteor-testing
- license
- MIT
- metadata
- { "area": "testing", "kind": "knowledge", "author": "meteor", "bundle": [ "fullstack" ], "meteor": ">=3.0", "tagline": "Set up and write Meteor 3 tests (`meteortesting:mocha`, async signatures, methods/publications, Playwright/Cypress E2E).", "docs_synced_at": "2026-11-13" }
- description
- Use when setting up, designing, writing, or repairing tests and test harnesses in a Meteor 3 app. Triggers on meteortesting:mocha, --driver-package, TEST_WATCH, TEST_BROWSER_DRIVER, MOCHA_GREP, meteor.testModule, focused tests, .only, Meteor.server.method_handlers, Meteor.server.publish_handlers, DDP.connect, --full-app integration mode, sinon, async test signatures, Playwright/Cypress E2E. Use this skill when the user asks about test runners, asks about testing publications, or asks about Jest vs Mocha in Meteor. For a failing, hanging, or flaky test whose failing layer or root cause is unknown, use meteor-debugging before changing the test or app.
02 资源文件 5
- 参考文档references/ddp-test-helpers.md2.7 KB
- 参考文档references/eval-cases.md11.5 KB
- 参考文档references/focused-runs.md4.2 KB
- 参考文档references/meteor-3.5.2-testing.md3.6 KB
- 参考文档references/mocha-setup.md5.0 KB
03 SKILL.md 正文
Testing Meteor 3 apps
meteortesting:mocha is the canonical Meteor test driver. It boots the
app in test mode (no app code runs except the test files) and reports
results in the server console.
If an existing test fails, hangs, or flakes and the failing layer is unknown,
use meteor-debugging to isolate the cause. Return here when evidence points to
test setup, design, driver behavior, fixtures, or regression coverage.
Decision flow
- Unknown failure in an existing test? Use
meteor-debuggingto classify application, data, harness, browser, environment, or shared-state causes. - Pure logic, no Meteor APIs? Plain Mocha or any test runner; nothing Meteor-specific.
- Method or publication? Integration test it with
meteortesting:mochausingMeteor.server.method_handlers[name].apply(ctx, args)orpublish_handlers. - Need to drive a real DDP client (cross-process or end-to-end DDP
semantics)? Use
--full-appmode andDDP.connect. - UI flow / browser interaction? Start the normal app with deterministic
test settings and run Playwright or Cypress against it. Use
meteor test --full-apponly when the browser flow must load app-test modules.
Setup
meteor add meteortesting:mocha
meteor npm install --save-dev @types/mocha
// package.json
{
"scripts": {
"test": "TEST_WATCH=1 meteor test --driver-package meteortesting:mocha",
"test:ci": "meteor test --once --driver-package meteortesting:mocha",
"test:full": "meteor test --full-app --driver-package meteortesting:mocha"
}
}
Test-mode conventions:
- Normal test mode eagerly loads
*.test[s].*and*.spec[s].*files, while ordinary application code loads only when imported by a test. - Filename discovery ignores
tests/directories. A configuredmeteor.testModuleinstead loads its explicit entry module and imports. --full-appeagerly loads the normal app plus*.app-test[s].*and*.app-spec[s].*files, and setsMeteor.isAppTest.
For Meteor 3.5.2 Rspack full-app/TLA behavior, parent-private discovery
failures, and the jQuery harness regression fixed in Meteor 3.6, read
release-specific test setup. Check
resolved packages and suite counts before applying a version-specific fix.
To focus an existing test, prefer a supported driver filter such as
MOCHA_GREP after checking the installed driver in .meteor/versions; use
.only only temporarily. These select registered tests but do not prevent
other test modules from evaluating. If loading itself causes interference,
inspect meteor.testModule and read references/focused-runs.md before
narrowing entrypoint imports. Restore every temporary focus or import change,
then run the normal affected suite. Read the configured entrypoint paths from
the project; do not invent paths, scripts, ports, or helpers.
For Meteor 3.6 Rspack ignore exceptions or separate legacy test entries, use the architecture and ignore boundaries. Check expected suites on each selected program; a modern zero-exit run is not proof of legacy coverage.
Method test (server-side)
Shared test entries also reach the browser. Use assert with strict methods;
server guards cannot hide static imports. See
assertion imports.
import assert from "assert";
import { Meteor } from "meteor/meteor";
import { Items } from "/imports/api/items";
if (Meteor.isServer) {
describe("items.add", function () {
beforeEach(async function () {
await Items.removeAsync({});
});
it("inserts when authed", async function () {
const _id = await Meteor.server.method_handlers["items.add"].apply(
{ userId: "u1" },
[{ title: "x", qty: 1 }],
);
const doc = await Items.findOneAsync(_id);
assert.strictEqual(doc.title, "x");
});
it("rejects when unauthed", async function () {
await assert.rejects(() =>
Meteor.server.method_handlers["items.add"].apply({ userId: null }, [{}]),
);
});
});
}
.apply(context, argsArray) is the documented form;
Meteor.server.method_handlers[name] is the registered method
implementation. Pass a stub this with userId (and unblock,
connection, etc. when needed).
Publication test (server-side)
if (Meteor.isServer) {
describe("items.mine publication", function () {
it("only ships the subscribing user's items", async function () {
await Items.removeAsync({});
await Items.insertAsync({ _id: "a", ownerId: "u1" });
await Items.insertAsync({ _id: "b", ownerId: "u2" });
const cursor = await Meteor.server.publish_handlers["items.mine"]
.apply({ userId: "u1" }, []);
const docs = await cursor.fetchAsync();
assert.deepStrictEqual(docs.map((d) => d._id), ["a"]);
});
});
}
For publications using the low-level this.added / this.changed API,
test with a real DDP client via --full-app mode (next section).
Always await the direct publish handler. Conventional handlers return the cursor immediately; async handlers return a Promise of the cursor.
End-to-end DDP test (--full-app mode)
import { DDP } from "meteor/ddp-client";
import { Mongo } from "meteor/mongo";
import { Tracker } from "meteor/tracker";
const conn = DDP.connect(Meteor.absoluteUrl());
const RemoteItems = new Mongo.Collection("items", { connection: conn });
function ready(sub) {
return new Promise((resolve) => {
const computation = Tracker.autorun((c) => {
if (sub.ready()) {
c.stop();
resolve();
}
});
});
}
const sub = conn.subscribe("items.mine");
await ready(sub);
const docs = RemoteItems.find().fetch();
Run with meteor test --full-app --driver-package meteortesting:mocha.
Client unit test (Minimongo)
if (Meteor.isClient) {
describe("Items minimongo", function () {
beforeEach(function () { Items.remove({}); });
it("filters by ownerId", function () {
Items.insert({ _id: "a", ownerId: "u1" });
Items.insert({ _id: "b", ownerId: "u2" });
assert.strictEqual(Items.find({ ownerId: "u1" }).count(), 1);
});
});
}
Client tests run in the browser the driver spawns. With
TEST_BROWSER_DRIVER=puppeteer, the browser is headless Chromium and
results flow back to the server console.
Do not treat a server-only green run as complete client coverage. The driver
prints a message when no browser is connected; configure
TEST_BROWSER_DRIVER in CI and confirm client test counts are present.
Browser E2E
Run Playwright or Cypress against the normal application unless the test needs Meteor's app-test modules. The server command must work from a clean clone with a tracked, nonsecret settings fixture or fully documented test environment variables. Do not point it at an ignored developer settings file.
Cover at least one complete mutation flow and one rejected server action. Basic page-title checks do not exercise async method stubs, authorization, or publication readiness.
Anti-patterns
- Reach for Jest. Jest does not understand Meteor's build system. Use
meteortesting:mocha. - Mock Mongo. Run the real driver against a clean DB.
- Forget
if (Meteor.isServer) { ... }guards. Server tests crash if they run in the browser harness. - Skip
beforeEachcleanup. Tests leak state across runs. - Catch and log a
beforeEachfailure without rethrowing. The test then runs against unknown state and can report a misleading assertion. - Assert only the database postcondition for a rejected method. Also require
the Promise to reject with the expected
Meteor.Error. - Replace
Meteor.userIdor another global without restoring it inafterEach. - Use
Meteor.callwith callbacks in async test code. UseMeteor.callAsyncor unwrapmethod_handlersdirectly.
See also
references/mocha-setup.mdreferences/focused-runs.mdreferences/ddp-test-helpers.mdreferences/eval-cases.md
04 同仓库更多 Skills
meteor-native
Use when building or maintaining Meteor 3 Android/iOS apps through Cordova. Triggers on meteor add-platform, android-device, ios-device, mobile-config.js, Cordova plugins, native signing or store artifacts, and mobile hot code push compatibility. Use this skill when the task already concerns Meteor's Cordova app workflow; use meteor-debugging for an unexplained cross-layer failure and meteor-deployment for the backend. React Native/Expo, Capacitor, and native Node.js addons are separate workflows.
migrate-to-rspack
Use when migrating an existing Meteor app to Rspack (Meteor 3.4+), or upgrading Rspack 1 to 2 on Meteor 3.6. Triggers on nested imports, mainModule entry points, server-only apps, replacing fourseven:scss / meteor/less / coffeescript / jorgenvatle:vite / zodern:melte with loaders, Svelte/TypeScript preprocessing or Lingui SWC plugin failures after upgrade, CommonJS default-import interop, module.exports in client graphs, Node built-ins in browser code, _build / build-assets / build-chunks, .meteorignore hiding handoff files, dynamic chunks under ROOT_URL, meteor.modules for CSS/HTML, resolve.symlinks or resolve.alias migration, automatic dependency updates and immutable CI/Docker builds. Use this skill when the user asks about migration compatibility or a build plugin's Rspack replacement. For new-app setup and rspack.config.js helpers, use meteor-modern-build-stack instead.
migrate-to-meteor-3
Use when migrating a Meteor 2.x application to Meteor 3.x. Triggers on callAsync, *Async Mongo, removed Fibers, implicit-global ReferenceError, lost Blaze reactivity, a publish function returning a Promise, a scheduler dropping a Promise, a read API receiving update modifiers, async allow/deny, an Iron Router controller not running, "Method stub took too long", Atmosphere resolution, Express 5 WebApp handlers, lost async context, rawCollection callbacks, TypeScript declaration failures during upgrades, useTracker, and useSubscribe. Use this skill when the user asks about upgrading Meteor, async caller propagation, iterators with await, or replacing and forking packages. Standalone declarations and type-checking belong to meteor-typescript.
meteor-typescript
Use when setting up or repairing Meteor application declarations, TypeScript configuration, JavaScript IntelliSense, or local and CI type-checking. Triggers on meteor types, meteor/* imports resolving to any, missing declarations, duplicate Meteor identifiers, zodern:types, @types/meteor, .meteor/types, tsconfig.json, jsconfig.json, and tsc --noEmit in a Meteor app. Use this skill when choosing or migrating declaration providers without changing the app's runtime or bundler. For a Meteor 2-to-3 runtime migration use migrate-to-meteor-3 first; for SWC/Rspack compilation use meteor-modern-build-stack or migrate-to-rspack. General TypeScript language questions and Atmosphere declaration publishing are outside this app scope.
meteor-security
Use when auditing or hardening a Meteor 3 application. Triggers on missing check() on method arguments, missing this.userId guards on publications, browser-policy CSP, DDPRateLimiter rules, oauth-encryption via Accounts.config oauthSecretKey, audit-argument-checks, allow/deny legacy patterns, BrowserPolicy.content.disallowInlineScripts, BrowserPolicy.framing.disallow. Use this skill when the user asks about hardening, asks about a security review, or asks about CSP for a third-party script (Stripe, Google Maps, fonts).
meteor-react
Use when building or debugging React interfaces in Meteor 3: meteor create --react, createRoot, JSX or TSX entry points, Rspack React detection, Fast Refresh, react-meteor-data, useTracker, useSubscribe, useFind, withTracker, Suspense, and Tracker.withComputation. Triggers on isLoading being treated as a boolean, useFind receiving fetch(), stale closure inputs, duplicate tracker side effects, unstable Suspense keys, lost reactivity after await, state reset after refresh, or React tests leaking computations. Use this skill when the user asks about a React skeleton, React Compiler, React-specific rspack.config rules, reactive data hooks, or classic versus Suspense integration. Route general bundler configuration to meteor-modern-build-stack and Meteor 2 upgrades to migrate-to-meteor-3.