Does Express Work With Cypress?
Express and Cypress work together seamlessly—use Express as your test server and Cypress as your end-to-end testing framework.
Quick Facts
How Express Works With Cypress
Express and Cypress are a natural pairing for full-stack JavaScript testing. You'll typically run an Express server (often with a test database) in your test environment, then point Cypress at `localhost:PORT` to test your application's UI and API interactions. Cypress handles all the E2E testing while Express serves your application. The developer experience is smooth: you start your Express server in one terminal, run Cypress in another, and get instant feedback with Cypress's time-travel debugger showing you exactly what happened at each step. Many teams use this combo with a dedicated test database seeded before each test run. The architecture is straightforward—no special integration code needed. Express doesn't need to know about Cypress; Cypress just makes HTTP requests to your running Express server like any other client would. You can also use Cypress's `cy.task()` feature to communicate directly with your test server for database resets or advanced setup, though this requires a custom plugin.
Best Use Cases
Quick Setup
npm install express cypress --save-dev// server.js - Your Express app
const express = require('express');
const app = express();
app.use(express.json());
app.get('/', (req, res) => res.json({ message: 'Hello' }));
let server;
if (require.main === module) {
server = app.listen(3000, () => console.log('Listening on 3000'));
}
module.exports = app;
// cypress/e2e/app.cy.js
describe('Express App', () => {
before(() => {
cy.visit('http://localhost:3000');
});
it('loads the homepage', () => {
cy.contains('Hello').should('exist');
});
});
// package.json scripts
"scripts": {
"start": "node server.js",
"test:e2e": "cypress open"
}
// Run: npm start (in one terminal), then npm run test:e2eKnown Issues & Gotchas
Port conflicts if your dev server and test server both run on the same port
Fix: Use different ports for development and testing, or run Express on a random available port during tests using `server.listen(0, ...)`
Database state leaking between tests if not properly reset
Fix: Use Cypress hooks (beforeEach/afterEach) with `cy.task()` to reset your test database, or use database transactions that rollback after each test
Timing issues where Cypress tries to hit the server before it's fully started
Fix: Use `cy.visit()` with retries enabled, or implement a health check endpoint that Cypress polls before running tests
CORS errors when Cypress runs on a different origin than your Express server
Fix: Configure Express with `cors` middleware to allow requests from `localhost:3000` (or your Cypress port) during testing
Alternatives
- •Next.js with Cypress—uses Express under the hood with built-in dev server, cleaner for fullstack apps
- •Django/Flask with Selenium—Python-based alternative if you prefer backend in Python
- •NestJS with Cypress—more structured Express alternative with better TypeScript support
Resources
Related Compatibility Guides
Explore more compatibility guides