Automated End-to-End Testing with Cypress and Husky Pre-Commit hooks

What is Cypress?

Cypress is a modern Javascript-based testing framework that can be used to automate end-to-end testing. The project’s website puts it perfectly, Cypress is for “fast, easy and reliable testing for anything that runs in a browser.” It has a ton of benefits over traditional testing automation frameworks and also comes with numerous features right out of the box, which we will go over in-depth in this article.

Why should I use it?

1. Easy Setup

Out of the tools that I have used to test applications, Cypress is by far the easiest, and quickest to setup. All you need to get started is one npm or yarn command (we will go over how to set it up in the second half of this article). Compare this to something like Selenium which requires an extensive set up and has a bunch of dependencies, making the process more complex than it needs to be.

2. Written in Javascript

If you are a web developer, you are most likely comfortable with writing code in Javascript and, or your product itself is in Javascript. Cypress tests are written in Javascript which means that you might not have to pick up a new language to write your tests like you would have to for other conventional forms of front-end testing.

3. Comes with a GUI

Cypress has a debugger and a GUI to show how your tests are doing and the ones that have failed/passed. It gives you a real-time look into what is happening with your tests and allows you to pause, resume and rerun the tests straight from the interface. It also comes inbuilt with an element selector. This can help build your tests quicker since it eliminates the time spent selecting elements, like in other frameworks.

4. Hot reloading

Cypress tests automatically reload when you save changes to your spec file. Although this might not seem like a big deal, it helps with not having to run commands over and over again to run the same tests, saving a lot of time.

5. Waits for components to load

Tired of specifying every line of your tests to be asynchronous? Cypress has you covered. It automatically waits for all the components to load, waits for commands and other checks before moving on. You can change this wait time that it automatically applies in the package.json if you are feeling the need to increase it. Here’s to never writing waits again!

6. Ability to go back in time

Cypress will give you superpowers, not just testing superpowers but the ability to go back and see how the test ran. The GUI allows you to go back and look at what the state of your page was when tested and where the test went from there. This is one of the best features of it hands down because you can point out exactly what improvements need to be made / what other use cases need to be accounted for

7. Amazing Documentation

If you haven’t been convinced yet, Cypress’ documentation will make you want to use it. As developers, we appreciate solid documentation. Cypress provides that to us. You can follow tutorials on their website that will set you up for working within it. They also have a bunch of code examples and best practices around using each function.

What are the drawbacks?

Honestly, it is difficult to think of any drawbacks, but after giving it a lot of thought I could come up with two.

1. Problems with single-page apps

While writing tests for certain single-page apps, Cypress had some difficulties recognizing that the components and the route of the page had changed.

2. Automated wait time might not be enough

Sometimes, the automated waiting that Cypress offers might not be enough for the components to load. Maybe you have a backend request which takes a while to process. This may cause the Cypress wait time to fail your test and you might have to specify custom wait times for certain components (you can see I am nitpicking now).

How do I set it up and use it?

Let’s start with creating a very basic react app. We will have a couple of form fields and buttons so that we can get a feel for how Cypress works. Use the following command to create a boiler-plate react app:

Sample React App
describe(“Our first test”, () => {  it(‘should go to our sample react app, () => {    cy.visit(“http://localhost:3000/");})}
cy.get(‘#formBasicEmail’).type(‘test’);
.should() — check for various thing.click() — click elements.contains() — checks if the DOM contains a string.url() — checks for URL properties
describe(“Our first test”, () => {  it(“should go to our sample react app”, () => {    cy.visit(“http://localhost:3000/");    cy.contains(“Cypress testing with Husky pre-commit hooks”);  });  it(“should see that the submit button is disabled”, () => {    cy.get(‘.submitBtn’).should(‘be.disabled’);    cy.get(‘.modalBtn’).should(‘be.enabled’);  });  it(“should enter some incorrect email value — submit should be         disabled and modal should be enabled”, () => {  cy.get(‘#formBasicEmail’).type(‘test’);  cy.get(‘.submitBtn’).should(‘be.disabled’);  cy.get(‘.modalBtn’).should(‘be.enabled’); }); it(“should enter some password value — submit should be disabled and modal should be enabled”, () => {  cy.get(‘#formBasicPassword’).type(‘test@test.com’);  cy.get(‘.submitBtn’).should(‘be.disabled’);  cy.get(‘.modalBtn’).should(‘be.enabled’); });  it(“should check the box — submit should be enabled and modal should be disabled”, () => {  cy.get(‘#formBasicCheckbox’).click();  cy.get(‘.submitBtn’).should(‘be.enabled’);  cy.get(‘.modalBtn’).should(‘be.disabled’);  });});
Cypress.Commands.add(‘checkForm’, () => {   cy.get(‘.submitBtn’).should(‘be.disabled’); cy.get(‘.modalBtn’).should(‘be.enabled’);
});
Final Result
npm install husky — save-devnpx husky install
npx husky add .husky/pre-commit “npm test”
Passing Test
Final Output
Failing Test

Conclusion

Cypress is a tool that I highly recommend using because of its ease of use and the amount of amazing features that it packs. It also makes testing, an important part of development, fun and exciting. Overall, in my opinion, it is the best testing framework out there for anything on the web.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store