Test Independence Done Right: How to write truly isolated tests!

Overview One of the MOST important rules in automation is having independent tests. This means tests should not rely on each other and you should be able to run any test from any suite at any time. In this blog post, I am sharing some proven practices I've picked up over a decade in test automation. Cypress is used for the demos, but the concepts apply to any test automation stack. Special thanks to @Sebastian Clavijo Suero for his great feedback and suggestions! ⚠️ Disclaimer: The techniques and practices shared in this article are based on real-world experience across multiple projects and teams. While they’ve worked well for me and many others, they’re not the only way to approach test isolation, and I’m not claiming these are the best approaches. There may be different valid solutions depending on your tech stack or infrastructure. The Problem Let’s look at an example of a simple API CRUD (Create, Read, Update, and Delete) test for a project entity in a sample application. Here are the available requests for its endpoint. POST /project > Create a new project GET /project/:id > Returns all projects PUT /project/:id > Update the project with projectId DELETE /project/:id > Delete the project with projectId You might write something like this: describe('CRUD Tests for /project', () => { let project; it('Should create a project', () => { cy.request('POST', '/project', { name: 'An Awesome Project' }) .then((res) => { project = res.body; }); }); it('Should read a project', () => { cy.request('GET', `/project/${project.id}`).its('body.name') // assumes a project already exists

May 3, 2025 - 17:11
 0
Test Independence Done Right: How to write truly isolated tests!

Overview

One of the MOST important rules in automation is having independent tests. This means tests should not rely on each other and you should be able to run any test from any suite at any time.

In this blog post, I am sharing some proven practices I've picked up over a decade in test automation. Cypress is used for the demos, but the concepts apply to any test automation stack.

Special thanks to @Sebastian Clavijo Suero for his great feedback and suggestions!

⚠️ Disclaimer: The techniques and practices shared in this article are based on real-world experience across multiple projects and teams. While they’ve worked well for me and many others, they’re not the only way to approach test isolation, and I’m not claiming these are the best approaches. There may be different valid solutions depending on your tech stack or infrastructure.

The Problem

Let’s look at an example of a simple API CRUD (Create, Read, Update, and Delete) test for a project entity in a sample application. Here are the available requests for its endpoint.

  1. POST /project > Create a new project
  2. GET /project/:id > Returns all projects
  3. PUT /project/:id > Update the project with projectId
  4. DELETE /project/:id > Delete the project with projectId

You might write something like this:

describe('CRUD Tests for /project', () => {
  let project;

  it('Should create a project', () => {
    cy.request('POST', '/project', { name: 'An Awesome Project' })
      .then((res) => {
        project = res.body;
      });
  });

  it('Should read a project', () => {
    cy.request('GET', `/project/${project.id}`).its('body.name')  // assumes a project already exists