or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

http-testing.mdindex.mdlaunchers.mdtest-annotations.mdtest-context.mdtest-resources.mdutilities.md

utilities.mddocs/

0

# Utilities

1

2

Helper classes for common testing scenarios including path mapping, system property management, annotation processing, and test scope management. These utilities provide essential functionality for advanced test scenarios and framework integration.

3

4

## Capabilities

5

6

### RestorableSystemProperties Class

7

8

Manages temporary system property changes with automatic restoration, essential for tests that need to modify global system state.

9

10

```java { .api }

11

public class RestorableSystemProperties implements Closeable {

12

public static RestorableSystemProperties setProperties(

13

Map<String, String> props,

14

String... additionalKeysToSave

15

) {}

16

public void close() {}

17

}

18

```

19

20

**Usage Example:**

21

```java

22

public class SystemPropertyTest {

23

@Test

24

public void testWithCustomProperties() {

25

// Save current system properties and set test values

26

try (RestorableSystemProperties restore = RestorableSystemProperties.setProperties(

27

Map.of(

28

"app.environment", "test",

29

"database.url", "jdbc:h2:mem:test",

30

"logging.level", "DEBUG"

31

),

32

"user.home", "java.version" // Additional properties to preserve

33

)) {

34

// Test logic that depends on system properties

35

assertEquals("test", System.getProperty("app.environment"));

36

assertEquals("jdbc:h2:mem:test", System.getProperty("database.url"));

37

38

// Verify application behavior with test properties

39

ApplicationConfig config = new ApplicationConfig();

40

assertTrue(config.isTestEnvironment());

41

42

} // Properties automatically restored here

43

44

// Verify properties are restored

45

assertNotEquals("test", System.getProperty("app.environment"));

46

}

47

48

@Test

49

public void testNestedPropertyChanges() {

50

try (RestorableSystemProperties outer = RestorableSystemProperties.setProperties(

51

Map.of("level", "outer"))) {

52

53

assertEquals("outer", System.getProperty("level"));

54

55

try (RestorableSystemProperties inner = RestorableSystemProperties.setProperties(

56

Map.of("level", "inner"))) {

57

58

assertEquals("inner", System.getProperty("level"));

59

60

} // Inner properties restored

61

62

assertEquals("outer", System.getProperty("level"));

63

64

} // Outer properties restored

65

}

66

}

67

```

68

69

### PathTestHelper Class

70

71

Utility for mapping test and application class directories, essential for build tool integration and resource location.

72

73

```java { .api }

74

public class PathTestHelper {

75

public static Path getTestClassesLocation(Class<?> testClass) {}

76

public static Path getTestClassesLocation(Class<?> requiredTestClass, CuratedApplication curatedApplication) {}

77

public static Path getAppClassLocationForTestLocation(Path testClassLocationPath) {}

78

public static Path getResourcesForClassesDirOrNull(Path classesDir, String name) {}

79

public static boolean isTestClass(String className, ClassLoader classLoader, Path testLocation) {}

80

public static Path getProjectBuildDir(Path projectRoot, Path testLocation) {}

81

}

82

```

83

84

**Usage Examples:**

85

```java

86

public class PathTestHelperTest {

87

@Test

88

public void testClassLocationMapping() {

89

// Get test class location

90

Path testLocation = PathTestHelper.getTestClassesLocation(this.getClass());

91

System.out.println("Test classes at: " + testLocation);

92

93

// Map to corresponding application classes

94

Path appLocation = PathTestHelper.getAppClassLocationForTestLocation(testLocation);

95

System.out.println("App classes at: " + appLocation);

96

97

// Verify paths exist

98

assertTrue(Files.exists(testLocation));

99

assertTrue(Files.exists(appLocation));

100

}

101

102

@Test

103

public void testResourceLocation() {

104

Path testClassesDir = PathTestHelper.getTestClassesLocation(this.getClass());

105

106

// Find test resources

107

Path testResources = PathTestHelper.getResourcesForClassesDirOrNull(testClassesDir, "test");

108

if (testResources != null) {

109

assertTrue(Files.exists(testResources));

110

System.out.println("Test resources at: " + testResources);

111

}

112

}

113

114

@Test

115

public void testClassTypeDetection() {

116

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

117

Path testLocation = PathTestHelper.getTestClassesLocation(this.getClass());

118

119

// Check if classes are test classes

120

assertTrue(PathTestHelper.isTestClass(

121

"com.example.MyTest", classLoader, testLocation));

122

123

assertFalse(PathTestHelper.isTestClass(

124

"com.example.MyService", classLoader, testLocation));

125

}

126

127

@Test

128

public void testProjectBuildDirectory() {

129

Path projectRoot = Paths.get(".");

130

Path testLocation = PathTestHelper.getTestClassesLocation(this.getClass());

131

132

Path buildDir = PathTestHelper.getProjectBuildDir(projectRoot, testLocation);

133

System.out.println("Build directory: " + buildDir);

134

135

// Verify build directory structure

136

assertTrue(Files.exists(buildDir));

137

assertTrue(Files.exists(buildDir.resolve("classes")));

138

assertTrue(Files.exists(buildDir.resolve("test-classes")));

139

}

140

}

141

```

142

143

### TestScopeManager Class

144

145

Manages test scope setup and teardown via SPI, providing hooks for test lifecycle management.

146

147

```java { .api }

148

public class TestScopeManager {

149

public static void setup(boolean isIntegrationTest) {}

150

public static void tearDown(boolean isIntegrationTest) {}

151

}

152

```

153

154

**Usage in Custom Test Extensions:**

155

```java

156

public class CustomTestExtension implements BeforeAllCallback, AfterAllCallback {

157

@Override

158

public void beforeAll(ExtensionContext context) {

159

boolean isIntegrationTest = context.getTestClass()

160

.map(cls -> cls.isAnnotationPresent(QuarkusIntegrationTest.class))

161

.orElse(false);

162

163

TestScopeManager.setup(isIntegrationTest);

164

165

if (isIntegrationTest) {

166

System.out.println("Setting up integration test environment");

167

// Additional integration test setup

168

} else {

169

System.out.println("Setting up unit test environment");

170

// Unit test specific setup

171

}

172

}

173

174

@Override

175

public void afterAll(ExtensionContext context) {

176

boolean isIntegrationTest = context.getTestClass()

177

.map(cls -> cls.isAnnotationPresent(QuarkusIntegrationTest.class))

178

.orElse(false);

179

180

TestScopeManager.tearDown(isIntegrationTest);

181

182

System.out.println("Test scope cleanup completed");

183

}

184

}

185

186

// Usage in test

187

@ExtendWith(CustomTestExtension.class)

188

public class ManagedScopeTest {

189

@Test

190

public void testWithManagedScope() {

191

// Test logic - scope is automatically managed

192

assertTrue(true);

193

}

194

}

195

```

196

197

### AnnotationUtils Class

198

199

Utility for finding annotations with inheritance support, useful for framework integration and custom annotation processing.

200

201

```java { .api }

202

public class AnnotationUtils {

203

public static <A extends Annotation> Optional<AnnotationContainer<A>> findAnnotation(

204

AnnotatedElement element,

205

Class<A> annotationType

206

) {}

207

}

208

209

public class AnnotationContainer<A extends Annotation> {

210

public AnnotationContainer(AnnotatedElement element, A annotation) {}

211

public AnnotatedElement getElement() {}

212

public A getAnnotation() {}

213

}

214

```

215

216

**Usage Examples:**

217

```java

218

public class AnnotationUtilsTest {

219

@Test

220

public void testAnnotationDiscovery() {

221

// Find annotation on class with inheritance

222

Optional<AnnotationContainer<QuarkusTestResource>> container =

223

AnnotationUtils.findAnnotation(MyTestClass.class, QuarkusTestResource.class);

224

225

if (container.isPresent()) {

226

QuarkusTestResource annotation = container.get().getAnnotation();

227

AnnotatedElement element = container.get().getElement();

228

229

System.out.println("Found @QuarkusTestResource on: " + element);

230

System.out.println("Resource class: " + annotation.value().getSimpleName());

231

}

232

}

233

234

@Test

235

public void testMethodAnnotationSearch() {

236

Method testMethod = ReflectionUtils.findMethod(MyTestClass.class, "testMethod");

237

238

Optional<AnnotationContainer<TestTransaction>> container =

239

AnnotationUtils.findAnnotation(testMethod, TestTransaction.class);

240

241

assertTrue(container.isPresent(), "Method should have @TestTransaction");

242

}

243

244

@Test

245

public void testFieldAnnotationSearch() throws NoSuchFieldException {

246

Field testField = MyTestClass.class.getDeclaredField("injectedService");

247

248

Optional<AnnotationContainer<InjectMock>> container =

249

AnnotationUtils.findAnnotation(testField, InjectMock.class);

250

251

assertTrue(container.isPresent(), "Field should have @InjectMock");

252

}

253

}

254

255

// Example test class for annotation discovery

256

@QuarkusTestResource(DatabaseTestResource.class)

257

public class MyTestClass {

258

@InjectMock

259

UserService injectedService;

260

261

@Test

262

@TestTransaction

263

public void testMethod() {

264

// Test implementation

265

}

266

}

267

```

268

269

## Advanced Usage Patterns

270

271

### Custom Test Framework Integration

272

273

Building custom test frameworks using the utilities:

274

275

```java

276

public class CustomTestFramework {

277

private final Map<String, Object> testContext = new HashMap<>();

278

279

public void setupTest(Class<?> testClass) {

280

// Use PathTestHelper for resource location

281

Path testClassLocation = PathTestHelper.getTestClassesLocation(testClass);

282

Path resourcesPath = PathTestHelper.getResourcesForClassesDirOrNull(testClassLocation, "test");

283

284

testContext.put("testClassLocation", testClassLocation);

285

testContext.put("resourcesPath", resourcesPath);

286

287

// Setup test scope

288

boolean isIntegrationTest = AnnotationUtils

289

.findAnnotation(testClass, QuarkusIntegrationTest.class)

290

.isPresent();

291

292

TestScopeManager.setup(isIntegrationTest);

293

testContext.put("isIntegrationTest", isIntegrationTest);

294

295

// Configure system properties

296

Map<String, String> testProperties = extractTestProperties(testClass);

297

RestorableSystemProperties restorableProps =

298

RestorableSystemProperties.setProperties(testProperties);

299

testContext.put("restorableProperties", restorableProps);

300

}

301

302

public void tearDownTest() {

303

// Restore system properties

304

RestorableSystemProperties restorableProps =

305

(RestorableSystemProperties) testContext.get("restorableProperties");

306

if (restorableProps != null) {

307

restorableProps.close();

308

}

309

310

// Tear down test scope

311

boolean isIntegrationTest = (boolean) testContext.get("isIntegrationTest");

312

TestScopeManager.tearDown(isIntegrationTest);

313

314

testContext.clear();

315

}

316

317

private Map<String, String> extractTestProperties(Class<?> testClass) {

318

Map<String, String> properties = new HashMap<>();

319

320

// Look for custom annotation with properties

321

Optional<AnnotationContainer<TestProperties>> container =

322

AnnotationUtils.findAnnotation(testClass, TestProperties.class);

323

324

if (container.isPresent()) {

325

TestProperties annotation = container.get().getAnnotation();

326

for (TestProperty prop : annotation.value()) {

327

properties.put(prop.name(), prop.value());

328

}

329

}

330

331

return properties;

332

}

333

}

334

335

// Custom annotations for the framework

336

@Target(ElementType.TYPE)

337

@Retention(RetentionPolicy.RUNTIME)

338

public @interface TestProperties {

339

TestProperty[] value();

340

}

341

342

@Target(ElementType.TYPE)

343

@Retention(RetentionPolicy.RUNTIME)

344

public @interface TestProperty {

345

String name();

346

String value();

347

}

348

```

349

350

### Build Tool Integration

351

352

Using path utilities for build tool integration:

353

354

```java

355

public class BuildToolIntegration {

356

public static void generateTestReport(Class<?> testClass) {

357

Path testLocation = PathTestHelper.getTestClassesLocation(testClass);

358

Path projectRoot = testLocation.getParent().getParent(); // Assume standard layout

359

Path buildDir = PathTestHelper.getProjectBuildDir(projectRoot, testLocation);

360

361

Path reportsDir = buildDir.resolve("reports").resolve("tests");

362

try {

363

Files.createDirectories(reportsDir);

364

365

Path reportFile = reportsDir.resolve("test-report.html");

366

try (PrintWriter writer = new PrintWriter(Files.newBufferedWriter(reportFile))) {

367

writer.println("<html><body>");

368

writer.println("<h1>Test Report for " + testClass.getSimpleName() + "</h1>");

369

writer.println("<p>Test location: " + testLocation + "</p>");

370

writer.println("<p>Build directory: " + buildDir + "</p>");

371

writer.println("</body></html>");

372

}

373

374

System.out.println("Test report generated: " + reportFile);

375

376

} catch (IOException e) {

377

System.err.println("Failed to generate test report: " + e.getMessage());

378

}

379

}

380

}

381

```

382

383

### Configuration Management

384

385

Advanced configuration management using system properties:

386

387

```java

388

public class ConfigurationManager {

389

private static final Map<String, RestorableSystemProperties> activeConfigurations =

390

new ConcurrentHashMap<>();

391

392

public static String setupConfiguration(String configName, Map<String, String> properties) {

393

String configId = configName + "-" + System.currentTimeMillis();

394

395

RestorableSystemProperties restore = RestorableSystemProperties.setProperties(

396

properties,

397

// Preserve important system properties

398

"java.home", "user.home", "java.class.path"

399

);

400

401

activeConfigurations.put(configId, restore);

402

return configId;

403

}

404

405

public static void restoreConfiguration(String configId) {

406

RestorableSystemProperties restore = activeConfigurations.remove(configId);

407

if (restore != null) {

408

restore.close();

409

}

410

}

411

412

public static void restoreAllConfigurations() {

413

activeConfigurations.values().forEach(RestorableSystemProperties::close);

414

activeConfigurations.clear();

415

}

416

417

// Usage in test lifecycle

418

@BeforeEach

419

public void setupTestConfig() {

420

Map<String, String> testConfig = Map.of(

421

"app.environment", "test",

422

"database.type", "h2",

423

"logging.level.com.example", "DEBUG"

424

);

425

426

String configId = ConfigurationManager.setupConfiguration("test", testConfig);

427

// Store configId for cleanup

428

}

429

430

@AfterEach

431

public void cleanupTestConfig() {

432

ConfigurationManager.restoreAllConfigurations();

433

}

434

}

435

```