


Create a Browser Factory with WebDriverManager
January 22, 2020


How to run Selenium WebDriver tests on free GitLab CI
June 18, 2020Introduction
It is common, especially in functional tests on any front-end (web, mobile), to include text validation in our tests to verify that the returned value is the expected one. These validations are user failures or even information about a successfully executed command.
However, it is common to see many professionals using the assertTrue
command instead of assertEquals
to validate the returned text.
This article has the intent to show the difference between the two main methods of verifying any information in an automated test script. I have seen in my career on teams and even on tech assignments, people confused and not using the proper method for their context.
I will show you why this is bad practice!
Differences between assertTrue and assertEquals
Those commands can be found in Java testing libraries like JUnit or TestNG and we call these methods assertions.
assertEquals
The assertEquals assertion will compare the expected information you have to be equal to the actual information from your target (e.g.: a text on a web page).
The assertEquals
method has the following syntax:
assertEquals(actual, expected);
The first parameter actual is the actual result we think is correct. The second parameter expected is the expected result from your target.
Let’s imagine you have an automated test script and you must verify, after a click on a delete icon, if the message is “Record deleted”.
// imagine that this text came from the webpage
String actualResult = "Record has been deleted";
assertEquals(actualResult, "Record deleted");
Notice that the difference between them is the “has been” text inside the actual result, that one came from the webpage. When you have this problem during the test execution you can see an error like this one:
org.junit.ComparisonFailure:
Expected :Record deleted
Actual :Record has been deleted
On the first line, you can see the problem (exception) type: (ComparisonFailure).
On the second line, you can see the expected result, in other words, the text you expected after hitting the delete button.
On the third line, you can see the actual result, in other words, the text that the webpage returned.
The use of assertEquals
makes it much easier to know what the problem is and the difference between the expected and actual results.
assertTrue
The assertTrue assertion will compare the expected result against true or false verification. If your result is true you have success, otherwise, an error will be shown.
The correct way to use the assertTrue is:
boolean hasRestriction = true;
assertTrue(hasRestriction);
In the case of a false value for hasRestriction
attribute an error will be shown:
java.lang.AssertionError
at org.junit.Assert.fail(Assert.java:86)
at org.junit.Assert.assertTrue(Assert.java:41)
at org.junit.Assert.assertTrue(Assert.java:52)
Did you manage to easily identify the problem through the error message?
I didn’t!
We can infer where the problem was generated, but only in this case that we have only one validation. How about the scenario where we have several ones?
The wrong way I’ve seen…
I believe this is the wrong way because I do not have a result where I can, quickly, understand the problem, so I cannot take action right away (fix the test, open a bug, etc…)
String name = "Elias Nogueira";
String city = "Amsterdam";
String jobPosition = "QA Engineer";
String experience = "20 years";
assertTrue(name.equals("Elias Nogueira"));
assertTrue(city.equals("Amsterdam"));
assertTrue(jobPosition.equals("Lead QA Engieer"));
assertTrue(experience.equals("20 years"));
Notice that we have only one difference in the assertion, compared to the String provided: the jobPosition
. If you use the assertTrue
, like the example above, you will see the following error:
java.lang.AssertionError
at org.junit.Assert.fail(Assert.java:86)
at org.junit.Assert.assertTrue(Assert.java:41)
at org.junit.Assert.assertTrue(Assert.java:52)
It’s not so informative, right? To track down this error and understand what is wrong, you must:
- See which data was used on the webpage
- Open the code on the specified line and see the expected result
- See the difference between them
The recommended way…
We have the following example using assertEquals:
String name = "Elias Nogueira";
String city = "Amsterdam";
String jobPosition = "QA Engineer";
String experience = "20 years";
assertEquals(name, "Elias Nogueira");
assertEquals(city, "Amsterdam", city);
assertEquals(jobPosition, "Lead QA Engineer");
assertEquals(experience, "20 years");
This test will fail. Notice, in the error below, the difference between the two compared texts.
org.junit.ComparisonFailure:
Expected :Lead QA Engineer
Actual :QA Engineer
Now it’s easy to understand the real problem and take action without a great effort: I’m expecting the text “Lead QA Engineer” but the actual result, for example, the webpage, is “QA Engineer”.
Example
In the code below you can have a small example comparing different ways to assert a text.
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import org.apache.commons.lang3.StringUtils;
import org.testng.annotations.Test;
public class AssertionTest {
public static final String ACTUAL = "text wrong here";
public static final String EXPECTED = "text right here";
// not recommended
@Test
public void usingAssertTrue() {
assertTrue(ACTUAL.equals(EXPECTED));
}
// best one
@Test
public void usingAssertEqual() {
assertEquals(ACTUAL, EXPECTED);
}
// not recommended
@Test
public void usingAssertTrueAndStringUtils() {
assertTrue(StringUtils.equals(ACTUAL, EXPECTED));
}
}
Conclusion
We have learned the difference between assertTrue
and assertEquals
, and how the use of assertEquals
brings a clear vision of what the error is without opening the code and trying to search for the text differences.
2 Comments
Great post, the main goal when we’re trying to identify an error is get a clear log exception, so when we know how to use correctly assertTrue or assertEquals this contributes to build a code more efficiently.
I agree with this approach. The only exception, for me, is when the text is in a list and you don’t know the position of the text, and I add a description to understand what is wrong. Like this:
assertAll(
{ Assertions.assertEquals(path, result.path) },
{ Assertions.assertEquals(2, result.messages.size) },
{
Assertions.assertTrue(
result.messages.contains(“field1: must not be blank”),
“field1: must not be blank”
)
},
{
Assertions.assertTrue(
result.messages.contains(“field2: must not be blank”),
“field2: must not be blank”
)
}
)