How to test that cache works with Cypress
Tags: cypress, testing, automtion, e2e
Published: 2021-05-05 21:55:10

## Learn how to verify that a search result came from the cache instead of an HTTP request with Cypress.io

Here we go with another "**Pinch of Cypress**." I hope you enjoy it!

In the [**advanced course of testing automation with Cypress**](https://www.udemy.com/course/testing-automation-with-cypress-advanced/?couponCode=B001C10C43DD5F6957CD) from the [**Talking About Testing School**](https://udemy.com/user/walmyr), I challenge my students to put the knowledge they got into practice with an application similar to that of the course. This is a searching application that integrates with the [**Hackernews API**](https://hn.algolia.com/api). In this application's version (the one for the challenge), when a search has already happened, the results are stored in a cache, avoiding a new request to the API when a search for the same term occurs again.

How do we test that?

🤔

I'll explain with an example.

```js
describe('Hacker News Search', () => {
  const term = 'cypress.io'

  beforeEach(() => {
    cy.intercept(
      '**/search?query=redux&page=0&hitsPerPage=100',
      { fixture: 'empty'}
    ).as('empty')
    cy.intercept(
      `**/search?query=${term}&page=0&hitsPerPage=100`,
      { fixture: 'stories'}
    ).as('stories')

    cy.visit('/')
    cy.wait('@empty')
  })

  it('correctly caches the results', () => {
    const faker = require('@faker-js/faker')
    const randomWord =faker.random.word()
    let count = 0

    cy.intercept(`**/search?query=${randomWord}**`, req => {
      count +=1
      req.reply({fixture: 'empty'})
    }).as('random')

    cy.search(randomWord).then(() => {
      expect(count, `network calls to fetch ${randomWord}`).to.equal(1)

      cy.wait('@random')

      cy.search(term)
      cy.wait('@stories')

      cy.search(randomWord).then(() => {
        expect(count, `network calls to fetch ${randomWord}`).to.equal(1)
      })
    })
  })
})
```

In the code above, what happens is the following:

1. We have a test suite for the search functionality for the Hacker Stories application
2. We defined a variable called `term` for code reuse reasons
3. So we have a function that runs before each test (`beforeEach`)
  1. In the `beforeEach` function, we defined two routes (which use fixtures) so that we don't depend on the Hackernews API. In the first route, which occurs as soon as the application is rendered, the fixtures will return an empty list of stories, and in the second, they will return two stories
  2. We then visit the home page of the application
  3. And finally, we wait for the initial request to end (the one that returns the empty list of stories)
4. Hence, we have the test itself to ensure that the cache works
  1. The test uses the [**`faker`**](https://fakerjs.dev/) library to generate random words for the search that the app will store in the cache
  2. Right at the beginning, we define a variable called `count`, which is initialized to zero (`0`). This variable's value will increase each time a request occurs for the same search term.
  3. Then we have the definition of another [**`cy.intercept`**](https://docs.cypress.io/api/commands/intercept), which intercepts a search request by the random word, performs a function that increments the counter, and finally, responds to that request with the fixture that returns an empty list of stories. Here's the secret, **when a request for such a term occurs, the counter will be incremented**
  4. There's a search for a random word, and we soon **assert that the counter has been incremented correctly**. Now, instead of `0`, it's `1`.
  5. A search for another term is done with their respective waiting. In this case, as it's another term, the counter is not incremented. This other term falls into another `cy.intercept` (created in `beforeEach`).
  6. Finally, **a new search happens for the random word previously searched, with the verification that the counter has not increased**, that is, it continues with a value of `1`, demonstrating that a new request did not occur for such a route, proving that the cache works. **Note:** if the cache weren't working, a new request would occur, which would increase the counter to `2`, and the final test assertion would fail.

This is an alternative to test how well a search cache works when talking about automated tests with [**Cypress**](https://cypress.io). I hope you find it useful.

**Reference:** https://glebbahmutov.com/blog/cypress-intercept-problems/

See the implementation details of the `search` custom command:

```js
// cypress/support/commands.js

Cypress.Commands.add('search', term => {
  cy.get('input[type="text"]')
    .should('be.visible')
    .clear()
    .type(`${term}{enter}`)
})
```

And of the fixtures:

```json
// cypress/fixtures/empty.json

{
  "hits": []
}

```

```json
// cypress/fixtures/stories.json

{
  "hits": [
    {
      "title": "Sample 1",
      "url": "https://example.com/1",
      "author": "Author 1",
      "num_comments": 34,
      "points": 91,
      "objectID": 0
    },
    {
      "title": "Sample 2",
      "url": "https://example.com/2",
      "author": "Author 2",
      "num_comments": 55,
      "points": 98,
      "objectID": 1
    }
  ]
}
```

That's it!

___

So, did you like this “**Pinch of Cypress**“?

Leave a comment.

___

Are you curious and want to learn more about **testing automation with Cypress**? I was hoping you could get to know [**my Cypress courses on Udemy**](https://www.udemy.com/user/walmyr/).

___

This post was originally published in Portuguese on the [**Talking About Testing**](https://talkingabouttesting.com/2021/05/05/como-testar-que-o-chache-funciona-em-um-teste-escrito-com-cypress/) blog.

___

👋 Until next time and happy testing!