Testing
Test commands
Run the full default test suite (TypeScript typecheck + all unit tests):
npm testThis is equivalent to:
npx tsc --noEmit
node ./scripts/run-tests.mjsRun unit tests explicitly (same behavior as npm test):
npm run test:unitRun smoke tests (requires a real environment — see Smoke tests):
npm run test:smokeBuild the CLI (used for build verification and before running smoke tests):
bun run buildLocal dry run (no WeChat account or credentials needed):
bun run dry-run --chat-key wx:test -- "/status"Pass multiple commands to simulate a conversation sequence:
bun run dry-run --chat-key wx:test -- "/session new demo --agent codex --ws backend" "/status"Unit tests
Unit tests live in tests/unit/ and mirror the src/ directory structure. They are:
- Stable and repeatable
- Free of external environment dependencies (no real
acpx, no real WeChat login, no network) - Run by both
npm testandnpm run test:unit
Test files follow the *.test.ts naming convention.
npm test runs the TypeScript typecheck (npx tsc --noEmit) before the tests. If typecheck fails, the tests do not run.
Rules for new unit tests:
- Place new tests in
tests/unit/, mirroring thesrc/subdirectory of the code under test. - Name test files
*.test.ts. - Do not place temporary debugging scripts in the repository root.
- Do not put real-environment tests into the unit test suite.
Smoke tests
Smoke tests live in tests/smoke/ and are not part of the default npm test run. They verify real-environment behavior and may require:
- A real
acpxsession - A real bridge subprocess
- A real WeChat login flow or live chat channel
- External network access, local agent runtime, or QR code scanning
Run smoke tests separately when you have the required environment set up:
npm run test:smokeDo not include smoke tests in the default suite. Environment differences between machines and CI runners make them unsuitable for automatic gating.
Local dry runs
The dry-run mode simulates a chat conversation without any external credentials. It is the fastest way to verify command routing, session state logic, and response formatting during development:
bun run dry-run --chat-key wx:test -- "/status"
bun run dry-run --chat-key wx:test -- "/session new demo --agent codex --ws backend" "/status"Each string after -- is sent as a separate chat message in sequence. The --chat-key wx:test flag identifies the simulated chat context.
Test layout
tests/
unit/ Default test suite; mirrors src/ structure
integration/ Reserved for cross-module tests (not yet enforced)
smoke/ Real-environment tests; not in default run
helpers/ Shared test utilities, fixture builders, and test-only tools
scripts/
run-tests.mjs Test runner invoked by npm test
src/ Production code only — no test files heretests/integration/ is reserved for tests that clearly depend on multiple modules cooperating across boundaries and that are not appropriate for tests/unit/. It is not currently enforced.
tests/helpers/ holds shared utilities and fixture builders. Small helpers may be inlined in a single test file; extract to tests/helpers/ when reuse across multiple files becomes apparent.
When adding a new test type in the future, add a subdirectory under tests/ rather than placing test files back in src/.