How to add end-to-end tests to a project

How to add end-to-end tests to a project

Also available in 🇪🇸Spanish and 🇵🇱 Polish

Congratulations. Setting end-to-end (E2E) is a pretty advanced topic, and it can bring a lot of value to your project. It has a chance of catching potential issues before merging changes to the main branch—much before getting anywhere close to deployment to production. The earlier you find the bug, the easier it is to fix. E2E enables you to do extensive testing as soon as the changes are available.

What are end-to-end tests?

E2E tests are scripts that interact with an application in a similar way a user would. They open a browser, load an URL, click the user interface (UI) elements such as buttons, and expect some results. Machines execute them, and they are way faster and more reliable than humans. They never get bored.

The only downside—they need precise instructions and can sometimes get more complicated to program than the feature they try to test. Writing the tests is programming, and it’s coupled with the application that is tested, but it’s a task that many programmers are not particularly excited about. If you get good at it, it could become your unique skill that helps you shine at work.

Pick your tooling!

There are plenty of options available for building an E2E suite:

  • Cypress
  • Playwright
  • Protractor
  • Selenium
  • TestCafe

Here, it’s the same as with other tech-stack decisions: it’s good to investigate your options well. Each test you write is tightly coupled with the platform you choose. It is possible to migrate from one testing tool to another, but that would be a project as big as replacing the front-end framework.

My experience is mostly with Protractor, a deprecated Angular-centered solution. I’m currently migrating tests to Cypress, and I’m impressed with the progress in testing tools in those years. What E2E tool would you like to use in your next project? Let me know in the poll:

Simple tests on the local machine

With your first tests, keep them trivial. Use whatever local testing URL you have, and just access it with your scripts. You don’t even need to check any workflow of the application. Just write a few tests, each for different routes, and verify that UI elements appear on the page. For example, you can check:

  • on /login, whether there are input fields for username and password
  • on /product/12, whether the product name is displayed
  • etc.

Even with such easy tests, you can prove:

  1. that the application is starting up and all routes are displayed with key UI elements
  2. that you can develop E2E tests

And with that, the E2E is taking off—the team has some tests, and a member (you) is willing and able to write more tests!

Image description

Get your team on board

You probably will not need to be pushy about it at first. Just make sure everybody is aware that there are E2E tests available, and build up the expectation that each developer should run them before merging stuff to the main branch. At this stage, you will notice all the differences between the local setups of your colleagues—different domains or ports people use locally. You can fix it either by making everybody use the same URL or making the test URL easily configurable, not hardcoded. Both approaches are OK. I went with just making everybody use the same localhost URL; in my case, there was almost no pushback from the team.

The next step is to test the happy path of a workflow—what the application should do when everything is working as expected. You write tests that check if the “add to cart” button actually adds products to the cart, and that “checkout” goes to the payment provider page. Those tests are more complicated to write, but they test critical parts of the application. They should help convince your colleagues about the usefulness of E2E. And your tests are getting a bit more sophisticated.

What next?

If you have any questions or doubts about E2E, feel free to post it in the comments! I’ll read it and do my best at responding. You can continue reading about managing fragile legacy code on my blog.