Bird
Raised Fist0
Cypresstesting~20 mins

API-first setup pattern in Cypress - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
API-first Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the test result of this Cypress API setup code?
Consider this Cypress test code that uses API-first setup to create a user before UI tests. What will be the test execution result?
Cypress
describe('User Profile Test', () => {
  before(function() {
    cy.request('POST', '/api/users', { name: 'Alice' }).then((response) => {
      expect(response.status).to.eq(201);
      cy.wrap(response.body.id).as('userId');
    });
  });

  it('loads user profile page', function() {
    cy.visit(`/users/${this.userId}`);
    cy.contains('Alice').should('be.visible');
  });
});
ATest fails: 'this.userId' is undefined causing visit URL to be incorrect.
BTest fails: cy.request is asynchronous and test runs before user creation.
CTest fails: API request returns 404 causing assertion failure.
DTest passes: user is created via API, profile page loads with name visible.
Attempts:
2 left
💡 Hint
Remember how Cypress aliases and 'this' context work inside tests.
❓ assertion
intermediate
1:30remaining
Which assertion correctly verifies API response in API-first setup?
You want to verify that the API response contains a user object with a non-empty 'id' field after creating a user. Which assertion is correct in Cypress?
Cypress
cy.request('POST', '/api/users', { name: 'Bob' }).then((response) => {
  // Which assertion below is correct?
});
Aexpect(response.body.id).to.be.undefined;
Bexpect(response.body.id).to.exist.and.to.be.a('string').and.to.have.length.greaterThan(0);
Cexpect(response.body).to.have.property('id', null);
Dexpect(response.status).to.equal(404);
Attempts:
2 left
💡 Hint
Check that the user ID exists and is a non-empty string.
🔧 Debug
advanced
2:00remaining
Why does this API-first setup test fail intermittently?
This Cypress test sometimes fails with 'Cannot read property "id" of undefined'. What is the likely cause?
Cypress
before(function() {
  cy.request('POST', '/api/users', { name: 'Carol' }).then((response) => {
    cy.wrap(response.body.id).as('userId');
  });
});

it('loads user profile', function() {
  cy.visit(`/users/${this.userId}`);
  cy.contains('Carol').should('be.visible');
});
AThe 'this.userId' is accessed before the alias is set because 'before' hook is asynchronous.
BThe API endpoint '/api/users' is incorrect causing undefined response body.
CThe test is missing a 'cy.wait()' causing timing issues.
DThe 'cy.wrap' does not create an alias accessible via 'this'.
Attempts:
2 left
💡 Hint
Consider how Cypress handles asynchronous commands and test context.
❓ framework
advanced
1:30remaining
Which Cypress command best supports API-first test setup?
In API-first testing, which Cypress command is best to create test data before UI tests?
Acy.intercept() to mock API responses without real data creation.
Bcy.visit() to load the UI and create data manually.
Ccy.request() to call backend API endpoints directly.
Dcy.wait() to delay tests until data is ready.
Attempts:
2 left
💡 Hint
Think about how to create real data via backend before UI tests.
🧠 Conceptual
expert
2:00remaining
What is the main advantage of API-first setup pattern in end-to-end testing?
Choose the best explanation for why API-first setup is preferred in modern UI testing frameworks like Cypress.
AIt creates test data quickly and reliably via backend APIs, reducing flaky UI setup steps.
BIt avoids the need for any UI tests by testing APIs only.
CIt allows tests to run without any backend server by mocking all API calls.
DIt requires less coding because UI interactions create all test data automatically.
Attempts:
2 left
💡 Hint
Think about speed, reliability, and test flakiness.

Practice

(1/5)
1. What is the main benefit of using the API-first setup pattern in Cypress tests?
easy
A. It prepares test data quickly by calling backend APIs before UI tests run.
B. It replaces UI tests completely with API tests.
C. It slows down tests by adding extra API calls.
D. It only works for frontend UI testing without backend interaction.

Solution

  1. Step 1: Understand API-first setup purpose

    API-first setup means using backend API calls to prepare data before UI tests.
  2. Step 2: Identify the benefit

    This approach makes tests faster and more reliable by avoiding UI data entry steps.
  3. Final Answer:

    It prepares test data quickly by calling backend APIs before UI tests run. -> Option A
  4. Quick Check:

    API-first setup = faster, reliable test data setup [OK]
Hint: API-first means setup via backend calls before UI tests [OK]
Common Mistakes:
  • Thinking API-first replaces UI tests
  • Assuming API calls slow down tests
  • Believing API-first only works on frontend
2. Which of the following is the correct way to make an API call in Cypress for setup?
easy
A. cy.fetch('POST', '/users', {name: 'John'})
B. cy.api('POST', '/users', {name: 'John'})
C. cy.call('POST', '/users', {name: 'John'})
D. cy.request('POST', '/users', {name: 'John'})

Solution

  1. Step 1: Recall Cypress API call syntax

    Cypress uses cy.request() to make HTTP requests.
  2. Step 2: Match correct method and parameters

    cy.request('POST', url, body) is the correct syntax.
  3. Final Answer:

    cy.request('POST', '/users', {name: 'John'}) -> Option D
  4. Quick Check:

    Use cy.request() for API calls in Cypress [OK]
Hint: Use cy.request() for API calls in Cypress [OK]
Common Mistakes:
  • Using cy.api() which is not a Cypress command
  • Using cy.call() or cy.fetch() which don't exist in Cypress
  • Mixing up method names or parameters
3. Given this Cypress test snippet using API-first setup:
cy.request('POST', '/api/users', {name: 'Alice'}).then((response) => {
  expect(response.status).to.eq(201)
  cy.visit('/users/' + response.body.id)
})

What will happen if the API returns status 400 instead of 201?
medium
A. The test will continue and visit the user page anyway.
B. The test will throw a syntax error.
C. The test will fail at the assertion checking response.status.
D. The test will ignore the response and pass.

Solution

  1. Step 1: Analyze the assertion on response status

    The test expects response.status to equal 201.
  2. Step 2: Understand behavior if status is 400

    If status is 400, the assertion expect(response.status).to.eq(201) fails and test stops with failure.
  3. Final Answer:

    The test will fail at the assertion checking response.status. -> Option C
  4. Quick Check:

    Assertion fails if response.status != 201 [OK]
Hint: Assertion fails if API response status is unexpected [OK]
Common Mistakes:
  • Assuming test continues after failed assertion
  • Thinking Cypress throws syntax error on bad status
  • Believing test ignores failed API responses
4. You wrote this API-first setup code in Cypress:
cy.request('POST', '/api/items', {name: 'Book'})
  .then((res) => {
    expect(res.status).to.eq(200)
    cy.wrap(res.body.id).as('itemId')
  })
cy.get('@itemId').then((id) => {
  cy.visit(`/items/${id}`)
})

But the test fails with "Cannot read property 'then' of undefined". What is the likely cause?
medium
A. The cy.get('@itemId') runs before the alias is set.
B. The API returned status 500 causing failure.
C. The cy.request method is misspelled.
D. The cy.wrap command cannot create aliases.

Solution

  1. Step 1: Understand Cypress command chaining and timing

    Cypress commands run asynchronously and in order, but alias usage requires the alias to be set before use.
  2. Step 2: Identify timing issue with alias usage

    cy.get('@itemId') is called immediately, before the alias is set inside the then callback, causing undefined error.
  3. Final Answer:

    The cy.get('@itemId') runs before the alias is set. -> Option A
  4. Quick Check:

    Alias must be set before cy.get() uses it [OK]
Hint: Set alias before using cy.get('@alias') to avoid timing errors [OK]
Common Mistakes:
  • Assuming API error causes this specific error
  • Thinking cy.request is misspelled
  • Believing cy.wrap cannot create aliases
5. You want to use API-first setup to create multiple users before a UI test. Which approach correctly ensures all users are created before visiting the page?
const users = [
  {name: 'Anna'},
  {name: 'Ben'},
  {name: 'Cara'}
]

// Which code snippet is correct?
hard
A. users.forEach(user => { cy.request('POST', '/api/users', user) cy.visit('/users') })
B. cy.wrap(users).each(user => { cy.request('POST', '/api/users', user) }).then(() => { cy.visit('/users') })
C. for (const user of users) { cy.request('POST', '/api/users', user) cy.visit('/users') }
D. cy.wrap(users).each(user => { cy.request('POST', '/api/users', user) }) cy.visit('/users')

Solution

  1. Step 1: Understand Cypress command queue and async behavior

    Cypress commands like cy.request are asynchronous and queued. To wait for all requests, use cy.wrap().each() with a .then() callback.
  2. Step 2: Analyze each option

    The native forEach and for-of options place cy.visit() inside the loop, causing visits after each request instead of after all. The cy.wrap(users).each(...) cy.visit() executes visit before requests due to queuing. Only cy.wrap(users).each(...).then(() => cy.visit()) waits for all requests before visiting.
  3. Final Answer:

    cy.wrap(users).each(user => { cy.request('POST', '/api/users', user) }).then(() => { cy.visit('/users') }) -> Option B
  4. Quick Check:

    Use cy.wrap().each() with then() to wait before next step [OK]
Hint: Chain .then() after cy.wrap().each() to wait for all API calls [OK]
Common Mistakes:
  • Placing cy.visit() inside the forEach or for-of loop
  • Using cy.wrap().each() without .then() afterward
  • Not chaining .then() to wait for all iterations
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard