0
0
Cypresstesting~5 mins

API-first setup pattern in Cypress

Choose your learning style9 modes available
Introduction

The API-first setup pattern helps prepare test data quickly and reliably by using backend APIs before running UI tests.

When you need to create test users or data before testing the app UI.
When UI setup is slow or flaky, and you want faster test preparation.
When you want to isolate UI tests from data creation steps.
When you want to reuse setup steps across many tests.
When you want to keep tests clean and focused on UI behavior.
Syntax
Cypress
cy.request({
  method: 'POST',
  url: '/api/users',
  body: { username: 'testuser', password: 'pass123' }
}).then((response) => {
  expect(response.status).to.eq(201)
  // use response data for next steps
})

Use cy.request() to call backend APIs directly.

Check the response status to confirm setup success.

Examples
Simple POST request to login API with assertion on status code.
Cypress
cy.request('POST', '/api/login', { username: 'user1', password: 'pwd' })
  .then((res) => {
    expect(res.status).to.eq(200)
  })
Delete a user by ID before running tests to ensure clean state.
Cypress
cy.request({
  method: 'DELETE',
  url: '/api/users/123'
}).then((res) => {
  expect(res.status).to.eq(204)
})
Fetch list of products to verify API returns data before UI tests.
Cypress
cy.request({
  method: 'GET',
  url: '/api/products'
}).then((res) => {
  expect(res.body).to.have.length.greaterThan(0)
})
Sample Program

This test suite uses API calls to create a user before tests, then tests login via UI, and finally deletes the user after tests.

Cypress
describe('API-first setup example', () => {
  before(() => {
    // Create a test user via API
    cy.request({
      method: 'POST',
      url: '/api/users',
      body: { username: 'testuser', password: 'pass123' }
    }).then((response) => {
      expect(response.status).to.eq(201)
      cy.wrap(response.body.id).as('userId')
    })
  })

  it('logs in with the created user', function () {
    cy.visit('/login')
    cy.get('input[name=username]').type('testuser')
    cy.get('input[name=password]').type('pass123')
    cy.get('button[type=submit]').click()
    cy.url().should('include', '/dashboard')
    cy.contains('Welcome, testuser').should('be.visible')
  })

  after(function () {
    // Clean up by deleting the test user
    cy.request({
      method: 'DELETE',
      url: `/api/users/${this.userId}`
    }).then((res) => {
      expect(res.status).to.eq(204)
    })
  })
})
OutputSuccess
Important Notes

Always verify API responses to catch setup errors early.

Use aliases (cy.wrap(...).as()) to share data between hooks and tests.

Cleaning up test data after tests keeps your environment stable.

Summary

API-first setup uses backend calls to prepare test data before UI tests.

This pattern makes tests faster and more reliable.

Remember to verify API responses and clean up after tests.