# Testing signals — expressjs/express

> Canonical page: https://codevetter.com/unpack/express/testing-signals

# Testing signals — expressjs/express

Scanned commit 9a34acf03cb818ff3f8bc40e44176e277a25cbb9 (2026-09-15). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

Testing is mocha + supertest with `after` for multi-assertion coordination, and it is unusually thorough for a codebase this size: 70 unit files under `test/` plus 18 acceptance files under `test/acceptance/`, totalling ~15,400 lines against ~5,500 lines of `lib/`. Unit files are named one-per-API (`res.send.js`, `req.host.js`, `app.param.js`), which makes the mapping from source method to test file mechanical. Acceptance tests do not use fixtures — they `require('../../examples/<name>')` and drive the real example apps, so `examples/` is effectively production test surface. Coverage runs through nyc in CI across the whole matrix, is merged with lcov and shipped to Coveralls.
- The runner is mocha with `--require test/support/env --check-leaks`, covering both `test/` and `test/acceptance/`; `--check-leaks` means any accidental global assignment fails the suite. — [package.json#L103](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/package.json#L103) [test/support/env.js](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/test/support/env.js)
- `test/support/env.js` forces `NODE_ENV=test` (which suppresses `logerror` output and keeps `view cache` disabled) and sets `NO_DEPRECATION=body-parser,express` to silence `depd` warnings. — [test/support/env.js](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/test/support/env.js) [lib/application.js#L615-L617](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/lib/application.js#L615-L617) [lib/application.js#L143-L145](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/lib/application.js#L143-L145)
- HTTP assertions run through `supertest` against the app function directly, without binding a port — e.g. `request(app).get('/').expect(200, done)`. — [test/exports.js#L59-L70](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/test/exports.js#L59-L70) [test/middleware.basic.js#L36-L42](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/test/middleware.basic.js#L36-L42) [package.json#L73](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/package.json#L73)
- `test/support/utils.js` provides the shared assertion vocabulary: `shouldHaveBody`, `shouldHaveHeader`, `shouldNotHaveBody`, `shouldNotHaveHeader`, `shouldSkipQuery` — with body comparison done on hex-encoded buffers. — [test/support/utils.js#L17-L40](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/test/support/utils.js#L17-L40)
- `test/support/tmpl.js` is a hand-rolled `$var.path` template engine used as the canonical view-engine double, avoiding a real engine dependency in most view tests. — [test/support/tmpl.js](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/test/support/tmpl.js) [test/app.render.js](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/test/app.render.js)
- The largest test files track the riskiest code: `app.router.js` (1217 lines), `res.sendFile.js` (913), `express.urlencoded.js` (828), `express.static.js` (815), `express.json.js` (755), `Router.js` (636), `res.send.js` (635). — [test/app.router.js](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/test/app.router.js) [test/res.sendFile.js](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/test/res.sendFile.js) [test/express.static.js](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/test/express.static.js) [test/res.send.js](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/test/res.send.js)
- Path-traversal behaviour is explicitly covered: `express.static.js` asserts handling of `/users/../todo.txt`, `/users/../../todo.txt` and the URL-encoded `/users/%2e%2e/%2e%2e/todo.txt`, and `res.sendFile.js` covers `fake/../name.txt` and `../name.txt` under a `root`. — [test/express.static.js#L83-L88](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/test/express.static.js#L83-L88) [test/express.static.js#L580-L590](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/test/express.static.js#L580-L590) [test/res.sendFile.js#L864-L900](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/test/res.sendFile.js#L864-L900)
- All 18 acceptance files import example apps rather than fixtures — `test/acceptance/auth.js` requires `../../examples/auth` and drives the full login/session/restricted flow including cookie extraction. — [test/acceptance/auth.js#L1-L10](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/test/acceptance/auth.js#L1-L10) [examples/auth/index.js](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/examples/auth/index.js)
- Seven of the 26 examples have no acceptance test: `online`, `route-middleware`, `search`, `session`, `static-files`, `view-constructor`, `view-locals` — leaving the custom-`View`-constructor extension point exercised only by the example itself. — [examples/README.md#L5-L28](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/examples/README.md#L5-L28) [test/acceptance/route-map.js](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/test/acceptance/route-map.js) [examples/view-constructor/index.js](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/examples/view-constructor/index.js)
- `test/exports.js` deliberately mutates `express.application`, `express.request` and `express.response` prototypes to prove the extension contract holds — meaning test ordering has real cross-file coupling. — [test/exports.js#L52-L70](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/test/exports.js#L52-L70)
- `test/regression.js` is a deliberately tiny guard file — currently one case asserting that throwing after `res.end()` still yields a clean 200 response. — [test/regression.js#L6-L20](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/test/regression.js#L6-L20)
- Coverage is produced per matrix cell (`npm run test-ci` → nyc lcovonly), uploaded as `coverage-node-<ver>-<os>` artifacts, then merged in a dedicated `coverage` job with `lcov -a` and pushed to Coveralls. — [.github/workflows/ci.yml#L74-L116](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/.github/workflows/ci.yml#L74-L116) [package.json#L104](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/package.json#L104)
- nyc excludes `examples`, `test` and `benchmarks` from instrumentation, so the acceptance tests contribute coverage for `lib/` only — and the `benchmarks` exclude refers to a directory that no longer exists in the tree. — [package.json#L104-L105](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/package.json#L104-L105)
- CodeQL scans `javascript` and `actions` on push/PR to master plus a weekly cron, with `paths-ignore: test`; OpenSSF Scorecard runs weekly and on branch-protection changes, publishing SARIF to code scanning. — [.github/workflows/codeql.yml#L15-L54](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/.github/workflows/codeql.yml#L15-L54) [.github/workflows/scorecard.yml#L6-L74](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/.github/workflows/scorecard.yml#L6-L74)
- Explicit `/* istanbul ignore next */` pragmas mark knowingly-uncovered branches, including `logerror`'s console path and the `stringify` escape default case. — [lib/application.js#L614-L616](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/lib/application.js#L614-L616) [lib/response.js#L1043-L1045](https://github.com/expressjs/express/blob/9a34acf03cb818ff3f8bc40e44176e277a25cbb9/lib/response.js#L1043-L1045)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
