0
# Test Profiles
1
2
Test profiles enable different configurations and CDI alternatives for different test scenarios, allowing tests to run with customized application behavior.
3
4
## @TestProfile Annotation
5
6
Associates a test class with a specific test profile implementation.
7
8
```java { .api }
9
@Target(ElementType.TYPE)
10
@Retention(RetentionPolicy.RUNTIME)
11
public @interface TestProfile {
12
/**
13
* The test profile to use. If subsequent tests use the same
14
* profile then Quarkus will not be restarted between tests,
15
* giving faster execution.
16
*/
17
Class<? extends QuarkusTestProfile> value();
18
}
19
```
20
21
### Usage Example
22
23
```java
24
import io.quarkus.test.junit.QuarkusTest;
25
import io.quarkus.test.junit.TestProfile;
26
27
@QuarkusTest
28
@TestProfile(DatabaseTestProfile.class)
29
class UserServiceDatabaseTest {
30
31
@Inject
32
UserService userService;
33
34
@Test
35
void testWithH2Database() {
36
// Test runs with H2 database configuration
37
}
38
}
39
```
40
41
## QuarkusTestProfile Interface
42
43
Defines the configuration and behavior for a test profile.
44
45
```java { .api }
46
public interface QuarkusTestProfile {
47
48
/**
49
* Returns additional config to be applied to the test. This
50
* will override any existing config (including in application.properties).
51
*/
52
default Map<String, String> getConfigOverrides() {
53
return Collections.emptyMap();
54
}
55
56
/**
57
* Returns enabled alternatives. This has the same effect as setting
58
* the 'quarkus.arc.selected-alternatives' config key.
59
*/
60
default Set<Class<?>> getEnabledAlternatives() {
61
return Collections.emptySet();
62
}
63
64
/**
65
* Allows the default config profile to be overridden.
66
*/
67
default String getConfigProfile() {
68
return null;
69
}
70
71
/**
72
* Additional QuarkusTestResourceLifecycleManager classes to be used
73
* from this specific test profile.
74
*/
75
default List<TestResourceEntry> testResources() {
76
return Collections.emptyList();
77
}
78
79
/**
80
* If this returns true then only the test resources returned from
81
* testResources() will be started, global annotated test resources
82
* will be ignored.
83
*/
84
default boolean disableGlobalTestResources() {
85
return false;
86
}
87
88
/**
89
* The tags this profile is associated with.
90
*/
91
default Set<String> tags() {
92
return Collections.emptySet();
93
}
94
95
/**
96
* The command line parameters that are passed to the main method on startup.
97
*/
98
default String[] commandLineParameters() {
99
return new String[0];
100
}
101
102
/**
103
* If the main method should be run.
104
*/
105
default boolean runMainMethod() {
106
return false;
107
}
108
109
/**
110
* If this method returns true then all StartupEvent and ShutdownEvent
111
* observers declared on application beans should be disabled.
112
*/
113
default boolean disableApplicationLifecycleObservers() {
114
return false;
115
}
116
}
117
```
118
119
## TestResourceEntry Class
120
121
Configuration for test resources within a profile.
122
123
```java { .api }
124
public final class TestResourceEntry {
125
126
public TestResourceEntry(Class<? extends QuarkusTestResourceLifecycleManager> clazz);
127
128
public TestResourceEntry(Class<? extends QuarkusTestResourceLifecycleManager> clazz,
129
Map<String, String> args);
130
131
public TestResourceEntry(Class<? extends QuarkusTestResourceLifecycleManager> clazz,
132
Map<String, String> args, boolean parallel);
133
134
public Class<? extends QuarkusTestResourceLifecycleManager> getClazz();
135
public Map<String, String> getArgs();
136
public boolean isParallel();
137
}
138
```
139
140
## Common Test Profile Patterns
141
142
### Database Configuration Profile
143
144
```java
145
import io.quarkus.test.junit.QuarkusTestProfile;
146
import java.util.Map;
147
148
public class H2DatabaseProfile implements QuarkusTestProfile {
149
150
@Override
151
public Map<String, String> getConfigOverrides() {
152
return Map.of(
153
"quarkus.datasource.db-kind", "h2",
154
"quarkus.datasource.jdbc.url", "jdbc:h2:mem:testdb",
155
"quarkus.hibernate-orm.database.generation", "drop-and-create"
156
);
157
}
158
}
159
160
@QuarkusTest
161
@TestProfile(H2DatabaseProfile.class)
162
class DatabaseIntegrationTest {
163
// Tests run with H2 in-memory database
164
}
165
```
166
167
### Alternative Bean Profile
168
169
```java
170
// Production implementation
171
@ApplicationScoped
172
public class EmailServiceImpl implements EmailService {
173
public void sendEmail(String to, String subject, String body) {
174
// Real email sending logic
175
}
176
}
177
178
// Test alternative
179
@Alternative
180
@ApplicationScoped
181
public class MockEmailService implements EmailService {
182
public void sendEmail(String to, String subject, String body) {
183
// Mock implementation - no actual email sent
184
}
185
}
186
187
// Test profile enabling the alternative
188
public class MockEmailProfile implements QuarkusTestProfile {
189
190
@Override
191
public Set<Class<?>> getEnabledAlternatives() {
192
return Set.of(MockEmailService.class);
193
}
194
}
195
196
@QuarkusTest
197
@TestProfile(MockEmailProfile.class)
198
class UserRegistrationTest {
199
200
@Inject
201
EmailService emailService; // Injects MockEmailService
202
203
@Test
204
void testUserRegistration() {
205
// Test runs with mock email service
206
}
207
}
208
```
209
210
### Test Resources Profile
211
212
```java
213
// Custom test resource
214
public class RedisTestResource implements QuarkusTestResourceLifecycleManager {
215
216
@Override
217
public Map<String, String> start() {
218
// Start Redis container
219
return Map.of(
220
"quarkus.redis.hosts", "redis://localhost:6379"
221
);
222
}
223
224
@Override
225
public void stop() {
226
// Stop Redis container
227
}
228
}
229
230
// Profile with test resource
231
public class RedisProfile implements QuarkusTestProfile {
232
233
@Override
234
public List<TestResourceEntry> testResources() {
235
return List.of(
236
new TestResourceEntry(RedisTestResource.class)
237
);
238
}
239
}
240
241
@QuarkusTest
242
@TestProfile(RedisProfile.class)
243
class CacheServiceTest {
244
// Test runs with Redis test container
245
}
246
```
247
248
### Development Mode Profile
249
250
```java
251
public class DevModeProfile implements QuarkusTestProfile {
252
253
@Override
254
public String getConfigProfile() {
255
return "dev";
256
}
257
258
@Override
259
public Map<String, String> getConfigOverrides() {
260
return Map.of(
261
"quarkus.log.level", "DEBUG",
262
"quarkus.hibernate-orm.log.sql", "true"
263
);
264
}
265
266
@Override
267
public boolean runMainMethod() {
268
return true; // Start application main method
269
}
270
}
271
```
272
273
### Tagged Profile System
274
275
```java
276
public class IntegrationTestProfile implements QuarkusTestProfile {
277
278
@Override
279
public Set<String> tags() {
280
return Set.of("integration", "database");
281
}
282
283
@Override
284
public List<TestResourceEntry> testResources() {
285
return List.of(
286
new TestResourceEntry(PostgresTestResource.class),
287
new TestResourceEntry(RedisTestResource.class)
288
);
289
}
290
}
291
292
// Run only tests with specific tags:
293
// mvn test -Dquarkus.test.profile.tags=integration
294
```
295
296
## Profile Performance Optimization
297
298
### Profile Reuse
299
```java
300
// Tests with same profile run consecutively without Quarkus restart
301
@QuarkusTest
302
@TestProfile(DatabaseProfile.class)
303
class UserServiceTest { }
304
305
@QuarkusTest
306
@TestProfile(DatabaseProfile.class) // Same profile - no restart
307
class ProductServiceTest { }
308
309
@QuarkusTest
310
@TestProfile(CacheProfile.class) // Different profile - restart required
311
class CacheServiceTest { }
312
```
313
314
### Resource Lifecycle Management
315
```java
316
public class OptimizedProfile implements QuarkusTestProfile {
317
318
@Override
319
public List<TestResourceEntry> testResources() {
320
return List.of(
321
// Parallel resource startup
322
new TestResourceEntry(DatabaseResource.class, Map.of(), true),
323
new TestResourceEntry(MessageQueueResource.class, Map.of(), true)
324
);
325
}
326
327
@Override
328
public boolean disableGlobalTestResources() {
329
return true; // Only use profile-specific resources
330
}
331
}
332
```
333
334
## Error Handling
335
336
### Profile Configuration Errors
337
```java
338
public class InvalidProfile implements QuarkusTestProfile {
339
340
@Override
341
public Map<String, String> getConfigOverrides() {
342
return Map.of(
343
"invalid.property", "value" // May cause deployment error
344
);
345
}
346
}
347
```
348
349
### Alternative Resolution Errors
350
```java
351
// Missing @Alternative annotation will cause deployment error
352
@ApplicationScoped // Should be @Alternative @ApplicationScoped
353
public class TestServiceImpl implements TestService { }
354
355
public class BrokenProfile implements QuarkusTestProfile {
356
357
@Override
358
public Set<Class<?>> getEnabledAlternatives() {
359
return Set.of(TestServiceImpl.class); // Deployment will fail
360
}
361
}
362
```