Tutorial Videos
Best Practices
This video by the creator of Cypress Brian Mann shows what we consider the best practices for writing tests for a realistic application.
First we'll test our "Login Page", refactor, and then create a
Custom Command. From there we'll use
cy.request()
to programmatically log in. Finally,
we'll discuss approaches for taking shortcuts by controlling your application's
state directly, and for writing your tests in isolation to prevent specs
from being coupled together or having to share knowledge.
Tutorial | Length | Release date | Cypress version |
---|---|---|---|
Organizing Tests, Logging In, Controlling State | 27:21 | 2.1.0 |
Video playlists
Learn how to use Cypress to solve specific testing problems from the videos in the playlists below.
- Official Cypress.io YouTube Channel
- Cypress.io - end-to-end Testing Framework by Bushra Alam
- Cypress Tips & Tricks by Gleb Bahmutov
- Cypress Component Testing for Svelte by Gleb Bahmutov
- Visually testing React component using open source tools by Gleb Bahmutov
You can also find free Cypress video tutorials on the Courses page.
Test a React Todo App
In this tutorial, we will walk through building a "Todo" application in React while testing it with Cypress. We will look at ways we can use Cypress to not only create a test suite for our application, but help us write our tests and guide feature implementation.
By the end of this tutorial, you will have a feel for what it is like to test your application with Cypress while implementing features. You will gain experience with many of the Cypress commands and see how Cypress can help you build your application while creating a great safety net of tests along the way.
We have a lot of ground to cover, so let's get started!
Contents:
Tutorial | Length | Release date | Cypress version |
---|---|---|---|
1. Project setup | 3:52 | 1.0.2 | |
2. Testing inputs | 7:17 | 1.0.2 | |
3. Form submission and XHRs | 10:21 | 1.0.2 | |
4. Loading data with fixtures | 9:00 | 1.0.2 | |
5. Todo item behavior | 8:19 | 1.0.2 | |
6. Toggling and debugging | 9:05 | 1.0.2 | |
7. Filters and data-driven tests | 11:39 | 1.0.2 | |
8. Full end-to-end tests part 1 | 8:59 | 1.0.2 | |
9. Full end-to-end tests part 2 | 7:04 | 1.0.2 |
1. Project setup
We will start by cloning a starter
repository.
This repo already has the build and server configuration handled. We will take a
look at the project's npm
dependencies and scripts,
then jump right into getting Cypress up and running.
2. Text inputs
We will work through creating our first real test and implementing the feature
under test as we go. We will see how to find and interact with elements on the
page and how to make assertions about their behavior. We will also look into
some best practices like using beforeEach
and defining our application's
baseUrl to remove duplicated code.
3. Form submission and XHRs
We will implement form submission for our todo app, leveraging
cy.server()
and cy.route()
to
stub calls to our API. We will iterate on our test and implementation, focusing
on the application's "happy path" first. Once our form is working, we'll use
another stubbed XHR call to setup a failure scenario and implement the code to
properly display an error message.
4. Loading data with fixtures
We will implement the initial data load for our todo app, leveraging
cy.server()
and cy.route()
to
stub the API call to load our data. We will use
fixture data to seed our application state.
As we iterate on our test and app code, we will create and use a
custom command to avoid unnecessary code
duplication and keep our tests clean and readable.
We will be using this list of todo objects to stub our XHR calls. For convenience, you can copy it from here and paste it in as you follow along.
[
{
"id": 1,
"name": "Buy Milk",
"isComplete": false
},
{
"id": 2,
"name": "Buy Eggs",
"isComplete": false
},
{
"id": 3,
"name": "Buy Bread",
"isComplete": false
},
{
"id": 4,
"name": "Make French Toast",
"isComplete": false
}
]
5. Todo item behavior
We will update our app to properly display todo items based on their
isComplete
property, adding tests to verify the proper behavior as we go. From
there, we'll test and implement the item deletion functionality. We will cover
interacting with an element that is hidden unless hovered over and look at
different ways of handling this situation. We'll also look at the appropriate
way to hold onto references to previously queried DOM elements using
.as()
to create aliases.
6. Toggling and debugging
We will create a test for todo item toggling. As we implement the toggle feature, we will encounter a problem with our code and look at how Cypress can help us debug our code. We will use the Cypress Command Log to narrow down our problem. Then, we can use the Developer Tools right in the Cypress App to step through the code to dig into the issue. We'll even see how we can update application state while debugging and let our test confirm our theory about the cause of the bug. Once the debugging is complete, we will refactor our code to be less error prone, relying on the test to help us get it right.
[Get the completed code for this lesson on GitHub](https://github.com/cypress-io/cypress-tutorial-build-todo/tree/06_toggle_debug)7. Filters and data-driven tests
We will test the application's footer behavior. First, we will ensure that our footer properly displays singular or plural text, based on the number of remaining todos. From there, we will test and implement the list filtering feature. We will create a test for one of the filters and see how to wire up React Router to make our filter links work. We will then look at how we can use standard JavaScript data structures to drive multiple assertions in our test, allowing us to test multiple variations of the filter behavior in a single test.
[Get the completed code for this lesson on GitHub](https://github.com/cypress-io/cypress-tutorial-build-todo/tree/07_data_driven)8. Full end-to-end tests part 1
We will connect our back end API to the front end we've been building. Once we
have the back end API connected, then we will create our first true end-to-end
test. Using the back end API, we will ensure a consistent starting state by
deleting any existing data from the database. Then we will test that our
application can create and save new todos without a stubbed back end. We will
also see how we can listen to and cy.wait()
for XHR
responses in our tests to avoid flake caused by unpredictable response times.
9. Full end-to-end tests part 2
We will continue building on our full end-to-end tests, this time seeding the
database to test our application against a populated database. We will repeat
the pattern of adding cy.wait()
commands to our tests to
ensure our back end has responded before moving on. Once we have tests for
deleting and updating items against a real back end, we will see how to run our
Cypress tests using cypress run
, giving us an ideal setup for running our
tests in a CI environment.