A Java DSL for synchronizing asynchronous operations
npx @tessl/cli install tessl/maven-org-awaitility--awaitility@4.3.0Awaitility is a Java DSL for synchronizing asynchronous operations. It makes it easy to test asynchronous code by providing a clean, readable API that allows developers to express expectations about asynchronous behavior without dealing with low-level threading, timeout, and concurrency concerns.
Maven:
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>4.3.0</version>
<scope>test</scope>
</dependency>Gradle:
testImplementation 'org.awaitility:awaitility:4.3.0'SBT:
libraryDependencies += "org.awaitility" % "awaitility" % "4.3.0" % Testimport static org.awaitility.Awaitility.*;
import static java.util.concurrent.TimeUnit.*;
import static org.awaitility.Durations.*;Optional additional imports for advanced usage:
import org.awaitility.core.ConditionFactory;
import org.awaitility.pollinterval.PollInterval;
import org.awaitility.pollinterval.FibonacciPollInterval;import static org.awaitility.Awaitility.*;
import static java.util.concurrent.TimeUnit.*;
// Wait at most 5 seconds until customer status is updated
await().atMost(5, SECONDS).until(customerStatusHasUpdated());
// Wait forever until order count is greater than 3
await().forever().until(() -> orderService.orderCount(), greaterThan(3));
// Wait 300 milliseconds until field value equals expected value
await().atMost(300, MILLISECONDS)
.until(fieldIn(orderService).withName("orderCount").andOfType(int.class), equalTo(5));
// Wait with custom polling interval and initial delay
with().pollInterval(ONE_HUNDRED_MILLISECONDS)
.and().with().pollDelay(20, MILLISECONDS)
.await("customer registration")
.until(customerStatus(), equalTo(REGISTERED));Awaitility is built around several key components:
Awaitility class for creating await statementsPrimary DSL for creating wait conditions with timeout and polling configuration. Foundation for all asynchronous waiting patterns.
// Main entry points
static ConditionFactory await();
static ConditionFactory await(String alias);
static ConditionFactory with();
static ConditionFactory given();
static ConditionFactory waitAtMost(Duration timeout);
static ConditionFactory waitAtMost(long value, TimeUnit unit);Different ways to specify conditions for waiting, including callable evaluation, predicate matching, assertion-based testing, and atomic variable monitoring.
// Condition evaluation methods
<T> T until(Callable<T> supplier, Matcher<? super T> matcher);
<T> T until(Callable<T> supplier, Predicate<? super T> predicate);
void until(Callable<Boolean> conditionEvaluator);
void untilAsserted(ThrowingRunnable assertion);Fine-grained control over wait timing, polling intervals, and execution strategies for optimal performance and test reliability.
// Timeout configuration
ConditionFactory atMost(Duration timeout);
ConditionFactory atLeast(Duration timeout);
ConditionFactory during(Duration timeout);
ConditionFactory between(Duration atLeast, Duration atMost);
ConditionFactory forever();
// Polling configuration
ConditionFactory pollInterval(Duration pollInterval);
ConditionFactory pollDelay(Duration pollDelay);
ConditionFactory pollInterval(PollInterval pollInterval);Configurable exception ignoring strategies for handling expected failures during condition evaluation without causing test failures.
// Exception handling
ConditionFactory ignoreException(Class<? extends Throwable> exceptionType);
ConditionFactory ignoreExceptions();
ConditionFactory ignoreExceptionsMatching(Matcher<? super Throwable> matcher);
ConditionFactory ignoreExceptionsMatching(Predicate<? super Throwable> predicate);Utilities for waiting on private field values and object state changes using reflection, ideal for testing internal component state.
// Field access
static FieldSupplierBuilder fieldIn(Object object);
static FieldSupplierBuilder fieldIn(Class<?> clazz);
interface FieldSupplierBuilder {
FieldSupplierBuilder ofType(Class<?> expectedType);
FieldSupplierBuilder withName(String fieldName);
FieldSupplierBuilder withAnnotation(Class<? extends Annotation> annotation);
<T> Callable<T> call();
}Specialized support for waiting on atomic variable changes with built-in matchers and type-safe operations.
// Atomic variable conditions
Integer untilAtomic(AtomicInteger atomic, Matcher<? super Integer> matcher);
Long untilAtomic(AtomicLong atomic, Matcher<? super Long> matcher);
<V> V untilAtomic(AtomicReference<V> atomic, Matcher<? super V> matcher);
void untilTrue(AtomicBoolean atomic);
void untilFalse(AtomicBoolean atomic);Global defaults, fail-fast conditions, custom executors, and logging for complex testing scenarios and performance optimization.
// Global configuration
static void setDefaultTimeout(Duration defaultTimeout);
static void setDefaultPollInterval(Duration pollInterval);
static void setDefaultPollDelay(Duration pollDelay);
static void reset();
// Fail-fast conditions
ConditionFactory failFast(Callable<Boolean> failFastCondition);
ConditionFactory failFast(String reason, ThrowingRunnable failFastAssertion);// Core interfaces
@FunctionalInterface
interface ThrowingRunnable {
void run() throws Exception;
}
@FunctionalInterface
interface ConditionEvaluationListener<T> {
void conditionEvaluated(EvaluatedCondition<T> condition);
default void beforeEvaluation(StartEvaluationEvent<T> startEvaluationEvent) {}
default void onTimeout(TimeoutEvent timeoutEvent) {}
default void exceptionIgnored(IgnoredException ignoredException) {}
}
// Event types for ConditionEvaluationListener
class EvaluatedCondition<T> {
public String getDescription();
public Matcher<? super T> getMatcher();
public T getCurrentConditionValue();
public long getElapsedTimeInMS();
public Duration getPollInterval();
public long getRemainingTimeInMS();
public boolean isConditionFulfilled();
public String getAlias();
}
class StartEvaluationEvent<T> {
public String getDescription();
public T getCurrentConditionValue();
public long getElapsedTimeInMS();
public long getRemainingTimeInMS();
public String getAlias();
}
class TimeoutEvent {
public String getDescription();
public long getElapsedTimeInMS();
public String getAlias();
}
class IgnoredException {
public Throwable getException();
public String getDescription();
public long getElapsedTimeInMS();
public String getAlias();
}
// Exception types
class ConditionTimeoutException extends RuntimeException {
public ConditionTimeoutException(String message);
public ConditionTimeoutException(String message, Throwable cause);
}
class TerminalFailureException extends RuntimeException {
public TerminalFailureException(String message);
public TerminalFailureException(String message, Throwable cause);
}
class DeadlockException extends Throwable {
public DeadlockException(long[] threads);
public String getMessage();
public ThreadInfo[] getThreadInfos();
}
// Field access exceptions
class FieldNotFoundException extends RuntimeException {
public FieldNotFoundException(String message);
}
class TooManyFieldsFoundException extends RuntimeException {
public TooManyFieldsFoundException(String message);
}
// SPI Extension Point
class Timeout {
/**
* Message shown in timeout exceptions (can be set globally)
*/
public static String timeout_message = null;
}// Duration constants from org.awaitility.Durations
static final Duration FOREVER;
static final Duration ONE_MILLISECOND;
static final Duration ONE_HUNDRED_MILLISECONDS;
static final Duration TWO_HUNDRED_MILLISECONDS;
static final Duration FIVE_HUNDRED_MILLISECONDS;
static final Duration ONE_SECOND;
static final Duration TWO_SECONDS;
static final Duration FIVE_SECONDS;
static final Duration TEN_SECONDS;
static final Duration ONE_MINUTE;
static final Duration TWO_MINUTES;
static final Duration FIVE_MINUTES;
static final Duration TEN_MINUTES;