Note: This article was originally published on the Telerik blog.
Nowadays, customers expect the software applications they use daily to provide rich experiences. Gone are the days of simple interactions with a handful of form fields interacting with a basic data store. These days, we have real-time applications with slick user interfaces interacting with multiple services on the cloud.
Because of this desire to include as much helpful functionality to our products as possible, applications can become a complex beast with many moving parts. Testing these applications has also become a challenge, with multiple pieces of functionality working in different ways. Usually, the more functionality an application has, the higher the chance that any modification breaks an unrelated area.
Developers and testers alike need to make sure all the pieces of the puzzle in their applications work well with each other. Typically, teams perform this kind of testing manually, but it's tedious and prone to mistakes. One of the most effective ways to ensure your customers have a good experience while using your applications is with automated end-to-end testing. Alongside other automated tests like those in unit and API testing, end-to-end tests are an essential part of the modern software development lifecycle.
What Is End-to-End Testing?
End-to-end testing, or E2E testing, involves verifying an entire application to ensure that the primary flows work from start to finish. Unlike other kinds of tests that only check a portion of your application, end-to-end tests go through the functionality as a whole. For applications that interact with different services or require complex actions, this type of testing simulates real-world scenarios and validates that what your customers see works as intended.
Benefits of End-to-End Testing and Automation
End-to-end tests provide a few significant benefits over other forms of testing. These tests undergo the same interactions as your customers when using your application under normal circumstances, unlike other tests that only touch smaller sections of the system. This kind of coverage helps ensure third-party services that aren't under our control work as intended with our application. In addition, an often-overlooked benefit is that the barrier to entry for creating end-to-end tests can be lower compared to other tests, thanks to the rise of low-code or codeless testing tools.
Some teams perform these types of tests manually, going through each step to cover their acceptance criteria. As mentioned earlier, this process takes time to complete, and the team can forget to go through the entire process in a rush to finish their work. However, more organizations are now leveraging the power of test automation to free them from the burden of the repetitive, error-prone work brought by manual testing.
Because automated tests go through each scenario quicker than if someone performed the same steps, the entire team can receive rapid feedback when something goes wrong with the application. Automated end-to-end tests also allow testers to perform other high-value tasks that automation can't cover, like exploratory testing. Automation is also beneficial for preventing human error and preventing the QA team from burning out by executing the same mundane tasks day after day.
Challenges of End-to-End Testing
Automating end-to-end testing can make your life much easier, but it does come with its fair share of challenges. If you're not aware of the potential issues when building an end-to-end test suite, it can quickly turn from a dream into a nightmare. Here are five challenges most testers face with end-to-end testing and a few tips on how to overcome each to make you into an E2E testing hero.
Challenge #1: Test Flakiness
End-to-end testing has a somewhat-earned reputation for unstable, flaky tests that fail irregularly. It's incredibly frustrating to have your test suite passing one day with no issues, only to see a test fail for no reason the next day. It's even more frustrating when you rerun your test suite and everything passes like nothing ever happened.
Because end-to-end tests have plenty of moving parts and validate different components throughout a test run, it's difficult to isolate what's causing a problem. This inconsistency leads to lots of lost productivity when figuring out the root cause of the flakiness since it's nearly impossible to replicate the failing scenarios. Even worse, flaky tests lead to teams accepting them, ignoring potential issues and decreasing the value of the automated test suite.
The main challenge of tackling an unstable test suite is finding a solution for your situation. You can take a few steps to help minimize inconsistent tests and eradicate any problems when they surface. There's no "one-size-fits-all" quick fix to eliminate flakiness in your end-to-end tests. These tips serve as an excellent starting point to help you isolate the issue and keep your automated tests running smoothly without any surprises:
- Keep track of test failures: On most automated test suites with flaky tests, you'll often see the same test cases fail again and again. These frequent offenders will yield clues that can help you iron out the instabilities in the application or test suite.
- Make the most of your testing tools: Most end-to-end testing tools have built-in features that can help you rerun failing tests. Besides helping avoid a test run failure, it usually will mark those tests as flaky. For instance, Telerik Test Studio allows you to rerun failing tests in a test list and marks any flaky tests for further investigation.
- Don't ignore flaky tests: Ignoring flaky tests won't make the problem disappear and can hide real issues in your application. When your test suite shows signs of flakiness, take the time to examine your tests and attempt to eradicate the issue before it gets worse.
Challenge #2: Slow Tests
Besides test flakiness, one of the top complaints about end-to-end tests is that they're slow. As mentioned above, end-to-end tests go through your entire stack and exercise every component, both internal and external. It's unfair to compare the testing time of these tests to the speedy unit or functional tests that only validate partial sections of your application.
Still, no one likes to wait around for a test run to finish. Everyone wants their test suite to wrap up as quickly as possible to move on with their day. A slow test suite can drastically reduce the effectiveness of software development and testing teams. For instance, many teams nowadays rely on successful test runs in their continuous integration system before merging code modifications or deploying new features. Having to wait for these builds can grind your work to a halt.
Speeding up your end-to-end tests relies on different factors, like the architecture of your application, any dependencies or reliance on external services, network connectivity and other scenarios. Your strategy will vary according to the application under test and your test suite. The following are some approaches you can take to speed up your tests:
- Mocking and stubbing functionality: Most applications these days connect to multiple external services or have to perform intensive calculations. You can avoid the overhead of these time-consuming functions by using mocks to simulate the behavior of the functionality.
- Set up the correct data as needed: Your tests can spend too much time setting up the application's initial state and cleaning things up after the tests run. Take some time to review the best way to ensure your test scenarios have what they need—nothing more and nothing less.
- Build your tests to run concurrently: Most end-to-end testing tools, such as Telerik Test Studio, allow you to run your tests in parallel or using multiple browsers. However, your scenarios need to work independently to prevent failures caused by relying on a specific order of the test suite. Build your tests with concurrency in mind to take advantage of this benefit.
Challenge #3: Long-Term Maintenance
Given that an end-to-end test goes through longer flows for each of its scenarios, it's no surprise that these test cases have a lot more steps and assertions than most other kinds of tests. For instance, let's say you're testing the flow for an e-commerce web application. A typical end-to-end test would go through searching for a product, viewing the details page, adding it to a cart and finalizing the order. This flow covers a lot of ground, and the test case is extensive.
As you accumulate more and more end-to-end test cases, the test suite will grow and expand significantly. Over time, your team may begin to struggle to keep the tests under control. It becomes difficult to add new tests without interfering with existing ones, and even the most minor changes to the application under test can bring your entire test suite crumbling down. That's why it's crucial to build your end-to-end test suite with long-term maintenance in mind.
A mistake many testing teams make when automating tests is to build as many test cases as possible without thinking about managing them down the road. They focus on automating whatever they can while bypassing any organization and structure in the test suite. Eventually, this mindset leads them down a road where the tests become more detrimental than helpful. To avoid falling into this trap, here are a few things to ponder while you begin creating your end-to-end tests:
- Define your test suite structure from the start: At the start of your test creation journey, take a few moments to decide how you'll structure your tests—directory structure, helper files, page object models and so on. The time you spend doing this at the beginning will pay off in the long haul.
- Reorganize as soon as the opportunity presents itself: When you feel some of your files or code could be organized in a better way, do it as soon as you can to keep your test suite tidy at all times. It's quicker to refactor and rearrange your test cases while you're working on them.
- Know the possibilities and limitations of your tools: Knowing what your testing tools can and can't do will help shape your decisions on how to write your tests in the best way possible for long-term use.
Challenge #4: Gathering Actionable Items
Once you have a few end-to-end tests working, you'll already begin seeing some of the benefits provided by test automation. Your team will have more time to focus on other high-value work, and you'll likely notice a few spots to improve in the underlying application. While the test suite can provide some peace of mind, your team still needs to address any potential issues that stem from its usage.
Far too often, testing teams create a robust automated end-to-end test suite for an application but fail to do anything with it outside of keeping track of failing tests. Of course, part of building a test suite is to make sure nothing breaks. But while end-to-end tests are excellent for surfacing regressions that occur during development, they can also serve beyond just alerting the team of a broken build.
The most useful end-to-end test suites provide the entire team with insight and observability. You'll spot ways to not only detect bugs but also to improve the system as a whole. Using these tests only to track regressions is a lost opportunity for the effort taken to build it. You can prevent wasting these valuable opportunities in a few ways:
- Monitor your test runs: Along with keeping track of broken and flaky tests, observe the sections under test that break often or are slow, which can signal areas that need attention in the underlying application. As the saying goes, what gets tracked gets improved.
- Run your end-to-end tests frequently: Make sure you put your tests to use by setting up a continuous integration system. Come up with the best strategy to run your tests without slowing the team down, like running a subset of your tests when a developer commits new code and running the entire suite at night.
- Keep other roles in the loop: Discuss any issues uncovered by your tests with the broader team. For instance, alert the development team of any areas you notice instability or slowness. Other team members in your organization can provide deeper insight into these issues, and together you can tackle these issues before they become more significant problems in the future.
Challenge #5: Demonstrating Value
Automating end-to-end tests takes a non-trivial amount of time and effort for any project. Even with the advances from testing tools nowadays, there's still tons of work required to get going with testing. Each project has its unique set of needs, so it's not as simple as deciding to build an automated test suite and letting the team loose. Teams have to plan their testing strategies, choose how to allocate resources and find the time to start.
Unfortunately, many organizations are unaware of how automated testing can help the long-term health of their projects. These companies look primarily for a return on their investment, which isn't readily apparent when kicking off automated testing. Since it's difficult to immediately demonstrate the usefulness of end-to-end testing at the start of a project, it can lead to the organization abandoning its efforts too quickly without anything to show for it.
Still, that doesn't mean you can't show how testing helps the entire organization until much later in the process. With some early preparation, you can begin displaying the benefits of what you're creating. If you're in a situation where you feel like you need to produce results and demonstrate the value of end-to-end testing, you can take a few measures to show that your work is helping everyone involved in the project:
- Make your test results visible to the team: Show the entire team that your end-to-end test suite is working hard by displaying test run results using tools like Slack, emails, dashboards or any other place the team can see them quickly and effortlessly.
- Generate reports to show the health of your test suite: Almost all testing tools these days can generate well-organized reports that show how your tests perform. For instance, Telerik Test Studio has a reporting section where you can check results and observe trends from your test runs.
- Keep track of how your tests improve your project: Come up with a list of valuable metrics you can measure for the project, like defects found before a release, development velocity and so on. Once you have a list of metrics, take a baseline measurement and see how they improve over time as your end-to-end test suite expands.
End-to-end testing is a vital part of a high-quality software application. It complements other forms of testing, such as unit testing or functional testing, by providing additional coverage and exercising the system as a whole. An end-to-end test can uncover issues that other isolated tests might not expose and works best if you have an application with different services interacting with each other.
However, the total amount of coverage provided by end-to-end tests also means increased complexity in managing them. The tests can be unstable and slow, requiring extra attention to keep them running smoothly. It's also challenging to demonstrate immediate value since they take longer to put into action. By following the tips listed in this article, you'll reduce these issues and provide a boost in quality across the entire project.
Automating end-to-end tests can be tricky and hard to show your organization that they're working. You'll need more time to plan, implement and execute. Once running, you'll also have to ensure they're working for your needs instead of slowing everyone down. But when done right, these tests will save your team countless hours of manual testing and make your application and team better for it.