expressjs/express
Testing
Active contributors: ulisesgascon, jonchurch, wesleytodd
Express's test suite is its safety net for a large ecosystem of consumers. It is comprehensive (~91 test files for ~6 source files) and runs on every pull request across eight Node versions.
Test stack
| Tool | Role |
|---|---|
mocha |
Test runner. Configured via package.json scripts and test/support/env. |
supertest |
HTTP assertion helper. Wraps request(app) to make assertions against a live app. |
nyc |
Coverage. Used in npm run test-ci and npm run test-cov. |
after, morgan, cookie-parser, cookie-session, connect-redis, express-session, method-override, vhost, pbkdf2-password, ejs, hbs, marked |
Used in fixtures and in the examples/ acceptance tests. |
Layout
test/
├── support/
│ └── env # Mocha --require: sets up env vars (e.g. NO_DEPRECATION)
├── fixtures/ # Static files used by tests (views, downloads, error pages, ...)
├── acceptance/ # Higher-level tests that run the bundled examples
├── Route.js
├── Router.js
├── app.*.js # One file per app.* method (app.use, app.param, app.render, ...)
├── req.*.js # One file per req helper (req.accepts, req.is, req.host, ...)
├── res.*.js # One file per res helper (res.send, res.json, res.cookie, ...)
├── express.json.js
├── express.urlencoded.js
├── express.text.js
├── express.raw.js
├── express.static.js
├── config.js
├── exports.js
├── middleware.basic.js
├── regression.js
└── utils.jsThe naming convention is strict: a method or helper named foo.bar lives in lib/foo.js and has tests in test/foo.bar.js.
Running tests
| Command | Effect |
|---|---|
npm test |
mocha --require test/support/env --reporter spec --check-leaks test/ test/acceptance/ |
npm run test-ci |
Same as above but wrapped in nyc to produce lcov.info. |
npm run test-cov |
nyc HTML report at ./coverage/index.html. |
npm run test-tap |
Mocha with TAP reporter — handy for piping into other tools. |
npx mocha test/res.send.js |
Run a single file (skips test/support/env unless added with --require). |
npx mocha --grep "should support" |
Filter by test name. |
--check-leaks is intentional: Express historically had global-leak bugs and the suite enforces a clean global state.
Common test pattern
A typical file uses supertest to fire HTTP requests at a small ad-hoc app:
var express = require('..');
var request = require('supertest');
describe('res.send(body)', function () {
it('should send a string', function (done) {
var app = express();
app.use(function (req, res) {
res.send('hello');
});
request(app).get('/').expect(200, 'hello', done);
});
});This pattern dominates the suite. Tests prefer constructing a fresh app per it() so behaviours are isolated.
Acceptance tests
test/acceptance/ runs the bundled examples to ensure they continue to work end-to-end. The npm test command includes this directory automatically. New examples should ship with an acceptance test verifying they at least boot and respond to a representative request.
Fixtures
test/fixtures/ contains:
views/— Jade/EJS/HBS template files for view-rendering tests.name.txt,name.dir/— files forres.sendFile/res.downloadtests.- Sub-folders for specific test scenarios.
Conventions
- Use
var(the codebase is ES5-style with a few targeted modern features). New code should match the surrounding file. - Use
done(err)callbacks rather than promises in tests, to match the existing style. - Prefer
request(app).expect(...)over building the assertion by hand. - Keep one behaviour per
it()— most tests are a few lines.
CI behaviour
CI runs npm run test-ci against the matrix in .github/workflows/ci.yml. The workflow uploads lcov.info artifacts per matrix cell, then merges them with lcov and posts the result to Coveralls.
Related pages
- Development workflow — how a change goes from local edit to merged PR.
- Patterns and conventions — code style rules enforced by ESLint.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.