Negative Testing with Selenium
Negative Testing with Selenium
Sometimes our automated tests need to dig a bit deeper. Sometimes, we need to validate more than just the happy path. But sometimes, we need to do negative testing. This is an easy task for a human mind, but how do we tell a script to determine how something reacts when the unexpected happens? That is what we’ll be covering today in this article.
First of all, we need to know what negative testing is. According to SmartBear, a negative test ensures that the application under test can handle invalid actions gracefully. In other words, negative tests check what happens when things go wrong.
Some negative tests are easier to implement than others. A negative test must often validate that an error pops up if the user does something considered invalid. That’s easy to find with Selenium and shouldn’t be a headache. But what happens when you want to ensure something doesn’t show up? Let’s say there’s a visual component currently not in the DOM, and you want to ensure it doesn’t show up. That’s where it gets tricky.
Today we’ll see a few ways to do negative testing with Selenium, including that tricky scenario. For this article, we will be using Instagram’s website. We’ll be creating some negative tests for it.
Another thing worth pointing out is that we will use the Page Object Model as shown in this tutorial. Please check this tutorial out if anything about the samples below seems confusing.
Character Limit Tests
There a two ways a character limit can be implemented on a website. They can either show an error when the user exceeds the character limit, or they can prevent the user from writing after they reach the limit. Since the “showing an error” approach is verified in the same way regardless of the error, we’ll focus on how to test if the site is preventing the user from writing after they reach the limit.
If we look closely at Instagram’s Username field, it does just this. The user is only able to input 30 characters.
The idea for this is that we will locate the UserName field, send more than 50 characters to it, and then we’ll capture its data to check if the field contains more than 30 characters or not. So let’s do this step by step.
- First, we need to locate our element in our Page Object. We will do this with the following code.
import pytest as pytest from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait class SignUpPage: def __init__(self, driver): self.driver = driver . . . self.username_textbox = WebDriverWait(self.driver.instance, 5).until( EC.visibility_of_element_located(( By.NAME, "username"))) . . .
- Now we need to send characters to it. We’ll create a method in our Page Object to send the keys to the WebElement. Then we’ll call this method from our Test Case file.
Our Test Case file will look like this by now. The strings file you can see in the code is just a file with all the strings we will use. At the moment, this is how it looks.
- Now that we have our element and part of our test, we need to write the method that will validate if the field has the character limit implemented or not. We will do this by getting the “value” attribute of the username textbox. Then asserting if the count is equal to what we need.
- Now we can run our test with the following command, which will work fine.
.python3 -m pytest testcases/test_instagram.py -k test_verify_username_character_limit
Missing Required Field Tests
Most forms deal with required fields in one of 2 ways. They either show the user in real-time that a field is missing once they pass it or the errors once the user submits the form. Either way is validated in the same way from Selenium’s point of view. In this case, we’ll see a case of a form that shows the error after the user submits the form.
We will run this negative scenario by writing some invalid information in the “Mobile Number or Email” field, leaving the rest of the fields alone, and then clicking the “Next” button.
- First, we need to locate our element in our Page Object. We will do this by adding this WebElement to our Page Object:
- Now we need to send characters to this field. Like in the previous scenario, we’ll need a method in our Page Object that writes on the WebElement and a method in our Test Case. For this, we’ll add this method to our Page Object:
Then we’ll add this to our Test Case
- The third step is to add the method that will validate that the error is present. In this case, the error is shown with a <span> whose class is “coreSpriteInputError gBp1f“. What we’ll do is that, since this error shows up in several fields and doesn’t have a unique specifier, we’ll go by count. We know that in this scenario, we should get three errors. This will depend on the site you’re testing. We’ll also need a method that clicks on the “Next” button to make the errors appear. For this, we’ll need to add these methods to our Page Object:
Our Test Case will now look like this:
- Now we need to run our test and watch it pass!
python3 -mpytest testcases/test_instagram.py -k test_verify_required_fields
Missing UI Component Tests
A good example of this case is when we open this Instagram site from a browser that has never opened it before (like the clean session Selenium starts for every test), we would not want to see the login screen. But how can we confirm this via Automation?
The thing is, Selenium cannot look for something that’s not present in the DOM. So how do you check if something doesn’t exist? Well, looking for it and letting the search fail. The tricky thing about this is that when the search fails, we will get an exception, and our test will fail. The fix for this is handling that exception and if we get the exception that we’re expecting, then continuing with our test.
- In this case, we will be writing directly the method that will do the validation. The idea is that we will try to find a button with the text “Login,” and if we can’t find it, we’ll mark it as passed. If we find it, we’ll do an assertion and mark it as failed with a message. For this, we need to add this method to our Page Object:
- Now, we just need to run our Test Case
python3 -m pytest testcases/test_instagram.py -k test_login_button_is_not_present
And with this, we are done! If you want to check out the source code, you can find it here.
Mike Arias wrote this article.
Senior Software Testing Engineer of TechAID.
OTHER POSTS YOU MIGHT LIKE
API Testing Tools: An Example-Based Guide
API Testing Tools For API testing, there are many tools out there that let you perform the test and collect the results. In this article, We will focus on three tools by showing how to make a request using the Trello API. But before…
If Clauses vs. ASSERT Statements – When to use which one?
If Clauses vs. ASSERT Statements – When to use which one? If clauses and ASSERT statements serve different, yet similar functions. This article aims to establish once and for all when to use “if” and when to use “asserts” in our test cases. There will…