Site icon Vinsguru

AssertJ Custom Assertions For Selenium WebDriver

Overview:

In this tutorial, I would like to show you how to create use AssertJ Custom Assertions for Selenium tests.

AssertJ:

AssertJ is a simple assertion library for Java using which assert statements can be written in fluent style.

Fluent APIs make your code readable and easily maintainable. We already have seen few articles on designing Page Objects and Business Workflows in fluent style. In this article, Lets see how we could include fluent assert statements for your automated tests using AssertJ library. If you take a look at the examples in this articles, You could easily compare that with your JUnit/TestNG assert statements and understand the benefits of using AssertJ.

Maven:

To include AssertJ in your Java project, include below maven dependency in your pom file. Check the maven repo here for the latest versions.

<dependency>
    <groupId>org.assertj</groupId>
    <artifactId>assertj-core</artifactId>
    <version>3.9.1</version>
    <scope>test</scope>
</dependency>

Once you have included in your pom file, do the below static import in your test classes.

import static org.assertj.core.api.Assertions.assertThat;

Examples:

Lets start with few simple examples.

boolean actual = false;

assertThat(actual).isTrue();
//or
assertThat(actual).isEqualTo(true);
@Test
public void stringCompare(){

    String expected = "Test Automation Guru";
    String actual   = "test automation guru";

    assertThat(actual).isEqualTo(expected);

}

Running the above code produces below output.

java.lang.AssertionError: 
Expecting:
 <"test automation guru">
to be equal to:
 <"Test Automation Guru">
but was not.

You can also include some meaningful description for your assert statements.

assertThat(actual).as("AssertJ String Comparison Check").isEqualTo(expected);

The above statement will display,

java.lang.AssertionError: [AssertJ String Comparison Check] 
Expecting:
 <"test automation guru">
to be equal to:
 <"Test Automation Guru">
but was not.
assertThat(actual).isNotNull()
                  .isNotBlank();
assertThat(actual).doesNotStartWith("Test")
                  .doesNotEndWith("Guru")
                  .doesNotContain("automation")
                  .contains("assertj");
assertThat(10).isBetween(5,15);

assertThat(10).isPositive()
                     .isGreaterThan(8)
                     .isLessThan(12);
LocalDate today = LocalDate.now();
LocalDate yesterday = LocalDate.now().minusDays(1);
LocalDate tomorrow = LocalDate.now().plusDays(1);

assertThat(today).isAfter(yesterday).isBefore(tomorrow);
assertThat(today).isAfter("2015-01-01").isBefore("2016-12-31");
Date today = new Date();
assertThat(today).hasMonth(3)
        .hasDayOfMonth(24)
        .hasHourOfDay(10)
        .hasMinute(15);
List<String> list = new ArrayList<>();
list.add("test");
list.add("automation");
list.add("guru");

assertThat(list).hasSize(3)  //passes
                .containsAnyOf("automation", "guru")  //passes
                .doesNotContain("test");   //fails as it contains test
//expected
List<String> expected = new ArrayList<>();
expected.add("guru");
expected.add("automation");
expected.add("test");

//actual
List<String> actual = new ArrayList<>();
actual.add("test");
actual.add("automation");
actual.add("guru");

//no change in the order check
assertThat(actual).containsExactly(expected.toArray(new String[expected.size()]));

It produces below output.

java.lang.AssertionError: 
Actual and expected have the same elements but not in the same order, at index 0 actual element was:
  <"test">
whereas expected element was:
  <"guru">
//any order check
assertThat(actual).containsAll(expected);
//OR
assertThat(actual).containsExactlyInAnyOrder(expected.toArray(new String[expected.size()]));
This is a sample file I am going to use for assertj comparison.
This file has multiple lines.
AssertJ is a cool library.
If you have not realized yet, may be you will now!
File expected = Paths.get("/home/vins/expected-file.txt").toFile();

assertThat(expected).exists()
                    .isFile()
                    .hasExtension("txt");
File expected = Paths.get("/home/vins/expected-file.txt").toFile();
File actual = Paths.get("/home/vins/actual-file.txt").toFile();

assertThat(expected).hasSameContentAs(actual);

List<String > expected = Files.readAllLines(Paths.get("/home/qa/expected-file.csv"));
List<String > actual = Files.readAllLines(Paths.get("/home/qa/actual-file.csv"));

assertThat(actual).containsAll(expected);
String expected = "Test Automation Guru";
String actual = "Test Automation Guru";

SoftAssertions.assertSoftly(s -> {
    s.assertThat(actual).doesNotContain("automation");
    s.assertThat(actual).doesNotStartWith("Test");
    s.assertThat(actual).doesNotEndWith("Guru");
    s.assertThat(actual).isEqualTo(expected);
});

It produces below output.

The following 2 assertions failed:
1) 
Expecting:
  <"Test Automation Guru">
not to start with:
  <"Test">

at AssertJTest.lambda$stringCompare$0(AssertJTest.java:31)
2) 
Expecting:
  <"Test Automation Guru">
not to end with:
  <"Guru">

at AssertJTest.lambda$stringCompare$0(AssertJTest.java:32)

AssertJ Custom Assertions:

As you have seen above, AssertJ covers most of the data types for your assertions. It might be more than enough for our Selenium automated tests. For example, if we need to check if a WebElement is displayed.

WebElement element = driver.findElement(By.id("id"));

//isDisplayed check
assertThat(element.isDisplayed()).isTrue();

However, it would be cool to have a separate assertion library for WebElement – to maintain a well readable and reusable code.

To implement your own assertion, create a new class by extending AbstractAssert class. Check this below sample for WebElement assertion.

public class WebElementAssert extends AbstractAssert<WebElementAssert, WebElement> {

    public WebElementAssert(WebElement webElement) {
        super(webElement, WebElementAssert.class);
    }

    public static WebElementAssert assertThat(WebElement webElement){
        return new WebElementAssert(webElement);
    }

    public WebElementAssert isDisplayed(){
        isNotNull();

        //check condition
        if(!actual.isDisplayed()){
            failWithMessage("Expected element to be displayed. But was not!!");
        }

        return this;
    }

    public WebElementAssert isEnabled(){
        isNotNull();

        //check condition
        if(!actual.isEnabled()){
            failWithMessage("Expected element to be enabled. But was not!!");
        }

        return this;
    }

    public WebElementAssert isButton(){
        isNotNull();

        //check condition
        if(!(actual.getTagName().equalsIgnoreCase("button") || actual.getAttribute("type").equalsIgnoreCase("button"))){
            failWithMessage("Expected element to be a button. But was not!!");
        }

        return this;
    }

    public WebElementAssert isLink(){
        isNotNull();

        //check condition
        if(!actual.getTagName().equalsIgnoreCase("a")){
            failWithMessage("Expected element to be a link. But was not!!");
        }

        return this;
    }

    public WebElementAssert hasAttributeValue(String attr, String value){
        isNotNull();

        //check condition
        if(!actual.getAttribute(attr).equals(value)){
            failWithMessage("Expected element to have attr <%s> value as <%s>. But was not!!", attr, value);
        }

        return this;
    }

}

Now lets use our assertion library.

//Launching a site and finding a button element
WebDriver driver = DriverManager.getDriver();
driver.get("https://wrappixel.com/demos/admin-templates/admin-pro/main/ui-notification.html");
WebElement element = driver.findElement(By.cssSelector("div.button-box button.btn-info"));

//expecting a button element to be displayed, enabled and to be a link
assertThat(element).isDisplayed()
                  .isEnabled()
                  .isLink();

Since the element was not a link, it is expected to fail.

java.lang.AssertionError: Expected element to be a link. But was not!!

If I chnage the assertion, It passes.

assertThat(element).isDisplayed()
                    .isEnabled()
                    .isButton()
                    .hasAttributeValue("class", "tst1 btn btn-info");

AssertJ Custom Soft Assertions:

Lets see how to make the above AssertJ custom assertion to a soft assertion.

import org.assertj.core.api.SoftAssertions;
import org.openqa.selenium.WebElement;

public class WebElementSoftAssert extends SoftAssertions {

    public WebElementAssert assertThat(WebElement actual){
        return proxy(WebElementAssert.class, WebElement.class, actual);
    }

}
protected void assertSoftly(Consumer<WebElementSoftAssert> assertConsumer){
    WebElementSoftAssert softAssert = new WebElementSoftAssert();
    assertConsumer.accept(softAssert);
    softAssert.assertAll();
}
assertSoftly(s -> {
    s.assertThat(element)
            .isDisplayed()
            .isEnabled()
            .isButton()
            .hasAttributeValue("class", "tst1 btn btn-info");
});

Summary:

AssertJ is one of the coolest libraries we have in Java. we were able to demonstrate AssertJ Custom Assertions in this tutorial. It makes your test automation script well readable and easily maintainable by chaining various assertions.

Read more about

Happy learning 🙂

Share This:

Exit mobile version