Author: Alexis Lazzuri - Frontend Leader @ NextDots

End to end testing (e2e) is a type of software testing which purpose is to validate the correctness of our application, not only from its internal functioning but also regarding its integration with external systems or interfaces, such as if the app were in a production environment.

In other words, with e2e testing we could simulate real-time testing using production-like data and settings, to validate the entire app flow as if it were being used by a real user.

As technology grows, software systems and applications become more and more complex. Also, different kinds of new integrations and external connections are included in our applications all the time. That makes our app entirely dependant on the proper functioning of several ‘sub-systems’ within it, some of which could be controlled by third-party providers. In that case, we won’t control the performance of such third-party resources, but in case one of them fail, that could collapse our entire application.

For the success of our application, the chance to face a whole collapse in the event of any change in the internal structure or any third-party dependency is a risk that we couldn’t afford. But, as we said before, that risk could be mitigated by the use of od e2e. e2e verifies the complete system flow, which is a big difference if compared with unit tests or integration tests, that just could be used to cover certain parts of our application. Thus, e2e increases test coverage of various sub-systems of our application, helps detect issues with sub-systems and increases confidence in the overall software product.

Difference between functional tests and e2e

Functional Tests End-to-End Tests
Testing is limited to one
single piece of code or application.
Testing crosses multiple applications
and user groups.
Ensures the tested software meets
acceptance criteria.
Ensures a process continues to work
after changes are made.
Tests the way a single user engages
with the application.
Tests the way multiple users work
across applications.
Validate the result of each test for
inputs and outputs.
Validate that each step in the
process is completed.

It is important to note that we could also use QA for testing our application before making any release to production. Still, in that case, QA shall perform the test based on the status of the app (and its third-party dependencies) at the time QA’s test is performed. If the environment or the dependencies of our application changes, we will need a new QA test to check the updated state of our app.

Notwithstanding the above, we are not claiming that e2e should replace QA. QA is always a required part of any development process. What we are saying here is that e2e should come before QA to help developers detect bugs in the early stage and to make QA cycles faster. As e2e tests are written once and could be maintained while our application grows up, we will always have the chance to check if our app is performing at any time. If we are developing a new feature, we could test how the application will react to it before submitting the app to QA, and if a bug appears, we could fix it as necessary to pass the tests. And once our feature is in production, we could periodically check the proper performance of our app and, if an error cames up, we could identify it and fix it as soon as detected. That will help developers to have fewer errors in the code, which will result in QA rejecting fewer tests and the owner having the chance to release new features faster.

In order to create our e2e, we will need the following tools:

  • Test runner: this is the engine we will use to run and generate tests.
  • Assertion Library: It gives us the logic of what we hope will happen to our elements.
  • Headless Browser: It provides us with an environment in which we could run our project and do user tests.

We could find some tests libraries that provide us with the tools mentioned above. Let’s take a look of them.

Test Libraries.


SELENIUM is a free (open-source) automated testing framework used to validate web applications across different browsers and platforms. You could write Selenium Test Scripts in multiple programming languages like Java, C#, Python, etc. Selenium has been around the most extended test tool available for developers (since 2004) and has established itself as the most popular web browser automation tool.

Selenium supports various browsers like Chrome, Mozilla, Firefox, Safari, and IE, and you can very easily automate browser testing across these browsers. Using Selenium WebDriver, you can see live, automated tests being performed on your computer screen.

Selenium is yet a highly portable tool that supports and can work across different operating systems like Windows, Linux, Mac OS, UNIX, etc. You can create Selenium test suites over any platform like Windows and can execute the same test suite on another platform, for example, Mac or Linux. This feature enables developers and software testers to quickly write test automation scripts without laying much emphasis on the platform on which it will run.


CYPRESS is a front end testing tool constructed for modern web applications. Unlike other testing tools (like Selenium) that operate by running outside of the browser and executing remote commands across the network, the Cypress engine directly works inside the browser. It enables Cypress to listen and modify the browser behavior at run time by manipulating DOM and altering network requests and responses on the fly.

Cypress is based in Mocha and Chai (one of the famous assertion libraries in JavaScript), and it adheres to the same style of writing test cases as will be used by any other JavaScript-based framework (like Jest).

Along with the test script runner, Cypress provides you a visual interface to indicate what all tests and which all commands are running, passed, or failed. It allows us to test highly interactive applications and carry out different tests.

Things we could do with Cypress:

  • Manipulating the DOM.
  • Asserting that if some element is available or present on the screen
  • Reading or writing data into/from fields
  • Submitting forms and even redirecting to a different page without actually making direct modifications to your code.


Puppeteer is a Node library which provides a high-level API to control Chromium or Chrome over the DevTools Protocol. This testing library was developed by the Google Chrome dev team and is JS-fully-based, super useful and easy tool for automating, testing and scraping web pages over a headless mode or headful either. Despite at the begining Puppeterr only allowed tests in Chrome, currently there is a package that allow runing puppeteer tests in Firefox.

Using Puppeteer we could simulate User’s interaction with the Browser to test features.

Here are the things we could do with Puppeteer:

  • Generate screenshots and PDFs of pages.
  • Crawl a SPA (Single-Page Application) and generate pre-rendered content (i.e. “SSR” (Server-Side Rendering)).
  • Automate form submission, UI testing, keyboard input, etc.

Some advantages of Puppeteer:

  • The setup is easier than other testing tools like Cypress or Selenium.
  • Puppeteer comes bundled with the browser, and it doesn’t need a browser driver.
  • Tests are easier to be written with Puppeteer if compared with other testings tools like Cypress or Selenium.
  • Puppeteer is more intuitive than others.
  • Puppeteer test seems to be faster in its execution if compared with Selenium.

Some disadvantages:

  • Puppeteer is not a framework (like Selenium) but just an API which allows us to control Chrome browser.
  • Puppeteer supports only test in Chrome and Firefox. Other test tools like Cypress support multiple browsers.
  • Puppeteer does not have any dashboard like Cypress.
  • Puppeteer has promises so we need to handle them with async logic. Other tools like Cypress automatically waits for commands and assertions before moving on.

Wrap up

We consider that implementing e2e in our app will contribute to having a high-quality development environment, complementing QA testing, and helping developers to write better code. It is true that implementing e2e is not cheap and could be time-expensive. Still, if you choose that option, you will save future time avoiding multiple QA tests and bug-fixing and will have the chance to implement and release your product (or any feature thereof) in a quicker way.. All the testing libraries we covered above have their pros and cons, and the decision about choosing each one of them will depend on the different needs of each project and development environment.

Contact us for new project o hire developers on-demand!