Cypress.io in a React App in Under 5 Minutes
How to install Cypress, write your first test, test UI interactions, and verify mobile layouts — all in a React app you can clone and run today.
John Ryan Cottam
2 min read
Cypress.io in a React App in Under 5 Minutes
Tests catch problems before users do. That’s it. That’s the pitch.
Cypress makes end-to-end testing approachable in a way that most tools don’t. It runs in the same event loop as your app, so you get native access to every object, every network request, every DOM event. No Selenium. No WebDriver. No server to spin up separately.
A few things that stand out:
- Ships with Mocha, Chai, Sinon, jQuery, Moment, and Bluebird — no extra installs
- Runs tests in a real browser with a live UI you can watch
- Records screenshots and video automatically
- Works with React, Vue, Angular, Express — anything that runs in a browser
- Tests are just JavaScript
Setup
Clone the starter React app:
git clone git@github.com:jcottam/blog.git
cd cypress-io-react
npm install
npm start
Verify it’s running at http://localhost:3000/, then install Cypress:
npm install cypress --save-dev
Add the open script to package.json:
"scripts": {
"cypress:open": "cypress open"
}
Launch the test runner:
npm run cypress:open
Cypress will open its Test Runner UI and scaffold a set of example tests. Run a few to see it in action.
Your first test
Create a new file in /cypress/integration — call it simple_spec.js. Click the filename in the Cypress UI and a browser window opens and runs it in real time.
Testing the application UI
Add a test that visits your app and checks that content loads:
describe('App', function() {
it('loads the homepage', function() {
cy.visit('/')
cy.contains('Movies')
})
})
Run it. It’ll fail — because Cypress doesn’t know where your app lives yet.
Add a cypress.json at the project root:
{
"baseUrl": "http://localhost:3000"
}
Start your React app in one terminal, Cypress in another:
npm start # terminal 1
npm run cypress:open # terminal 2
All green.
Interactivity tests
When a user clicks a movie poster, the title and release date should appear in the header. Write a test to lock that behavior in:
it('Click Movie, Expect Title', function() {
cy.get('[data-cy=movie-3]').click()
cy.get('[data-cy=selected-movie] .title').contains('Gone Girl')
})
it('Click Movie, Expect Release Date', function() {
cy.get('[data-cy=movie-6]').click()
cy.get('[data-cy=selected-movie] .release-date').contains('01 Oct 1993')
})
cy.get() selects by data-cy attribute — a cleaner selector than class names that tend to change. Click, assert, done.
Mobile test
Responsive design is a requirement, not a feature. Test it:
it('renders correctly on mobile', function() {
cy.viewport('iphone-6')
cy.visit('/')
cy.get('.movie-grid').should('be.visible')
cy.screenshot()
})
The screenshot lands in cypress/screenshots/ — useful evidence for QA sign-off.
One thing worth remembering
Retrofitting tests onto a finished app is painful. Writing tests as you build is not. Cypress makes TDD fast enough that there’s no reason to skip it.
Project files are on GitHub. Docs are at docs.cypress.io.