Wyszukaj / o blogu

Cypress: cy.intercept() - przechwytywanie zapytań HTTP

Opublikowano śro 02 lutego 2022 w qa • 2 min read

cypress

Wprowadzenie stubbing vs mocking

Oba pojęcia odnoszą się do podstawiania danych w celu przeprowadzenia testów - mockowanie odnosi się jednak do podstawiania danych w celu testowania funkcjonalności, podczas gdy stubowanie w celu zmiany stanu komponentu/strony/aplikacji.

Mocks vs Stubs = Testowanie funkcjonalne vs testowanie stanu => oznacza to że może w teście być wiele stubbów ale tylko jeden mock (w ramach zasady: testowania jednej funkcjonalności na test).

!!! -> więcej na ten temat patrz: SO - What's the difference between a mock & stub?

cy.intercept()

cy.request()- pozwala na przechwycenie zapytania typu HTTP przez test cypressowy - taka komenda może przydać się w przypadku gdy 1) chcemy aby dane zapytanie doszło do skutku zanim zaczniemy wykonywać kolejną komendę lub 2) gdy zależy nam na przechwyceniu requestu HTTP i podstawienia danych do niego, w celu testowania zachowania się aplikacji front-endowej.

beforeEach(() => {
    cy.viewport(viewport)
    cy.intercept('GET', '/xxx/xxx_data?page=1', { fixture: 'xxx/xxx_data.json' })
})

cy.intercept() + cy.wait()

Nasłuchiwanie zapytania typu GET na */comments/*

cy.intercept('GET', '**/comments/*').as('getComment')

Sprawdzanie statusu

cy.wait('@getComment').its('response.statusCode').should('be.oneOf', [200, 304])

Logowanie obiektu (DTO) w konsoli

cy.get('@post').then(console.log)

cy.intercept() + cy.wait() + cy.commnad()

Cypress.Commands.add('waitForApp2Start', dto => {
  cy.intercept('GET', '/xyz', { fixture: 'xdata' }).as('xdata')
  cy.intercept('GET', '/search_data?*', { fixture: 'searchData' }).as('searchData')
})


cy.waitForApp2Start()
cy.visit('').wait('@xdata').wait('@searchData')

przechwytywanie wielu zapytań / mockowanie wielu zapytań

cy.clock()- pozwala na "zamrożenie" zegara oraz wszystkich funkcji związanych z mierzeniem czasu jak setInterval czy setTimeout

cy.tick() - pozawala na manualne sterowanie czasem

it('fetches from the server (spies)', () => {
  cy.clock()
  cy.intercept('GET', '/favorite-fruits').as('fruits')
  cy.visit('/fruits.html')
  // pierwsze zapytanie
  cy.wait('@fruits').its('response.statusCode').should('equal', 200)

  // po 30 sekundach pytanie jest ponawiane 
  cy.tick(30000)
  cy.wait('@fruits').its('response.statusCode').should('equal', 200)
  [...]

Mockowanie zapytania HTTP

  it('returns different fruits every 30 seconds', () => {
    cy.clock()
    let k = 0

    // za każdym razem kiedy pojawia się zapytanie inna odpowiedź jest podstawiana
    cy.intercept('/favorite-fruits', (req) => {
      k += 1
      switch (k) {
        case 1:
          return req.reply(['apples 🍎'])
        case 2:
          return req.reply(['grapes 🍇'])
        default:
          return req.reply(['kiwi 🥝'])
      }
    })

    cy.visit('/fruits.html')
    cy.contains('apples 🍎')
    cy.tick(30000)
    cy.contains('grapes 🍇')
    cy.tick(30000)
     cy.contains('kiwi 🥝')
})

Za każdym razem kiedy intercept jest wywoływany używa pierwszego elementu z tablicy odpowiedzi i usuwa go. Po pierwszych dwóch razach, responses.shift() zawsze zwraca undefined i wtedy odpowiedź jest w postaci tablicy zawierającej kiwi.

it('returns different fruits every 30 seconds (array shift)', () => {
  cy.clock()

  // return difference responses on each call
  const responses = [
    ['apples 🍎'], ['grapes 🍇'],
  ]

  cy.intercept('/favorite-fruits', (req) => {
    req.reply(responses.shift() || ['kiwi 🥝'])
  })

  cy.visit('/fruits.html')
  cy.contains('apples 🍎')
  cy.tick(30000)
  cy.contains('grapes 🍇')
  cy.tick(30000)
  cy.contains('kiwi 🥝')
})

Testowanie API przy pomocy Cypressa

Generalnie Cypress nie powstał w celu testowania API - do tego zostały stworzone inne biblioteki oraz narzędzia (patrz linki w sekcji: Powiązane artykuły) nie oznacza to jednak, że nie może być z powodzeniem do tego wykorzystywany. Powstała nawet do tego osobna wtyczka cy-api.

Tutaj znajdziesz linki do materiałów na YT(ang), które przedstawiają w jaki sposób można testować API w Cypressie (i jest to naturalne rozwinięcie materiału opisanego powyżej)

Cypress - API Testing | Part 14

Cy-api/Cypress API testing Tricks

CYPRESS API TESTING Introduction - CYPRESS REQUEST


Źródła:

intercept - cypress.io

example.cypress.io/commands/waiting

Asserting Network Calls from Cypress Tests

Testing periodic network requests with cy.intercept and cy.clock combination