Mastering Cypress Test Setup and Teardown with before:run and after:run

Simran Sandhu
3 min readJan 8, 2025

--

Cypress is a powerful tool for end-to-end testing, but when it comes to managing resources dynamically, such as creating and cleaning up test data, leveraging before:run and after:run hooks in cypress.config.ts can simplify and automate these processes. This article explains how to use these hooks to handle test setup and teardown efficiently.

Why Use before:run and after:run Hooks?

  • before:run:
  • Executes once before the test suite starts.
  • Ideal for setting up resources, like creating test projects or fetching authentication tokens.
  • after:run:
  • Executes once after the test suite completes.
  • Perfect for cleaning up resources, such as deleting test projects or data.

Hypothetical Scenario: Testing a User Management System

Imagine you’re testing a user management system. Your tests require:

  1. A test user to exist before running the suite.
  2. The test user to be deleted after the tests are completed.

We will use before:run to create the user and after:run to delete it.

1. Creating Resources with before:run

In this example, the before:run hook will:

  1. Fetch an authentication token to interact with the system’s API.
  2. Create a test user using the token.
  3. Store the userId for cleanup.

import { defineConfig } from ‘cypress’;
import axios from ‘axios’;
import fs from ‘fs’;
import path from ‘path’;

// Helper to fetch an authentication token
async function getAuthToken(): Promise<string> {
const apiUrl = ‘https://api.example.com/login';
const credentials = { username: ‘testAdmin’, password: ‘password123’ };

const response = await axios.post(apiUrl, credentials, {
headers: { ‘Content-Type’: ‘application/json’ },
});

if (response.status === 200 && response.data.token) {
return response.data.token;
} else {
throw new Error(‘Failed to fetch auth token’);
}
}

// Helper to create a test user
async function createTestUser(authToken: string): Promise<string> {
const apiUrl = ‘https://api.example.com/users';
const userDetails = { name: ‘Test User’, email: ‘testuser@example.com’, role: ‘tester’ };

const response = await axios.post(apiUrl, userDetails, {
headers: {
Authorization: `Bearer ${authToken}`,
‘Content-Type’: ‘application/json’,
},
});

if (response.status === 201 && response.data.id) {
return response.data.id; // Return the created user’s ID
} else {
throw new Error(‘Failed to create test user’);
}
}

export default defineConfig({
e2e: {
setupNodeEvents(on, config) {
let authToken: string;
let userId: string;

on(‘before:run’, async () => {
console.log(‘Setting up resources before tests…’);
try {
// Step 1: Get Auth Token
authToken = await getAuthToken();
console.log(‘Auth Token:’, authToken);

// Step 2: Create Test User
userId = await createTestUser(authToken);
console.log(‘Test User Created with ID:’, userId);
} catch (error) {
console.error(‘Error during setup:’, error.message);
throw error;
}
});

// Cleanup resources after tests
on(‘after:run’, async () => {
console.log(‘Cleaning up resources after tests…’);
try {

// Step 1: Delete Test User
const apiUrl = `https://api.example.com/users/${userId}`;
await axios.delete(apiUrl, {
headers: {
Authorization: `Bearer ${authToken}`,
},
});

console.log(‘Test User Deleted Successfully’);
} catch (error) {
console.error(‘Error during cleanup:’, error.message);
}
});

return config;
},
},
});

2. Cleaning Up Resources with after:run

The after:run hook reads the userId stored into variable and deletes the user using the API. This ensures a clean slate for subsequent test runs.

The before:run and after:run hooks in Cypress provide powerful lifecycle events to manage test setups and teardowns. By automating resource creation and cleanup, you can maintain a clean test environment and reduce manual effort.

--

--

Simran Sandhu
Simran Sandhu

Written by Simran Sandhu

Passionate Engineer, Mother. "Without continual growth and progress, such words as improvement, achievement, and success have no meaning." - Benjamin Franklin

No responses yet