Assertions in UI tests
UI tests consist of two primary components: UI interactions and assertions. UI interactions include click and type actions that a user may perform.
Assertions are assumptions on the application being tested that must always be true. Assertions verify the existence or contents of UI elements on the screen.
For example, an UI test for a login system might include UI interactions for writing credentials and clicking on a sign-in button, but would use assertions to verify the existence of that button, the contents of the username field or to check if we got redirected or not to the main/welcome page correctly.
Assertions help testers to check if the application under test behaves as expected or not. They compare expected results to actual results.
In test automation, assertions are checkpoints that determines whether an automated test succeeded or not.
There are different types of assertion in UI testing, such as text content assertion, UI element existence assertion, or element property assertion.
In this article, we’re going to talk about various assertions and give examples with Java and Maveryx.
Working with assertions
Let’s take a login application for our example
We would verify a user will be able to login with a valid username and valid password.
First of all, we would have to navigate to the login page. Once there, we would check if the current page is the login page.
Then, we would enter our username and password. Before going on, we would check if username and password were filled in correctly.
Next, after asserting something about the “Sign In” button existence, we would click it to log in into the system.
Finally, we would want to check that we were redirected from the login form to the application’s main/welcome page.
The test case will result in the following steps:
1. navigate to Login Page
2. check for the presence of ‘Member Login’ text element
3. check the username field was empty
4. enter username
5. check the username field contains the entered value
6. check the password field was empty
7. enter password
8. check the password field contains the entered value
9. check for the presence of ‘Sign In’ button
10. click sign-in button
11. check for the presence of ‘Welcome!’ text element
Once we’ve got our test case, we can simply convert it into a test script:
public void loginTest() throws Exception {
Bootstrap.startApplication("Chrome");
new GuiBrowser().navigateTo("https://localhost:8080/login");
GuiHtmlElement title = new GuiHtmlElement(AccessibleRoleMaveryx.WEB_H2);
assertEquals("Member Login", title.getText());
GuiText username = new GuiText("Username");
String usnm = "maveryx";
assertTrue(username.getText().isEmpty());
username.setText(usnm);
assertEquals(usnm, username.getText());
GuiPasswordText password = new GuiPasswordText("Password");
String pwd = "N6$J#3ug";
assertTrue(password.getText().isEmpty());
password.setText(pwd);
assertEquals(pwd, password.getText());
GuiButton ok = new GuiButton("Sign In");
ok.waitForObject(1, 1);
ok.click();
GuiHtmlElement message = new GuiHtmlElement(AccessibleRoleMaveryx.WEB_H1);
assertEquals("Welcome!", message.getText());
}
Let’s walk through the test script.
1) Bootstrap.startApplication("Chrome");
2) new GuiBrowser().navigateTo("https://localhost:8080/login");
The above two lines launches the browser (1) and navigates to the login page’s URL (2).
Once there, we can simply check that we got landed on the login page if we can find an HTML H2 header containing the text “Member login” (3).
GuiHtmlElement title = new GuiHtmlElement(AccessibleRoleMaveryx.WEB_H2);
3) assertEquals("Member Login", title.getText());
The statement assertEquals(expected, actual) verifies the value of the H2 header element getting the actual value, title.getText(). Then it is matched with the expected value. If the assertion condition is not met (the values don’t match) then it will throw the org.junit.ComparisonFailure exception.
Before entering the username, we check if the text field is empty (4). Then we type the username (5) and check if the value was entered (6).
GuiText username = new GuiText("Username");
String usnm = "maveryx";
4) assertTrue(username.getText().isEmpty());
5) username.setText(usnm);
6) assertEquals(usnm, username.getText());
At point 6, alternatively we can use:
assertTrue(username.getText().equals(usnm));
Repeat the same for the password.
Before entering the password, we check if the password field is empty (7). Then we type the password (8) and check if the password was entered (9).
GuiPasswordText password = new GuiPasswordText("Password");
String pwd = "N6$J#3ug";
7) assertTrue(password.getText().isEmpty());
8) password.setText(pwd);
9) assertEquals(pwd, password.getText());
The following block checks the existence (10) of the “Sign In” button and clicks it (11).
GuiButton ok = new GuiButton("Sign In");
10) ok.waitForObject(1, 1);
11) ok.click();
The function waitForObject() checks for the presence (waits to see) of the “Sign In” button on the web page. If the button is not present it returns ObjectNotFoundException.
After that, it’s simply one line to check and see that we got redirected to the main/welcome page correctly. We can be sure that we have, if we can find an HTML H1 header containing the text “Welcome!”.
GuiHtmlElement message = new GuiHtmlElement(AccessibleRoleMaveryx.WEB_H1);
assertEquals("Welcome!", message.getText());
To verify that we got redirect to the main/welcome page, we can also check the current page URL:
assertEquals("https://localhost:8080/login/welcome", new GuiBrowser().getCurrentPageUrl());
You are now ready to run the test.
At runtime, if an assertion fails, the test will be aborted and the remaining test steps will not be executed. Assertions are designed in a way that makes the test fail if the assertion fails.
How to Write Better Test Assertions
Before concluding, we would give you two golden rules in using assertions.
1) “One assertion, one condition.” Don’t aggregate multiple checks in one assertion. It is tempting to aggregate multiple checks in one assertion. Don’t write assertions which check conditions that you could split to multiple assert statements. Always check the simplest condition possible.
Any gain in speed when writing complex conditions is lost when someone needs to debug why an assertion fails. The true value of an assertion is often realized only when it fails.
2) “Provide enough data when an assertion fails”
When writing your UI tests, it is important to provide detailed data when an assertion fails, so that someone looking at a test report can most easily see what failed and begin to figure out the “why” for fixing the bug.
You could syntactically be okay with something like this:
assertTrue(username.getText().isEmpty());
However, that assertion will only show up as a failure in a report with no context other than a line number. An improved message looks like this:
assertTrue("The Username field is not empty.", username.getText().isEmpty());
Java Assertions Libraries
There are many Java assertions library you can use.
Maveryx by default uses the JUnit assertions, but alternatively you can use:
– Hamcrest: an assertion framework to write matcher objects allowing rules to be defined declaratively
– AssertJ: fluent assertions for Java
– Truth: an assertions library designed to make test assertions more flexibly and failure messages more readable