Skip to content

Cypress - Hooks

Cypress, leveraging Mocha’s structure, provides hooks that allow you to run code at specific points during the execution of your test suites and test cases. These are useful for setting up preconditions or cleaning up after tests.

The primary hooks available are:

  • before(callback): Runs once before any of the tests within a describe block.
  • after(callback): Runs once after all tests within a describe block have completed.
  • beforeEach(callback): Runs before each individual test (it block) within a describe block.
  • afterEach(callback): Runs after each individual test (it block) within a describe block.

Here’s how you can use these hooks in a test file:

describe('Hooks Example Suite', function() {
before(function() {
// Runs once before all tests in this block
cy.log('Before All Hook: Executing once before all tests');
// Example: Seed database, start a server
});
after(function() {
// Runs once after all tests in this block
cy.log('After All Hook: Executing once after all tests');
// Example: Clean up database, stop a server
});
beforeEach(function() {
// Runs before each test in this block
cy.log('Before Each Hook: Executing before each test');
// Example: Visit a page, log in a user
cy.visit('https://example.cypress.io/commands/actions');
});
afterEach(function() {
// Runs after each test in this block
cy.log('After Each Hook: Executing after each test');
// Example: Log out user, clear cookies/localStorage
});
it('First Test Case', function() {
cy.log('Executing First Test Case');
cy.get('.action-email').type('test1@example.com');
});
it('Second Test Case', function() {
cy.log('Executing Second Test Case');
cy.get('.action-disabled').should('be.disabled');
});
});

Execution Results:

When you run this test, the Cypress Command Log will show the cy.log messages in the following order (interspersed with other command logs):

  1. ‘Before All Hook: Executing once before all tests’ (runs once)

  2. ‘Before Each Hook: Executing before each test’ (before First Test Case)

  3. ‘Executing First Test Case’

  4. ‘After Each Hook: Executing after each test’ (after First Test Case)

  5. ‘Before Each Hook: Executing before each test’ (before Second Test Case)

  6. ‘Executing Second Test Case’

  7. ‘After Each Hook: Executing after each test’ (after Second Test Case)

  8. ‘After All Hook: Executing once after all tests’ (runs once at the very end)

This demonstrates that before and after run once per describe block, while beforeEach and afterEach run for every it block within that describe.

Mocha (and thus Cypress) also provides ways to control which tests or suites are run using .only and .skip modifiers. These can be appended to describe() or it().

Appending .only to a describe or it block will ensure that only that block (and any other blocks also marked with .only) will be executed within the spec file. All other tests will be skipped.

describe('Focusing Tests with .only', function() {
it('This test will be skipped', function() {
cy.log('First Test - Skipped');
});
it.only('This test will run', function() {
cy.log('Second Test - I will run!');
// Useful for focusing on a specific test during development
});
it('This test will also be skipped', function() {
cy.log('Third Test - Skipped');
});
});
// If multiple .only are used, all of them will run:
describe.only('Another focused suite', function() {
it('This test inside a focused suite will run', function(){
cy.log('Test in describe.only');
});
});

Execution Results with .only:

The Command Log will only show execution for ‘Second Test - I will run!’ and ‘Test in describe.only’. The other tests will be marked as pending/skipped.

Common Pitfall: Remember to remove .only before committing your code, as it can lead to unintentionally skipping other important tests in your suite or in CI.

Appending .skip to a describe or it block will cause that block to be skipped during the test run.

describe('Skipping Tests with .skip', function() {
it('This test will run', function() {
cy.log('First Test - Will run');
});
it.skip('This test will be skipped', function() {
cy.log('Second Test - I am skipped!');
// Useful for temporarily disabling a flaky or work-in-progress test
});
it('This test will also run', function() {
cy.log('Third Test - Will run');
});
});

Execution Results with .skip:

The Command Log will show execution for ‘First Test - Will run’ and ‘Third Test - Will run’. ‘Second Test - I am skipped!’ will be marked as pending/skipped.

Real-world Application: beforeEach is commonly used to navigate to a specific page or ensure a user is logged in before each test case. afterEach can be used for cleanup like logging out or resetting application state. .skip is helpful for temporarily disabling tests that are known to be failing or are under development.