In this era of digitalization, most of our work is accomplished using computers and mobile phones. All the digital devices are operated using the internet, chances of errors due to loss of internet connectivity, server issues, etc. are higher. These errors are painful to the customers and might bring negative ratings to the applications that may lead to business loss.
It is hence recommended to gracefully manage and handle these errors for a better customer experience. We come across some scenarios while using a website or a mobile application where the requests were not completed as expected and the page load failed, however instead of getting an error we receive a meaningful message that describes the state of the application. Such graceful handling of errors is required for overall robustness and stability of the application.
Let’s take an example of an ATM machine. When we go to an ATM to withdraw money, we expect to get the money, right? However, if we don’t have the money in the account, the ATM should be programmed in a way to show a message that the Bank Balance doesn’t have money, and this is a good example of InvalidBankBalanceException.
What if the ATM was not programmed to handle the InvalidBankBalanceException? It would have handed over the money to people who shouldn’t be receiving it!!
Exception Handling is a key to good software. Pretend that everything is going to fail and try to handle those scenarios as you write your code. If such scenarios are not handled gracefully, it might become users’ pain and eventually will bring a lot of chaos leading to business loss in the later run.
In this blog, we will learn about exceptions and how to handle them. We will also learn about writing exception tests using the TestNG framework.
What are Exceptions?
An Exception is an event that occurs during the application program’s execution and disrupts the normal flow of the application. It represents faults, errors or exceptional conditions that need special handling.
Exceptions may occur due to programming errors, invalid Input, unavailability of resources (example- Server connection down, Network issues, required file missing). When an exception is thrown the application might crash or throw an error and will stop execution.
Why is Exception handling required?
Exceptions need to be handled to ensure the robustness, maintainability and reliability of the application. It can be done by identifying potential exception scenarios, like what happens when a user suddenly turns off the internet on his mobile device while using the application.
Implementing appropriate exception handling mechanisms like using try-catch blocks and providing some meaningful message and recovery options to users when errors come up, are all part of exception handling.
Using appropriate measures to handle exceptions helps prevent application crashes, helps in error diagnosis and debugging and overall enhances the stability as well as provides smooth customer experience.
The following are some of the commonly encountered exceptions during software development
A NullPointerException occurs when the code tries to use or access an object that doesn’t actually exist.
For example, let’s say we have a variable named “address”. If we haven’t assigned any value to this variable(null value) and try to print its length, a NullPointerException will be thrown.
An IllegalArgumentException is thrown when a method or function cannot accept or handle a value or an argument. It means that the value provided does not meet the expectation of that method.
For example, we have a method that calculates the square root of a number. If we provide a negative number to this method, it doesn’t make any sense as square roots are not defined for negative methods in Mathematics. In this case, this method will throw an IllegalArgumentException.
IOException is thrown when there is a problem reading from or writing to a file or stream. This exception is related to input/output operations.
For example, the file is not found in the path or there are issues related to permissions.
An ArrayIndexOutOfBoundsException is thrown when we try to retrieve an element from an array using an invalid index, probably an index that is outside the valid range of the array.
For example, if we have an array of 2 elements and we try to access the element at index position 5, we will get an ArrayIndexOutOfBoundsException.
ClassNotFoundException is thrown when the program tries to use a class that it cannot find or load.
For example, let’s say we are writing the code for a program that uses external or third party libraries and if we forget to include the required dependencies in our project or if the library file is not available in the expected location we may encounter ClassNotFoundException
|An InterruptedException is thrown when a program is interrupted while it is performing its task. This exception is related to thread synchronization and commonly used for dealing with concurrency issues and handling multithreading scenarios.
Importance of handling exceptions in test automation
Exception handling plays an important role in test automation due to following reasons
Helps making the test automation robust
It helps in gracefully handling the errors and continuing execution of the tests instead of stopping the execution abruptly.
It helps the testers and developers in debugging the exact root cause of the test failure by capturing detailed information about the error occurred during the test execution.
Test Flow Control
It helps in controlling the flow of tests by defining alternative paths when the expected conditions are not met.
For example, let’s say, if the tests encounter a NoSuchElementException stating that the element was not found, then instead of tests getting stopped it should log the actual stack trace and continue with the next test.
Overall, exception handling helps to build stable, reliable and maintainable test scripts by gracefully handling the errors and better error reporting.
Demonstration: How to write Exception Tests in TestNG
TestNG provides a simple and easy way to handle expected exceptions. It provides us with the expectedExceptions parameter in the @Test annotation to specify that a specific exception is expected to be thrown during test execution. This helps in verifying that the expected behavior is working as intended.
@Test (expectedExceptions = <Exceptionclass name>.class)
Let’s go step by step and learn how to write exception tests in TestNG.
We will be using Selenium WebDriver here to demonstrate the exception handling.
All the code demoed in this blog is available on GitHub.
First, create a new project with Maven and update the dependencies for Selenium WebDriver and TestNG in the pom.xml file.
Here is the screenshot of the dependencies and properties blog from the pom.xml file.
Dependencies and Properties block – pom.xml
The following two common exceptions in Selenium WebDriver will be demoed in this blog by writing exception tests for it using TestNG:
Test Scenario 1 : Writing Tests for Timeout Exception
A TimeoutException is thrown in Selenium WebDriver when the WebDriver is unable to perform an action within a specified time limit.
We will be using the pageLoadTimeout() method of Selenium WebDriver to set a time limit for page loading. It should ideally throw a TimeoutException once the page fails to load in the stipulated time limit. The page load timeout is given as 3 seconds meaning the page should be loaded in 3 seconds or else the timeout exception should be thrown.
We have already provided the expectedException as TimeoutException.class as a parameter inside the @Test annotation. On execution of this test the TimeoutException should be thrown and the test should be marked as passed.
Let’s now increase the page load time to 10 seconds, here, the page should get loaded within the stipulated time and print the title in the console. The test should fail as the TimeoutException will not be thrown.
Test Scenario 2: Writing Test for NoSuchElementException
A NoSuchElementException is thrown in Selenium Webdriver when the WebDriver is unable to locate a given web element on the web page using the specified selector.
In this test, we will be locating the page title of the pcloudy website . We will be providing an incorrect selector here. Here, the page header has the “h1” TagName however we will provide the TagName as “h3” in the test as the locator for the page header.
It should throw NoSuchElementException. Once the exception is thrown the test will be marked as passed.
On executing the test, it should be marked as passed as NoSuchElementException will be thrown.
Let’s now provide the correct selector with TagName “h1” to locate the page header.
Here, the test should locate the page header and print its text in the console, however, the test should be marked as Fail as NoSuchElementException will not be thrown.
Effective exception handling is a critical aspect of building robust, reliable and stable automated test suites. With TestNG’s exception test feature, we can easily capture, manage, and report exceptions, thereby enhancing the overall quality and stability of the tests.
By implementing the techniques discussed in this blog post, you will be well-equipped to handle exceptions smartly and make your automation tests more effective.
Remember, proactive exception handling is a key factor in building resilient and trustworthy test automation frameworks.