9

Testing with Awaitility made simple

 1 year ago
source link: http://www.mastertheboss.com/various-stuff/testing-java/testing-with-awaitility-made-simple/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

The Awaitility library introduces a functional style usage to express expectations of an asynchronous system in a concise and easy to read manner. Let’s have a deep dive into it with this tutorial.

Overview of Awaitility

Awaitility (as the name says) checks expectations based on a timing condition. Here is a basic example of it:

await().atMost(5, SECONDS).until(checkCondition());
await().atMost(5, SECONDS).until(checkCondition());

In the above example, checkCondition contains the condition to verify. Therefore, we will wait at most 5 seconds to verify that condition is true. If you don’t specify any timeout Awaitility will wait for 10 seconds and then throw a ConditionTimeoutException if the condition has not been fulfilled.

Even in this simple form, Awaitility has some advantages over Thread.sleep(). Indeed we don’t have to wait for a fixed amount of time if the condition is already verified.

Let’s see a slightly more complex example. In this example, we are introducing untilAsserted which waits until a Runnable supplier execution passes. In this example, we are asserting that in, at most 3 seconds, the server log file will contain a text in it:

await().atMost(3, TimeUnit.SECONDS).untilAsserted(() -> {
String content =null;
Path filePath = Path.of("/home/jboss/wildfly-26.1.0.Final/standalone/log/server.log");
content = Files.readString(filePath);
} catch (IOException exc) { exc.printStackTrace(); }
Assertions.assertTrue(content.indexOf("Admin console listening") > -1);
await().atMost(3, TimeUnit.SECONDS).untilAsserted(() -> {
      String content =null;
      try {
    	  Path filePath = Path.of("/home/jboss/wildfly-26.1.0.Final/standalone/log/server.log");
    	  content = Files.readString(filePath);    
      } catch (IOException exc) { exc.printStackTrace(); }
      
      Assertions.assertTrue(content.indexOf("Admin console listening") > -1);
             
});

If your tests include several checks from , it is a good idea to introduce an alias for it. This way you will be able to catch easily which test is failing:

await("Check my Heros").atMost(3, SECONDS).until(herosAvailable());
await("Check my Heros").atMost(3, SECONDS).until(herosAvailable());

Checking Types

Next, let’s see how to verify an assertion which requires checking a time limit and the returned Type, including its size.

Here is an Endpoint which produces an array of Hero objects:

public Hero[] get() {
Hero hero[] = new Hero[3];
hero[0] = new Hero("Spiderman");
hero[1] = new Hero("Batman");
hero[2] = new Hero("Hulk");
return hero;
@GET
public Hero[] get() {
        Hero hero[] = new Hero[3];
        hero[0] = new Hero("Spiderman");
        hero[1] = new Hero("Batman");
        hero[2] = new Hero("Hulk");
        return hero;
}

The following condition will check that, within 2 seconds, the HTTP GET endpoint returns an array of Hero with a lenght of 3:

await().atMost(2, SECONDS)
.untilAsserted(() -> Assertions.assertEquals(3, get().as(Hero[].class).length));
await().atMost(2, SECONDS)
     .untilAsserted(() -> Assertions.assertEquals(3, get().as(Hero[].class).length));

Using Poll intervals

A poll interval tells Awaitility how often it should evaluate the condition that is supplied to the until method. In the following example, we use a poll interval of 250 milliseconds with an initial delay of 50 milliseconds until

with().pollInterval(250, TimeUnit.MILLISECONDS).and().with().pollDelay(50, MILLISECONDS).await().until(herosAvailable());
with().pollInterval(250, TimeUnit.MILLISECONDS).and().with().pollDelay(50, MILLISECONDS).await().until(herosAvailable());

Check the condition between a time frame

You can also check that the await condition is true only between a specific timing. For this purpose, you can use atLeast in your condition. For example:

await().atLeast(50, TimeUnit.MILLISECONDS).and().atMost(3, SECONDS).until(herosAvailable());
await().atLeast(50, TimeUnit.MILLISECONDS).and().atMost(3, SECONDS).until(herosAvailable());

In the above example, it is expected that the condition evaluates to true between 50 ms and 3 seconds. If it evaluates to true before, you will see the following Exception:

Condition was evaluated in 10 milliseconds which is earlier than expected minimum timeout 50 milliseconds
Condition was evaluated in 10 milliseconds which is earlier than expected minimum timeout 50 milliseconds

Check condition during an amount of time

Finally, it’s possible to assert that a condition evaluates to true during a time frame. For example, if we were to check that the endpoint returns the same number of Hero during 800 to 1500 ms:

await().during(800, MILLISECONDS).atMost(1500, MILLISECONDS).untilAsserted(() -> Assertions.assertEquals(3, get().as(Hero[].class).length));
await().during(800, MILLISECONDS).atMost(1500, MILLISECONDS).untilAsserted(() -> Assertions.assertEquals(3, get().as(Hero[].class).length));

In the above example, there won’t be any Exception if the condition evaluates to true earlier than the time frame.

How to build projects using Awaitility

Finally, in order to build Test classes using Awaitility you need to include the following dependency in your pom.xml

<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>4.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
            <groupId>org.awaitility</groupId>
            <artifactId>awaitility</artifactId>
            <version>4.2.0</version>
            <scope>test</scope>
</dependency>

Conclusion

This article was a quick walkthough the Awaitility DSL API. You can find the source code for this example on GitHub: https://github.com/fmarchioni/mastertheboss/tree/master/quarkus/awaitility

Post Views: 7

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK