No company would release a piece of software without testing it. But there are many ways of testing software. End to end testing is one way. It might even be the most important way, though often the most time- and resource-intensive one. Luckily, there are ways to automate end to end tests.
In today’s post, we’ll clarify not only what end to end testing is, but how it fits into an overall testing strategy that can benefit every organization.
What Is End To End Testing?
In theory, end to end testing is the process of testing a piece of software from start to finish as it will be used by the actual users. For a web application, you would start a browser, navigate to the correct URL, use the application as intended, and verify the behavior. In the case of desktop application, you would start up the application, use it, and verify its behavior too. If you’re testing an API, you would make calls just like the real clients would do.
Whatever your piece of software, the idea is to run the application with all of its dependencies: database, external services, metrics, logging, etc. This can still be in a test environment, separate from the production environment. But ideally, this test environment represents the production environment as closely as possible.
You may have noticed that I started this section with the words “in theory.” This is because it might not always be possible to run the application without real side effects, even in an isolated testing environment. This can be the case when external dependencies only exist in the production environment.
For example, in an industrial setting, it’s not uncommon to have only production PLCs (computers that drive industrial machines). You don’t want your end to end tests influencing the machines in the production environment. So in this case, you’ll have to be creative and stop the commands from going to the PLCs, while still verifying their correctness.
There are many situations where you might want to “fake” certain components of your overall application for your end to end tests. But in end to end tests, you want to reduce these fake components to a minimum. Read on to find out why.
Why Do We Need End To End Tests?
Software can and should be tested on many levels. At the lowest level, we have the unit test. This is where programmers write a small routine to test the routine they are actually writing. All these small routines together will form your application. But it’s useful for the programmers to write these small test routines so they can have fast feedback on whether or not they are implementing a feature correctly.
However, just verifying that all those small pieces work isn’t enough. It doesn’t ensure that they work correctly together. This is where integration tests come into play. In integration tests, two or more components are used together in a test and the result is verified.
But even if all these tests run perfectly fine, you could still have bugs or unmet requirements.
First of all, if you have a UI, unit and integration tests don’t cover the UI. Is the UI structured correctly? Is it a pleasant experience? Are all the necessary elements in place? Can the user achieve what they want to achieve? These types of questions can only be answered by an end to end test.
A second reason why end to end tests are necessary is that there are so many moving pieces in modern software: servers can cause applications to behave differently, configuration must be set up correctly, and external dependencies influence our application. Testing separate components will not cover all this.
Does this mean unit and integration tests don’t have value? Definitely not. Unit, integration, and end to end tests all play an important role in an overall testing strategy.
The Overall Testing Strategy
Testing software is an activity that happens on multiple levels, by multiple people in different roles. Developers test their code with unit and integration tests, while testers work together with developers to define test scenarios that they’ll run manually or automatically.
End to end testing is the category of tests that’s drawn at the top of the testing pyramid. The testing pyramid gives us a guideline of how many types of tests we should have. Because they are easy to write and maintain, and fast to run, it’s valuable to have many unit tests. As we move up the pyramid, our tests start using more pieces of our application. These tests become slower to execute and harder to maintain.
That’s why there are usually fewer end to end tests than there are unit tests. But the end to end tests are still featured in the testing pyramid. In the section above, I’ve explained why they’re still valuable.
The different categories of tests each have their unique value in the overall strategy of testing your software. But many organizations still perform the end to end testing manually—even when there are tools that can automate end to end tests. With automated end to end tests, you can add and maintain more tests in less time.
Using End To End Tests
It isn’t always clear how to start with end to end tests. Many companies manually test new features and leave it at that. But this allows bugs in features that previously worked to go unnoticed.
The first step is to identify test scenarios. Get together with business owners, developers, and testers and think about some scenarios that you want to test before every release. This doesn’t have to be an exhaustive list. It’s better to have a minimal set running first, and then expand on it later.
Using this list, you can now map out the different steps in each scenario. Write down the steps that need to be performed and the expected results.
Notice that we still haven’t automated anything yet. You can already use these scenarios to perform manual end to end tests. Of course, the real value lies in automating these tests. But if, for some reason, it can’t be automated (yet), at least you have some end to end tests to get started with.
However, a next step will be to automate these tests. An application without a UI like a REST API can be tested by executing a series of calls to the API and checking the results. Tools like Postman or a Cucumber library are useful here.
UIs are traditionally harder to run in automated tests. Tools like Selenium can run automated UI tests, but easily lead to fragile tests. They also require a decent amount of work to build and maintain. With Testim, you can create tests just by using your application. Testim records your actions and can then run those actions as an end to end test. Testim is unique because it will learn about your application. If you change your UI, Testim is able to notice this and adapt the test. This leads to less fragile tests, allowing you to focus more on improving your product.
Once you have a few end to end tests set up, make sure they run in your CI process. This provides valuable feedback to developers so they know if they broke anything with a code change. As you experience the value of end to end tests, you can then repeat the process: identify test scenarios, list the steps, and automate the test.
The Importance of Automation in a Software Testing Strategy
In the previous section, we’ve briefly mentioned the value of automating your tests. We’ll now delve into that topic in a deeper way.
Automated Testing Helps You Not Only To Save Time
So, why is automated testing so important? A correct but incomplete answer would be: “to save time.”
Sure, automated testing does help you save a lot of time, which is already a huge benefit in itself. But the real value of automated testing is way deeper than that. We can summarize such importance in a single sentence: without automated testing, you can’t deliver high-quality software quickly. Period.
That’s not to say that automated testing is the only factor that leads to software quality. You should also be aware of the main code smell, adopt coding best practices, and use processes—such as code reviews—and tools—for instance, linters—that can help improve the quality of your code.
But without automated testing, you’re pretty much hopeless in your struggle against software quality issues, particularly the ones we call regressions.
Software Suffers From Regressions
What are regressions? Well, do you know those situations when you fix a defect—or add a new feature—and then another thing stops working? That’s a regression.
Though physical systems can suffer from regressions, software is particularly prone to them, due to its very nature. Since any part of the application can interact with any other part, even the smallest change to a codebase can, in theory, cause unintended consequences to another seemingly unrelated part.
Automated Tests Can Save You From Regressions
Even though we could list many reasons why your software testing strategy should include automation, protecting your apps against regression is certainly one of the most important ones. And why is that?
Well, think about it. Since software applications are so susceptible to regressions, there’s really no way to have the bare minimum of confidence in the quality of your app unless you completely test it after each and every change. No matter how small or insignificant it is or appears to be: if you made a change to the code, you’ve got to test everything again.
Now think about doing this manually and you’ll quickly realize that we’re talking about a sishypeahn task. Even if you could manage to pull it off, the process would be so slow that all of your competitors would beat you to market.
So, aggressively pursuing automation in your test strategy is the only way you can have confidence in the quality of the code you ship while maintaining the ability to ship it as fast as you need.
End To End Testing Example
What would an example of (manual) E2E test look like? That’s what we’ll cover now. To do that, we’ll use the website demoblaze.com, which is a demo site for testing purposes.
To perform the test, you can follow the steps below:
- Go to https://demoblaze.com.
- Click on the first product (the Samsung Galaxy s6 phone, with a price of $360.)
- On the product’s page, ensure the name and the price of the product are correct.
- Then, click on the “Add to cart” button.
- Ensure you see an alert with the message “Product added.”
- Click on the “Cart” link, in the main navigation menu.
- Ensure the cart has a single product with the correct info, and the total is $360.
- Finally, click on the “Delete” link and verify whether the product got deleted.
This is a simple test case for testing whether the cart functionality of an e-commerce site works as intended. With a robust codeless test automation tool like Testim, automating a test like this one would be a breeze.
Which Layers of an App Are Involved In E2E Testing? A Simple Checklist
You’ll often notice that there seems to be some overlap between different kinds of testing. Though in definitions you might find on Wikipedia and even blog posts like this one things might look very clear, the reality is often messy.
When it comes to E2E testing, you might discover that the lines between it and other forms of testing might often be blurred. For instance, how does E2E testing differs from UI testing? After all, end to end testing might require entering text into fields and clicking on links and buttons. Where do you draw the line?
Though a little bit of overlapping is inevitable, keep in mind the definition of end-to-end tests: they test the application as a whole, going from one end (the user interface) to the other (the database or other storage solution.) So, to determine whether you’re dealing with a real end to end test, you have to ensure it interacts with all layers of your app. You can use the following checklist:
- Presentation (or UI) layer. All E2E tests necessarily interact with the UI layer. Keep in mind that this isn’t necessarily a graphical user interface (GUI.) It could be a command-line interface, a text-based interface. The endpoints of a REST API could also be considered a type of user interface.
- Domain logic layer. A true E2E must interact with the app’s real domain logic. Imagine an application that consists of an Angular frontend that consumes a REST API. Now suppose you have some tests that drive the application through the frontend while mocking the API with a fake one for testing purposes. Though such tests would be valuable, they would not be considered E2E tests.
- Persistence layer. Unlike other types of tests such as unit testing, end to end tests talk to the real persistence solution. The persistence solution doesn’t necessarily have to a database; we could be talking about session/cooks or even the browser local storage. All that matters is that it’s the real storage solution used by the application.
How would our example from the previous section fare against the checklist above?
- Does it interact with the presentation layer? Yep, definitely.
- Does it involve domain logic? Sure. Had we added another product worth 140 dollars, the total amount would have to be updated to $500. That’s domain logic.
- What about the persistence layer? The site does keep the products we’ve added to the cart while navigating between pages, so there’s definitely some persistence happening.
Test Your Software
This article aimed to clarify not only what end to end testing is, but also why it’s necessary. End to end testing accompanies other types of tests like unit and integration tests. It fits in an overall testing strategy that every organization will benefit from. This rings especially true if you automate your end to end tests.
This post was written by Peter Morlion. Peter is a passionate programmer that helps people and companies improve the quality of their code, especially in legacy codebases. He firmly believes that industry best practices are invaluable when working towards this goal, and his specialties include TDD, DI, and SOLID principles.