lpm test
Run project tests with Vitest, Jest, Mocha, or a package script, including selected workspace members.
Use lpm test to run the test runner declared by your project.
lpm test [OPTIONS] [ARGS]...Quickstart
lpm install -D vitest
lpm test
lpm test -- --watch| Mode | Command |
|---|---|
| Run the current package | lpm test |
| Run every workspace member | lpm test --all |
| Run selected members | lpm test --filter web |
| Run affected members | lpm test --affected --base main |
| Get a JSON result | lpm --json test |
Runner selection
LPM CLI reads dependencies and devDependencies in the package manifest.
It checks these runners in order:
- Vitest:
vitest run. - Jest:
jest. - Mocha:
mocha. - The
testscript inpackage.json.
A declared runner takes priority over the package script. If the selected runner has no installed executable, run lpm install. Detection does not download a runner automatically.
To select the package script directly, use lpm run test.
The dedicated test command does not use task commands, task caching, or task dependencies from lpm.json.
Project configuration
lpm.json has no dedicated test section.
Runtime pins and project environment configuration still apply.
{
"runtime": {
"node": "22"
},
"env": {
"test": ".env.test"
}
}tasks.test.env selects the environment for detected test runners and package scripts first.
If that field is absent, env.test selects the environment file.
A task environment can apply even though tasks.test.command does not replace the package script.
The script also uses its pretest and posttest hooks and npm lifecycle variables.
A failed hook stops the later phases.
Forwarded arguments apply to the main script.
Both execution paths load the project environment and enforce its environment schema.
The command has no dedicated --env option.
See environment files and lpm run for named script environments.
LPM CLI prepares configured Node and Bun versions before the test run.
Workspace members inherit root runtime pins and can override each runtime locally.
It checks engines.node against the Node executable on the test PATH.
A strict engine mismatch stops the run.
If a configured runtime cannot be installed, LPM CLI warns and uses the first matching executable on PATH. Use lpm use to install the required version. See managed runtimes for runtime selection and automatic downloads.
Coverage and CI
lpm install -D vitest @vitest/coverage-v8
lpm test -- --coverage
lpm --json test --allVitest runs once by default. Jest and Mocha receive their arguments directly. A package script controls its own test behavior. For CI, use a script that exits after its test run.
Put runner options after -- to keep them separate from LPM CLI options.
For example, Jest's --all belongs after the delimiter:
lpm test -- --all
lpm test --filter web -- --reporter=verboseWatch mode
lpm test -- --watch
lpm test --filter web -- --watchFor Vitest watch mode, LPM CLI removes the default run argument.
Jest and Mocha receive their watch options directly.
Jest's -w <N> sets its worker count. It does not request watch mode.
A workspace selection can watch exactly one member.
LPM CLI rejects a watch request that selects no members or multiple members.
Jest's --watchAll also requests watch mode.
Vitest short-option bundles such as -uw also request watch mode.
Tokens after a second -- belong to the runner and do not select watch mode.
On Unix, Ctrl+C or a stop signal stops active runners and their tracked descendants. A daemon that detaches and outlives its parent manages its own shutdown. LPM CLI gives child cleanup handlers time to run before it forces termination. A stopped run does not start later hooks.
For disabled Vitest watch mode, use --watch=false.
Values such as --watch=off and --watch=0 enable watch mode in Vitest.
Workspace selection
lpm test --all
lpm test --filter '@scope/*'
lpm test --filter './apps/*'
lpm test --filter web --filter api
lpm test --filter-prod ...shared
lpm test --affected --base origin/main
lpm test --filter web --fail-if-no-match
lpm test --all --workspace-concurrency 2Detection runs separately for each selected member. A workspace can use different runners in different members. The command reports a missing runner as a member failure.
--all cannot combine with filters or --affected.
Filters and --affected combine as a union.
--filter-prod excludes development edges from dependency closures.
Members run in dependency order. Independent members can run together.
A failed member does not stop the remaining selected members.
--workspace-concurrency limits the number of selected members that run at once.
The limit uses the CLI flag, then root lpm.toml [workspace].concurrency, then global workspace-concurrency, then available parallelism.
This limit does not control each runner's internal workers.
See workspace filters.
JSON output and failures
lpm --json test
lpm --json test --filter webBoth single-package and workspace runs emit one JSON result. The result includes each member's status. Failed members include captured output or a launch error. Successful members do not include their captured output.
A single-package run preserves the runner or hook exit code.
If any selected member fails, a workspace run exits with status 1.
Each failed member retains its own exit code.
On Unix, interrupted runs exit with 130 for SIGINT or 143 for SIGTERM.
A launch or configuration failure has exit_code: null and an error message.
Failures before member preparation use the global error object.
Captured output has a 10 MiB limit per stream.
JSON mode closes stdin and emits its result after completion.
If a child leaves output pipes open, LPM CLI bounds the final drain and cleans up the owned process groups. Background services from a package pre-hook remain available through the main script and post-hook. In JSON mode, cleanup occurs after the script sequence.
Flags
| Flag | Effect |
|---|---|
--all | Select every workspace member |
--filter <FILTER> | Select members with the workspace filter grammar. Repeat to combine selections |
--filter-prod <FILTER_PROD> | Select members with production dependency closures |
--affected | Select members affected by Git changes |
--base <BASE> | Set the Git base for --affected. Default: main |
--changed-files-ignore-pattern <CHANGED_FILES_IGNORE_PATTERN> | Ignore matching changed paths during Git-based selection |
--test-pattern <TEST_PATTERN> | Treat matching changed paths as test-only during affected selection |
--fail-if-no-match | If no workspace member matches, fail |
--workspace-concurrency <N> | Limit concurrent workspace members |
Runner flags belong after --.
See global flags.
See also
- lpm run — package scripts and configured tasks
- lpm bench — benchmark runners
- Test and bench runners — shared runner behavior
- Workspaces — dependency graphs and selection