Level up you're UI Testing with Cypress

Level up you're UI Testing with CypressThis article is an introduction to integration testing Vue apps using cypress. You will learn why to use cypress, how to set up cypress and how to integrate it into your project.
Categoriestesting integration test
Date
2022-02-20
Hire me on Upwork!

Hi, in this guide I want to show you the amazing testing library Cypress.

You will learn what cypress is why to use cypress and how to use cypress for quality assurance in your next vue js or other JavaScript Project.

What is Cypress

Cypress is mainly an E2E (end to end) testing framework, and it does its job really well. Cypress is a framework-independent End to End testing framework, like selenium. Cypress is built with developers in mind, due to that it is very easy to use. Cypress also provides amazing documentation to its users. They support everything from powerful assertions over mocking, including network requests, conditional testing a beautiful Dashboard, and CI integration.

Interested? Let's dive deeper into Cypress.

Why Cypress

Why testing in general? Sure you can simply just skip testing and do features instead (like some managers in your company would suggest). Of course, you will save some time, but it all comes back to you in production. It's like driving your car without a seatbelt. You will save some time when everything runs fine, it will run fine. But when things go wrong, and they will over a long period of time, you have to break. You will hurt yourself or others and wish you invested the time when starting and have no broken nose (or worse) now. So please make sure to always wear a seatbelt when driving a car and always test your code before putting it in construction.

How you test is up to you. There are many different possibilities like manual testing (i would not suggest), unit testing, or UI testing.

Within the JavaScript ecosystem, you have access to amazing unit test frameworks like jest, they are amazing to test the logic in your application. But what if the logic is not the problem? What if your code is correct and you just called the wrong method in a click listener?

That's where Cypress comes into play. With Cypress, you are directly interacting you`re UI like a real user would do. So you are able to test your code from a higher-level perspective and still validate the correctness of your business logic.

Another why for Cypress is that accessing the UI feels so much more natural than simply accessing the code itself. The Cypress test runner also provides you with screenshots of failed tests and a fully visual experience while running your test to easily see what you're test is doing. Even if you want to keep up with unit tests, the component testing of cypress keeps you covered.

Using Cypress for testing gives the Developer a more natural experience, more code coverage with fewer tests, and a more intuitive API compared to Jest.

Getting started with Cypress

To install Cypress runner on your machine follow the instructions given on the getting started page.

To Install cypress into your project run

npm install cypress --save-dev

After a few seconds, Cypress is installed on your machine and ready to use.

To start the cypress runner run

npx cypress open

The Cypress runner opens und it will look something like this:

This is the Cypress test runner. (For Privacy reasons I have removed the top line with my private mail address).

On The Top left, you can change the browser you want to use for your tests, right you can see three tabs.

Under tests(the active one) you can see all your tests, yes there are already some.

Inside the Runs Tab, you can connect Cypress with you're cypress Dashboard.

After connecting with the Dashboard you can copy the code you got into the CMD line. Make sure to use npx as prefix!

npx cypress run --record --key <you're key>

You can also see now the results of this run inside the dashboard.

How Cypress Organizes its tests

The integrations directory

After Cypress is successfully installed, you can see an Cypress directory inside yor project. By default you get lots of example tests, testing an given project made by cypress. These are located under the Integration directory.

The fixtures directory

Some of these tests are mocking network requests, the fixtures for mocking are located in the fixtures directory. When it comes to network mocking there are some different oppinions. Some say you should not since an e2e test should also use the data provided by the API. Others say that you should to keep the tests independent from API changes and only test the frontend with Cypress. Needles to say that the tests are way faster wihen cypress uses mocking instead of waiting for every request to finish.

In my team we are combining both, small tests are allways mocking network requests. We have about 2 to 3 tests which are real E2E tests and uses the application in the same way a real user would and runs complete user flows without mocking network requests. This E2E tests are executet bevor going to production.

The Support directory

When uning cypress you will start loving this directory.

In the commands.js directory you can define custom commands such as accessing only visible items by their data cy as shown bellow.

Cypress.Commands.add("getByDataCy", (selector, ...args) => {
  return cy.get(`[data-cy=${selector}]`, ...args);
});

This is great to speed up your testing and building some sort of own test framework on top of cypress.

The Index.js file is used to configure cypress and to load your commands files. There is not really more to say about it. To dig deeper on it, see the docs.

The Plugins directory

There you can add plugins to cypress for example to interact with UI frameworks like vuetify or your webpack config.

Each Plugin needs its own file, and they must be registered again in the index.js.

Testing your app with Cypress

Another good thing with cypress is that it is independend from any JS and UI framework. Since Cypress is directly interacting with DOM you can test your vue js app with cypress in the same way as testing an react app with cypress.

To prof this i want to show how to test an example provided by cypress.

As an example i wanted to show one of the examples you get after installing cypress. I decided to describe the assertions.spec.js since asserting is an imporant feature and cypress did a great job on providing an natural chainable clean syntax for it.

See self:

context('Assertions', () => {
  beforeEach(() => {
    cy.visit('https://example.cypress.io/commands/assertions')
  })

  describe('Implicit Assertions', () => {
    it('.should() - make an assertion about the current subject', () => {
      // https://on.cypress.io/should
      cy.get('.assertion-table')
        .find('tbody tr:last')
        .should('have.class', 'success')
        .find('td')
        .first()
        // checking the text of the <td> element in various ways
        .should('have.text', 'Column content')
        .should('contain', 'Column content')
        .should('have.html', 'Column content')
        // chai-jquery uses "is()" to check if element matches selector
        .should('match', 'td')
        // to match text content against a regular expression
        // first need to invoke jQuery method text()
        // and then match using regular expression
        .invoke('text')
        .should('match', /column content/i)

      // a better way to check element's text content against a regular expression
      // is to use "cy.contains"
      // https://on.cypress.io/contains
      cy.get('.assertion-table')
        .find('tbody tr:last')
        // finds first <td> element with text content matching regular expression
        .contains('td', /column content/i)
        .should('be.visible')

      // for more information about asserting element's text
      // see https://on.cypress.io/using-cypress-faq#How-do-I-get-an-element’s-text-contents
    })

The above test visits the website before each test.

This tested page contains an basic table. The test acceses the table and checks it for different propertys like the text inside with have.text or with

cy.get('.assertion-table')
  .find('tbody tr:last')
  // finds first  element with text content matching regular expression
  .contains('td', /column content/i)
  .should('be.visible')

The test validates if the last row of the table is also visible.

I think you get the powerful concept behind cypress and also behind cypress assertions. For more info on it visit the cypress assertion page. For the ecample visit the assertion example page. And as you probably seen we do not need to even know the framework used to create this table.

Only differences are with Component testing. There the framework is also important since component tests are cypress version of writing unit tests like with jest. This is one of the topics for my next articles.

Example: test a vue js app with cypress

To see an example for tesing an vue app with cypress see this link, they tested an vue Toto app with cypress and gone an step further usin aplitools to also check the appearance of the UI.

Conclusion

Due to its simple API and great interaction with all JavaScript frameworks cypress is a great choice when it comes to testing. You can quickly write tests to check the functionality in the same way a user sees it. Due to this it is also more fun to write tests and you can simply use the Browser console to debug your Cypress tests.

Thank you for reading this article, i'm planing on writing more articles aboutcypress and its powerfull concepts including Component tests, visual testing with Aplitools, handling file uploads etc.

If you want to know more about Cypress or simply say hi, yo can contact me in the say hi section.

Happy testing,

Alex

Recommended Products for you
recommended for you