Cypress Tutorial for Beginners: Your First Test in 10 Minutes

July 18, 2025

Imagine the familiar dread: a critical bug slips past manual checks and makes it into production. The frantic scramble to patch, the potential loss of user trust, and the hours spent on damage control could have been prevented. This scenario highlights the non-negotiable need for robust automated testing. For years, however, end-to-end (E2E) testing was often seen as a necessary evil—brittle, slow, and notoriously difficult to set up. This is the landscape that Cypress was built to change. It's a next-generation testing framework designed from the ground up to be developer-friendly, reliable, and incredibly fast. This comprehensive cypress tutorial is your express lane to modern E2E testing. We'll demystify the process, guiding you from zero to a fully functional automated test in the time it takes to drink your morning coffee. Forget complex configurations and flaky selectors; prepare for a testing experience that finally works for you, not against you. According to a report on QA statistics, a significant portion of development time is spent on fixing bugs that could be caught by automation, making efficient testing tools more valuable than ever.

What is Cypress and Why Should You Care?

Before we dive into the practical steps, it's essential to understand what makes Cypress a game-changer in the world of web automation. Cypress is a JavaScript-based end-to-end testing framework built for the modern web. Unlike legacy tools like Selenium, which operate by running remote commands across the network, Cypress executes in the same run loop as your application. This architectural choice is the source of its power.

Think of it this way: Selenium is like a person controlling a robot from another room through a walkie-talkie, leading to delays and potential misinterpretations. Cypress, on the other hand, is like having the test script sitting directly inside the robot's brain, giving it instantaneous, native access to everything happening within the application. This fundamental difference provides a suite of benefits that directly address the historical pain points of E2E testing.

Key Features That Define the Cypress Experience

  • Time Travel & Debuggability: Cypress takes snapshots of your application as your tests run. When a test fails, you can hover over each command in the Command Log to see exactly what the application looked like at that moment. This eliminates guesswork and drastically reduces debugging time. Furthermore, you have full access to developer tools like Chrome DevTools, allowing you to use debugger and console.log statements within your test code. The official Cypress website highlights this as a core philosophy: to make testing a seamless part of the development workflow.
  • Automatic Waiting: One of the most common sources of flaky tests is timing. Traditional frameworks often require you to litter your code with explicit waits (sleep(5000)) to wait for elements to appear or animations to finish. Cypress is smarter. It automatically waits for commands and assertions to resolve before moving on. For instance, when you write cy.get('button').click(), Cypress waits for the button to become visible and actionable before attempting to click it. This feature alone makes tests dramatically more reliable.
  • Network Traffic Control: Modern applications are heavily reliant on API calls. Cypress gives you the power to control, stub, and test network requests and responses on the fly without ever involving your backend server. Using the cy.intercept() command, you can test edge cases like network errors or empty responses, ensuring your front-end handles them gracefully. This capability is crucial for creating truly isolated and fast front-end tests, a concept detailed in many software testing methodology articles.
  • Consistent and Reliable Results: Because Cypress has full control over the application and network, it can deliver consistent, repeatable, and flake-free test results. The ability to control every aspect of the test environment is paramount, a principle echoed by Google's testing philosophy which emphasizes the need for fewer, more reliable E2E tests.

Your First 5 Minutes: Setting Up Your Cypress Environment

One of the most compelling aspects of this cypress tutorial is demonstrating just how quickly you can get started. We're going to set up a new project and install Cypress in a few simple command-line steps. This process is designed to be frictionless, a stark contrast to the often-complex setup required by other testing frameworks.

Prerequisites

Before you begin, ensure you have the following installed on your system:

  • Node.js: Cypress is a Node.js application. You can download the latest LTS version from the official Node.js website. A version of 14.x or higher is generally recommended.
  • A Code Editor: Any text editor will work, but a modern editor like Visual Studio Code is highly recommended for its excellent JavaScript support and integrated terminal.

Once the prerequisites are met, open your terminal or command prompt and follow these steps.

Step 1: Create a Project Directory

First, we need a dedicated folder for our project. Let's create one and navigate into it.

$ mkdir cypress-beginner-tutorial
$ cd cypress-beginner-tutorial

This command creates a new directory named cypress-beginner-tutorial and then changes your current location to be inside that new directory. All subsequent commands will be run from here.

Step 2: Initialize a Node.js Project

Next, we need to initialize our directory as a Node.js project. This is done by creating a package.json file, which will manage our project's dependencies (like Cypress) and scripts. The -y flag simply accepts all the default prompts.

$ npm init -y

After running this, you'll see a new package.json file in your directory. This file is central to the Node.js ecosystem, as explained in the official npm documentation.

Step 3: Install Cypress

Now for the main event: installing Cypress. We'll install it as a development dependency because it's a tool used for building and testing your application, not for running it in production.

$ npm install cypress --save-dev

This command downloads the Cypress package from the npm registry and adds it to the devDependencies section of your package.json file. The installation might take a minute or two as it downloads the Cypress binary for your specific operating system.

Step 4: Open the Cypress App

With Cypress installed, the final step is to open its interactive Test Runner. The recommended way to do this is by using npx.

$ npx cypress open

npx is a package runner tool that comes with npm and allows you to execute package binaries without having to specify the full path. The first time you run this command, Cypress will perform a one-time setup process. It will verify that it can run on your machine and, most importantly, it will scaffold a complete folder structure inside your project. This automatic setup is a key feature that makes getting started so easy. You'll see a new cypress/ directory and a cypress.config.js file appear in your project—we'll explore those next.

Exploring the Cypress Ecosystem: The Test Runner and Project Structure

When you ran npx cypress open, two important things happened: the Cypress Test Runner application launched, and a standard project structure was created for you. Understanding these two components is fundamental to working effectively with Cypress.

The Interactive Test Runner

The window that opens is the Cypress Test Runner. This is your command center for writing, running, and debugging tests. Initially, it will prompt you to choose a testing type. For our purposes, select E2E Testing. Cypress will then confirm its configuration and show you a list of available browsers it has detected on your system (e.g., Chrome, Firefox, Edge). Below that, you'll see a list of 'specs,' which are your test files. Cypress creates some example specs for you to explore, which is a great way to see more advanced patterns in action. When you click on a spec file, Cypress opens the selected browser and begins executing the test, providing a rich, interactive view.

Demystifying the cypress/ Folder Structure

Cypress's scaffolding process creates a clean, organized home for all your testing artifacts. Let's break down the purpose of each key directory and file inside the generated cypress/ folder. This structure is a core part of any good cypress tutorial because it provides a convention-over-configuration approach that simplifies project management.

  • cypress/e2e/: This is where you'll spend most of your time. It's the designated home for all your end-to-end test files (specs). By default, Cypress will look for files with a .cy.js, .cy.ts, .cy.jsx, or .cy.tsx extension inside this directory. The example files Cypress creates live here.

  • cypress/fixtures/: Fixtures are used to store static test data. Instead of hardcoding large JSON objects or HTML snippets directly in your tests, you can place them in a file within this folder (e.g., user.json). You can then load this data in your test using the cy.fixture() command. This practice keeps your tests clean and your data manageable, a best practice supported by resources like the Cypress Real World App, which demonstrates advanced usage patterns.

  • cypress/support/: This folder is for creating reusable behavior. It contains two important files by default:

    • e2e.js: This file runs before every single spec file. It's the perfect place to import global styles or put global configurations. By default, it imports commands.js.
    • commands.js: This is where you define custom Cypress commands. For example, if you frequently log in during your tests, you could create a cy.login() command to encapsulate the steps of visiting the login page, filling in credentials, and clicking the submit button. This is a powerful feature for keeping your tests DRY (Don't Repeat Yourself).
  • cypress.config.js: This file, located in your project's root directory, is the heart of your Cypress configuration. Here, you can define global settings like a baseUrl (so you don't have to type the full URL in every cy.visit()), set default timeouts, configure viewport sizes, and much more. The official Cypress configuration documentation is an exhaustive resource for all available options. A well-configured project is a maintainable one, a principle that is universally applicable in software development as noted by industry leaders like Atlassian.

The Main Event: Writing and Running Your First Cypress Test

We've laid the groundwork, and now it's time for the payoff. In the next few minutes, we will create a brand new test file from scratch, write commands to interact with a live website, make an assertion to verify its behavior, and watch it run in the Test Runner. This is the core of our cypress tutorial.

Step 1: Create Your Spec File

Navigate to the cypress/e2e/ directory in your code editor. Delete the example files that Cypress created for now, so we can focus on our own. Create a new file named my-first-test.cy.js. The .cy.js suffix is the modern convention that Cypress uses to identify a file as a test spec.

Step 2: The Test Structure (Mocha Syntax)

Cypress adopted the test structure from Mocha, a popular JavaScript test framework. This provides a simple, readable way to organize your tests using describe() and it() blocks.

  • describe(name, function): This is a suite that groups together related tests. You can think of it as a chapter in your testing book.
  • it(name, function): This is an individual test case. It contains the actual test steps and assertions.

Let's add this basic structure to our my-first-test.cy.js file:

describe('My First Test Suite', () => {
  it('should perform a basic interaction and assertion', () => {
    // Our test commands will go here!
  })
})

This structure is highly readable and helps communicate the intent of your tests, a key principle of Behavior-Driven Development (BDD) which has influenced many modern testing tools, as discussed in communities like the Stack Overflow blog.

Step 3: Writing Cypress Commands

All Cypress commands are chained off the global cy object. Commands are asynchronous and are queued for execution. Let's write a simple test that visits a page, finds an input field, types into it, and verifies that the input contains the typed text. We will use the excellent example application provided by Cypress.

  • cy.visit(): Navigates the browser to a specific URL.
  • cy.get(): Selects one or more DOM elements using a CSS selector.
  • .type(): Types characters into a selected DOM element.
  • .should(): Creates an assertion. Assertions are how you verify that your application is in the correct state.

Let's put it all together. Update your it block with the following code:

describe('My First Test Suite', () => {
  it('should perform a basic interaction and assertion', () => {
    // 1. Visit the page
    cy.visit('https://example.cypress.io/commands/actions')

    // 2. Find the email input field, type into it
    cy.get('.action-email').type('[email protected]')

    // 3. Assert that the input field now contains the typed text
    cy.get('.action-email').should('have.value', '[email protected]')
  })
})

Notice the clear, chainable syntax. It reads almost like plain English. The power of .should() comes from the extensive library of assertions (built on Chai) it supports, allowing you to check for visibility, CSS properties, text content, and more. You can find a full list in the Cypress assertions documentation.

Step 4: Run Your Test and See the Magic

Save the my-first-test.cy.js file. If your Cypress Test Runner is still open, it will automatically detect the new file and display it in the list of specs. If not, open it again with npx cypress open.

Click on my-first-test.cy.js.

Cypress will launch a browser and execute your test. On the left, you'll see the Command Log, which shows each command (VISIT, GET, TYPE, ASSERT) as it executes. On the right, you'll see your application. The test will run very quickly, and if all goes well, you'll see a green checkmark next to your it block.

This is the moment of truth. You have successfully written and executed your first automated end-to-end test. Congratulations! You can now click on any step in the Command Log to see a DOM snapshot of the application at that precise moment, demonstrating the powerful time-travel debugging feature we discussed earlier.

What's Next? Best Practices for Your Cypress Journey

You've successfully completed the 'hello world' of E2E testing with Cypress. This is a fantastic start, but it's just the beginning. To transition from writing a single test to building a robust and maintainable test suite, it's crucial to adopt some best practices from the outset.

Core Best Practices to Adopt Now

  • *Use `data-Attributes for Selectors:** It's tempting to use CSS classes or IDs to select elements (like we did with.action-email). However, these are often subject to change for styling or JavaScript purposes, which can break your tests. A more resilient strategy is to add dedicated test attributes to your elements, likedata-cy="email-input". Your test would then usecy.get('[data-cy=email-input]')`. This decouples your tests from your styling and implementation details. This practice is strongly recommended by the official Cypress best practices guide.
  • Avoid cy.wait(number): While Cypress provides cy.wait() for arbitrary waits, using it to pause for a fixed amount of time is an anti-pattern. It leads to tests that are either too slow (waiting longer than necessary) or flaky (not waiting long enough). Instead, rely on Cypress's built-in automatic waiting and assertions. If you need to wait for a network call, use cy.intercept() to wait for a specific API response.
  • Keep Tests Independent: Each it() block should be able to run independently and in any order. Avoid writing tests that depend on the state created by a previous test. Use beforeEach() or before() hooks to set up the necessary state (like logging in or seeding a database) for each test or test suite. This ensures your test suite is reliable and easy to debug. The concept of test isolation is a cornerstone of effective automated testing, as detailed in many software engineering blogs.

Your Path Forward

With these best practices in mind, here are some areas to explore as you continue your Cypress journey:

  • Network Mocking: Dive deep into cy.intercept(). Learn how to stub API responses to test how your UI behaves in different scenarios (e.g., loading states, error messages).
  • Custom Commands: As your tests grow, identify repetitive actions and abstract them into custom commands in cypress/support/commands.js to keep your tests clean and readable.
  • CI/CD Integration: Learn how to run your Cypress tests headlessly from the command line using npx cypress run. This is the key to integrating your tests into a Continuous Integration/Continuous Deployment (CI/CD) pipeline, enabling you to run your entire test suite automatically every time new code is pushed. Tools like the Cypress Dashboard can further enhance this by providing video recordings and detailed analytics of your test runs.

In just a short time, you have journeyed from a blank project directory to a fully operational end-to-end test. You've installed Cypress, navigated its Test Runner, understood its project structure, and authored a test that interacts with a real web application. This cypress tutorial was designed to prove one thing: modern E2E testing doesn't have to be a chore. With its developer-centric design, intuitive API, and powerful debugging tools, Cypress empowers you to build a reliable quality assurance safety net with confidence and speed. The passing test you just witnessed is more than just a green checkmark; it's your first step towards shipping more resilient applications, catching bugs before your users do, and ultimately, becoming a more effective developer. Continue to explore, build on these fundamentals, and embrace the confidence that comes with a well-tested codebase.

What today's top teams are saying about Momentic:

"Momentic makes it 3x faster for our team to write and maintain end to end tests."

- Alex, CTO, GPTZero

"Works for us in prod, super great UX, and incredible velocity and delivery."

- Aditya, CTO, Best Parents

"…it was done running in 14 min, without me needing to do a thing during that time."

- Mike, Eng Manager, Runway

Increase velocity with reliable AI testing.

Run stable, dev-owned tests on every push. No QA bottlenecks.

Ship it

FAQs

Momentic tests are much more reliable than Playwright or Cypress tests because they are not affected by changes in the DOM.

Our customers often build their first tests within five minutes. It's very easy to build tests using the low-code editor. You can also record your actions and turn them into a fully working automated test.

Not even a little bit. As long as you can clearly describe what you want to test, Momentic can get it done.

Yes. You can use Momentic's CLI to run tests anywhere. We support any CI provider that can run Node.js.

Mobile and desktop support is on our roadmap, but we don't have a specific release date yet.

We currently support Chromium and Chrome browsers for tests. Safari and Firefox support is on our roadmap, but we don't have a specific release date yet.

© 2025 Momentic, Inc.
All rights reserved.