DEV Community

Santiago Salazar Pavajeau
Santiago Salazar Pavajeau

Posted on

5 4

Easily test React-Redux with Cypress

Cypress is a very visual Javascript testing framework that can do end-to-end, integration and unit tests. One of its cool features, is the ease of querying elements with the tool on the test browser, especially when using frameworks like Semantic UI, Bootstrap, etc. because UI components are pre-defined and it's harder to know the underlying HTML elements making up the components.

Quickly testing from the user's perspective

    it('New project modal form is controlled', () => {

        cy.get('.eight > .button')
          .click()

        cy.get(':nth-child(2) > .ui > input')
          .type('Test title')
          .should('have.value', 'Test title')

        cy.get('textarea')
          .type('Test description')
          .should('have.value', 'Test description')

        cy.get('#new-project')
          .click()
   })
Enter fullscreen mode Exit fullscreen mode

Cypress will give you the selectors like: cy.get('.eight > .button') (from their browser testing select feature), which give access to the element from the DOM. In this case, it is an input element so we can .type something into the input, check the updated value it .should have, and finally .click() on the submit button.

Testing the store and the backend API

Cypress allows for end-to-end testing having access to asynchronous calls, and also the application environment. However, having access to our redux store can be a little tricky.

First, because this data is only meant to exist inside the React application, and making it available to an external environment like Cypress can be insecure.

...
export const store = createStore(reducer, 
  applyMiddleware(thunk)
  );

...

if (window.Cypress) {
  window.store = store
}
...
Enter fullscreen mode Exit fullscreen mode

Second, if the application state updates asynchronously, this requires the tests to only run after the state has updated. Cypress has several ways to deal with this like only testing the DOM elements on the surface instead of the Redux store underneath or testing the backend with asynchronous requests tests.

But if we want to build an application starting from Redux, and focus on developing tests for the store we can use the cypress-pipe package, which helps Cypress wait to test the store when it's actually updated.

    it('Adds a new user', () => {
      cy.visit('/projects')
      cy.get('[href="#/new-project"]').click()
      cy.get(':nth-child(2) > .ui > input').type('Test Title')
      cy.get('textarea').type('Test Description')
      cy.get('[type="submit"]').click()

      cy.request(`${URL}people`)
        .then((response) => {
          expect(response.status).to.eq(200)
        })

      const getProjects = (window) => window.store.getState().projects

      cy.window().pipe(getProjects).should('have.length', 5)
    })
Enter fullscreen mode Exit fullscreen mode

Here we make a test of a new project feature on the site. So the test types the title and description and then submits it. We can have access to the store through the window object on the Cypress browser environment and test our Redux state with the right timing.

Feel more than welcome to reach out with any ideas/comments at Linkedin or Twitter, or check out my portfolio.

Playwright CLI Flags Tutorial

5 Playwright CLI Flags That Will Transform Your Testing Workflow

  • 0:56 --last-failed
  • 2:34 --only-changed
  • 4:27 --repeat-each
  • 5:15 --forbid-only
  • 5:51 --ui --headed --workers 1

Learn how these powerful command-line options can save you time, strengthen your test suite, and streamline your Playwright testing experience. Click on any timestamp above to jump directly to that section in the tutorial!

Watch Full Video πŸ“ΉοΈ

Top comments (2)

Collapse
 
xendke profile image
Juan Xavier Gomez β€’

Very interesting!

Collapse
 
santispavajeau profile image
Santiago Salazar Pavajeau β€’

Thanks Juan Xavier! πŸ‘Ύ

Image of Timescale

πŸ“Š Benchmarking Databases for Real-Time Analytics Applications

Benchmarking Timescale, Clickhouse, Postgres, MySQL, MongoDB, and DuckDB for real-time analytics. Introducing RTABench πŸš€

Read full post β†’

πŸ‘‹ Kindness is contagious

Explore a trove of insights in this engaging article, celebrated within our welcoming DEV Community. Developers from every background are invited to join and enhance our shared wisdom.

A genuine "thank you" can truly uplift someone’s day. Feel free to express your gratitude in the comments below!

On DEV, our collective exchange of knowledge lightens the road ahead and strengthens our community bonds. Found something valuable here? A small thank you to the author can make a big difference.

Okay