Create Test Server
create-test-server is a utility that creates a minimal Express.js server for robust HTTP and HTTPS testing, operating on randomly chosen ports. It automatically generates self-signed SSL certificates with an associated CA certificate, enabling authenticated SSL requests in test environments. Currently at version 3.0.1, its release cadence follows semantic versioning, with major versions indicating breaking changes. A key differentiator is its approach to testing: instead of fragile HTTP mocking that can break across Node.js versions (e.g., Nock), it advocates for testing against a real, locally running server. It handles JSON, plain text, URL-encoded forms, and buffer bodies by default, making it versatile for various API testing scenarios. The library provides a Promise-based API that integrates seamlessly with modern asynchronous test runners like AVA.
Common errors
-
TypeError: server.get is not a function
cause Attempting to call methods on the `server` object before the `createTestServer()` Promise has resolved, meaning `server` is still a Promise, not the resolved server object.fixEnsure `createTestServer()` is `await`ed. Example: `const server = await createTestServer(); server.get('/foo', 'bar');` -
Error: self-signed certificate in certificate chain
cause An HTTP client (like `got`) is trying to make an HTTPS request to the test server but does not trust the auto-generated self-signed certificate, rejecting the connection.fixWhen making HTTPS requests, either provide the `server.caCert` to your client and set the `Host` header to match the server's certificate common name, or disable SSL certificate validation in the client (e.g., `rejectUnauthorized: false` for `got`). -
ERR_REQUIRE_ESM
cause Attempting to use `require()` to import `create-test-server` in an environment configured for ESM (e.g., `"type": "module"` in `package.json`), or trying to `import` it with named imports in ESM.fixIf in ESM, use `import createTestServer from 'create-test-server';`. If in CommonJS, use `const createTestServer = require('create-test-server');`. Ensure your project's module system configuration aligns with your import statements.
Warnings
- breaking Direct access to internal Express application instance or raw HTTP/HTTPS server properties was removed or changed to private in a prior major version for API stability. Rely only on the documented `server` object methods and properties (e.g., `server.get`, `server.url`).
- gotcha When making HTTPS requests to `create-test-server`, clients like `got` will by default reject self-signed certificates. This requires specific client configuration to either trust the generated CA certificate or explicitly bypass certificate validation.
- gotcha Ports for HTTP and HTTPS are chosen randomly by default upon each server instantiation. Relying on fixed ports for testing will lead to conflicts or failures.
- gotcha The `createTestServer()` function returns a Promise. Forgetting to `await` its resolution will lead to errors as you try to access properties (`.url`, `.get`, etc.) on an unresolved Promise.
Install
-
npm install create-test-server -
yarn add create-test-server -
pnpm add create-test-server
Imports
- createTestServer (ESM Default)
import { createTestServer } from 'create-test-server';import createTestServer from 'create-test-server';
- createTestServer (CommonJS Direct)
const { createTestServer } = require('create-test-server');const createTestServer = require('create-test-server'); - TestServer (Interface)
import { TestServer } from 'create-test-server';import type { TestServer } from 'create-test-server';
Quickstart
import test from 'ava';
import got from 'got';
import createTestServer from 'create-test-server';
test('should respond to a basic GET request with text', async t => {
const server = await createTestServer();
server.get('/hello', 'world');
const response = await got(`${server.url}/hello`);
t.is(response.body, 'world');
await server.close();
});
test('should handle POST requests with JSON body', async t => {
const server = await createTestServer();
server.post('/data', (req, res) => {
res.json({ received: req.body });
});
const testData = { message: 'hello from client' };
const response = await got.post(`${server.url}/data`, {
json: testData,
responseType: 'json'
});
t.deepEqual(response.body, { received: testData });
await server.close();
});