Common test utilities and framework for Quarkus applications, providing core testing infrastructure including application launchers, test isolation, configuration management, and integration with REST Assured for HTTP testing
—
Comprehensive lifecycle management for external test dependencies like databases, message brokers, and external services. The test resource system provides sophisticated scoping strategies, parallel resource startup, and automatic configuration injection.
Defines test resources for lifecycle management with optional configuration and scoping control.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(QuarkusTestResource.List.class)
public @interface QuarkusTestResource {
Class<? extends QuarkusTestResourceLifecycleManager> value();
ResourceArg[] initArgs() default {};
boolean parallel() default false;
boolean restrictToAnnotatedClass() default false;
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ResourceArg {
String name();
String value();
}Usage Example:
@QuarkusTestResource(value = DatabaseTestResource.class,
initArgs = @ResourceArg(name = "db.version", value = "13"))
public class UserServiceTest {
// Test implementation
}Alternative to QuarkusTestResource with enhanced scope control for resource sharing and isolation.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(WithTestResource.List.class)
public @interface WithTestResource {
Class<? extends QuarkusTestResourceLifecycleManager> value();
ResourceArg[] initArgs() default {};
boolean parallel() default false;
TestResourceScope scope() default TestResourceScope.MATCHING_RESOURCES;
}
public enum TestResourceScope {
RESTRICTED_TO_CLASS, // Complete isolation, restart for each test
MATCHING_RESOURCES, // Restart only when resources differ
GLOBAL // Apply to all tests in suite
}Usage Example:
@WithTestResource(value = DatabaseTestResource.class,
scope = TestResourceScope.GLOBAL)
public class IntegrationTest {
// Shared database resource across all tests
}Main interface for managing test resource lifecycle with hooks for initialization, injection, and cleanup.
public interface QuarkusTestResourceLifecycleManager {
Map<String, String> start();
void stop();
default void setContext(Context context) {}
default void init(Map<String, String> initArgs) {}
default void inject(Object testInstance) {}
default void inject(TestInjector testInjector) {}
default int order() { return 0; }
interface Context {
String testProfile();
TestStatus getTestStatus();
}
interface TestInjector {
void injectIntoFields(Object fieldValue, Predicate<Field> predicate);
class Annotated implements Predicate<Field> {
public Annotated(Class<? extends Annotation> annotationType) {}
}
class MatchesType implements Predicate<Field> {
public MatchesType(Class<?> type) {}
}
class AnnotatedAndMatchesType implements Predicate<Field> {
public AnnotatedAndMatchesType(Class<? extends Annotation> annotationType, Class<?> type) {}
}
}
}Implementation Example:
public class DatabaseTestResource implements QuarkusTestResourceLifecycleManager {
private PostgreSQLContainer<?> container;
@Override
public Map<String, String> start() {
container = new PostgreSQLContainer<>("postgres:13")
.withDatabaseName("testdb")
.withUsername("test")
.withPassword("test");
container.start();
return Map.of(
"quarkus.datasource.jdbc.url", container.getJdbcUrl(),
"quarkus.datasource.username", container.getUsername(),
"quarkus.datasource.password", container.getPassword()
);
}
@Override
public void stop() {
if (container != null) {
container.stop();
}
}
@Override
public void inject(TestInjector testInjector) {
testInjector.injectIntoFields(container,
new TestInjector.MatchesType(PostgreSQLContainer.class));
}
@Override
public int order() {
return 100; // Start after other resources
}
}Lifecycle manager with annotation-based configuration for type-safe resource initialization.
public interface QuarkusTestResourceConfigurableLifecycleManager<ConfigAnnotation extends Annotation>
extends QuarkusTestResourceLifecycleManager {
default void init(ConfigAnnotation annotation) {}
}Usage Example:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DatabaseConfig {
String version() default "13";
boolean withData() default false;
}
public class ConfigurableDatabaseResource
implements QuarkusTestResourceConfigurableLifecycleManager<DatabaseConfig> {
private DatabaseConfig config;
@Override
public void init(DatabaseConfig annotation) {
this.config = annotation;
}
@Override
public Map<String, String> start() {
// Use config.version() and config.withData() for setup
return configMap;
}
}Control resource startup order using the order() method:
public class DatabaseResource implements QuarkusTestResourceLifecycleManager {
@Override
public int order() { return 10; } // Start early
}
public class CacheResource implements QuarkusTestResourceLifecycleManager {
@Override
public int order() { return 20; } // Start after database
}Access test execution context and failure status:
public class MonitoringResource implements QuarkusTestResourceLifecycleManager {
private Context context;
@Override
public void setContext(Context context) {
this.context = context;
}
@Override
public void stop() {
if (context.getTestStatus().isTestFailed()) {
// Capture logs for failed tests
captureLogs();
}
}
}Inject resource instances directly into test fields:
public class MyTestResource implements QuarkusTestResourceLifecycleManager {
private CustomService service;
@Override
public Map<String, String> start() {
service = new CustomService();
return Map.of();
}
@Override
public void inject(TestInjector testInjector) {
testInjector.injectIntoFields(service,
new TestInjector.Annotated(CustomService.class));
}
}
// In test class:
public class MyTest {
@CustomService
CustomService injectedService; // Automatically injected
}Enable parallel startup for independent resources:
@QuarkusTestResource(value = DatabaseResource.class, parallel = true)
@QuarkusTestResource(value = MessageBrokerResource.class, parallel = true)
public class IntegrationTest {
// Both resources start in parallel
}Install with Tessl CLI
npx tessl i tessl/maven-io-quarkus--quarkus-test-common