or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

config-storage.mdengine-implementation.mdhierarchical-engine.mdindex.mdtest-descriptors.mdtest-discovery.mdtest-execution.md

test-descriptors.mddocs/

0

# Test Descriptors

1

2

Hierarchical test descriptor system for representing discovered tests and containers with metadata, sources, and relationships. Test descriptors form a tree structure that represents the organization of tests within an engine.

3

4

## Capabilities

5

6

### TestDescriptor Interface

7

8

Core interface representing a single test or container in the test hierarchy, providing metadata, child management, and source information.

9

10

```java { .api }

11

/**

12

* Mutable descriptor for a test or container within the test hierarchy.

13

*/

14

public interface TestDescriptor {

15

/**

16

* Get the unique identifier for this descriptor.

17

* @return unique ID within the engine's namespace

18

*/

19

UniqueId getUniqueId();

20

21

/**

22

* Get the display name for this descriptor.

23

* @return human-readable name for display purposes

24

*/

25

String getDisplayName();

26

27

/**

28

* Get the set of tags associated with this descriptor.

29

* @return unmodifiable set of test tags

30

*/

31

Set<TestTag> getTags();

32

33

/**

34

* Get the source location of this test or container.

35

* @return optional test source (class, method, file, etc.)

36

*/

37

Optional<TestSource> getSource();

38

39

/**

40

* Get the parent descriptor of this descriptor.

41

* @return optional parent descriptor

42

*/

43

Optional<TestDescriptor> getParent();

44

45

/**

46

* Set the parent descriptor of this descriptor.

47

* @param parent the parent descriptor

48

*/

49

void setParent(TestDescriptor parent);

50

51

/**

52

* Get all direct child descriptors.

53

* @return unmodifiable set of child descriptors

54

*/

55

Set<? extends TestDescriptor> getChildren();

56

57

/**

58

* Add a child descriptor to this descriptor.

59

* @param child the child descriptor to add

60

*/

61

void addChild(TestDescriptor child);

62

63

/**

64

* Remove a child descriptor from this descriptor.

65

* @param child the child descriptor to remove

66

*/

67

void removeChild(TestDescriptor child);

68

69

/**

70

* Remove this descriptor from its parent.

71

*/

72

void removeFromHierarchy();

73

74

/**

75

* Get the type of this descriptor.

76

* @return descriptor type (CONTAINER, TEST, or CONTAINER_AND_TEST)

77

*/

78

Type getType();

79

80

/**

81

* Find the first descendant matching the given predicate.

82

* @param predicate the matching predicate

83

* @return optional matching descendant

84

*/

85

Optional<? extends TestDescriptor> findByUniqueId(UniqueId uniqueId);

86

87

/**

88

* Accept a visitor for traversing the descriptor hierarchy.

89

* @param visitor the visitor to accept

90

*/

91

void accept(Visitor visitor);

92

93

/**

94

* Check if this descriptor contains any executable tests.

95

* @param testDescriptor the descriptor to check

96

* @return true if contains tests, false otherwise

97

*/

98

static boolean containsTests(TestDescriptor testDescriptor);

99

100

/**

101

* Type of test descriptor.

102

*/

103

enum Type {

104

/** Contains other tests or containers but is not executable itself */

105

CONTAINER,

106

/** Executable test that does not contain other tests */

107

TEST,

108

/** Both container and executable test */

109

CONTAINER_AND_TEST

110

}

111

112

/**

113

* Visitor interface for traversing test descriptor hierarchies.

114

*/

115

interface Visitor {

116

/**

117

* Visit a test descriptor.

118

* @param descriptor the descriptor to visit

119

* @param remove function to remove the descriptor from its parent

120

*/

121

void visit(TestDescriptor descriptor, Runnable remove);

122

}

123

}

124

```

125

126

**Usage Example:**

127

128

```java

129

// Create hierarchical test structure

130

TestDescriptor engineDescriptor = new EngineDescriptor(

131

UniqueId.forEngine("my-engine"), "My Test Engine"

132

);

133

134

// Add class container

135

UniqueId classId = engineDescriptor.getUniqueId().append("class", "MyTestClass");

136

TestDescriptor classDescriptor = new MyClassDescriptor(classId, MyTestClass.class);

137

engineDescriptor.addChild(classDescriptor);

138

139

// Add test methods

140

UniqueId methodId = classId.append("method", "testSomething");

141

TestDescriptor methodDescriptor = new MyMethodDescriptor(methodId, testMethod);

142

classDescriptor.addChild(methodDescriptor);

143

144

// Navigate hierarchy

145

Optional<TestDescriptor> found = engineDescriptor.findByUniqueId(methodId);

146

Set<? extends TestDescriptor> children = classDescriptor.getChildren();

147

```

148

149

### AbstractTestDescriptor

150

151

Abstract base implementation providing common functionality for test descriptors, including hierarchy management and visitor support.

152

153

```java { .api }

154

/**

155

* Abstract base implementation of the TestDescriptor interface.

156

*/

157

public abstract class AbstractTestDescriptor implements TestDescriptor {

158

/**

159

* Constructor for creating test descriptors.

160

* @param uniqueId unique identifier for this descriptor

161

* @param displayName display name for this descriptor

162

*/

163

protected AbstractTestDescriptor(UniqueId uniqueId, String displayName);

164

165

/**

166

* Constructor with optional source.

167

* @param uniqueId unique identifier for this descriptor

168

* @param displayName display name for this descriptor

169

* @param source optional test source

170

*/

171

protected AbstractTestDescriptor(UniqueId uniqueId, String displayName, TestSource source);

172

173

// Implements all TestDescriptor methods with sensible defaults

174

175

/**

176

* Add a tag to this descriptor.

177

* @param tag the tag to add

178

*/

179

protected void addTag(TestTag tag);

180

181

/**

182

* Set the source for this descriptor.

183

* @param source the test source

184

*/

185

protected void setSource(TestSource source);

186

}

187

```

188

189

### EngineDescriptor

190

191

Specialized test descriptor implementation for test engine root descriptors.

192

193

```java { .api }

194

/**

195

* TestDescriptor implementation for test engine root descriptors.

196

*/

197

public class EngineDescriptor extends AbstractTestDescriptor {

198

/**

199

* Create an engine descriptor.

200

* @param uniqueId unique ID for the engine (should be engine root)

201

* @param displayName display name for the engine

202

*/

203

public EngineDescriptor(UniqueId uniqueId, String displayName);

204

205

/**

206

* Engine descriptors are always containers.

207

* @return Type.CONTAINER

208

*/

209

@Override

210

public final Type getType();

211

}

212

```

213

214

### TestSource Implementations

215

216

Various implementations of the TestSource interface for different types of test origins.

217

218

```java { .api }

219

/**

220

* Test source for Java classes.

221

*/

222

public class ClassSource implements TestSource {

223

public static ClassSource from(Class<?> javaClass);

224

public static ClassSource from(String className);

225

public Class<?> getJavaClass();

226

public String getClassName();

227

}

228

229

/**

230

* Test source for Java methods.

231

*/

232

public class MethodSource implements TestSource {

233

public static MethodSource from(Method javaMethod);

234

public static MethodSource from(Class<?> javaClass, Method javaMethod);

235

public static MethodSource from(Class<?> javaClass, String methodName);

236

public static MethodSource from(String className, String methodName);

237

public static MethodSource from(String className, String methodName, String methodParameterTypes);

238

239

public Class<?> getJavaClass();

240

public String getClassName();

241

public Method getJavaMethod();

242

public String getMethodName();

243

public String getMethodParameterTypes();

244

}

245

246

/**

247

* Test source for files.

248

*/

249

public class FileSource implements TestSource {

250

public static FileSource from(File file);

251

public static FileSource from(File file, FilePosition position);

252

public File getFile();

253

public Optional<FilePosition> getPosition();

254

}

255

256

/**

257

* Test source for directories.

258

*/

259

public class DirectorySource implements TestSource {

260

public static DirectorySource from(File directory);

261

public File getDirectory();

262

}

263

264

/**

265

* Test source for packages.

266

*/

267

public class PackageSource implements TestSource {

268

public static PackageSource from(String packageName);

269

public String getPackageName();

270

}

271

272

/**

273

* Test source for URIs.

274

*/

275

public class UriSource implements TestSource {

276

public static UriSource from(URI uri);

277

public URI getUri();

278

}

279

280

/**

281

* Test source for classpath resources.

282

*/

283

public class ClasspathResourceSource implements TestSource {

284

public static ClasspathResourceSource from(String classpathResourceName);

285

public static ClasspathResourceSource from(String classpathResourceName, FilePosition position);

286

public String getClasspathResourceName();

287

public Optional<FilePosition> getPosition();

288

}

289

290

/**

291

* Composite test source combining multiple sources.

292

*/

293

public class CompositeTestSource implements TestSource {

294

public static CompositeTestSource from(TestSource... sources);

295

public List<TestSource> getSources();

296

}

297

```

298

299

**Usage Example:**

300

301

```java

302

// Create various test sources

303

TestSource classSource = ClassSource.from(MyTestClass.class);

304

TestSource methodSource = MethodSource.from(MyTestClass.class, "testMethod");

305

TestSource fileSource = FileSource.from(new File("MyTest.java"));

306

307

// Use in test descriptors

308

TestDescriptor classDescriptor = new MyClassDescriptor(

309

uniqueId, "MyTestClass", classSource

310

);

311

312

TestDescriptor methodDescriptor = new MyMethodDescriptor(

313

methodId, "testMethod", methodSource

314

);

315

```

316

317

### Visitor Pattern Support

318

319

Built-in support for traversing test descriptor hierarchies using the visitor pattern.

320

321

```java { .api }

322

/**

323

* Composite visitor that combines multiple visitors.

324

*/

325

public class CompositeTestDescriptorVisitor implements TestDescriptor.Visitor {

326

/**

327

* Create a composite visitor from multiple visitors.

328

* @param visitors the visitors to combine

329

* @return composite visitor

330

*/

331

public static CompositeTestDescriptorVisitor of(TestDescriptor.Visitor... visitors);

332

333

@Override

334

public void visit(TestDescriptor descriptor, Runnable remove);

335

}

336

```

337

338

**Usage Example:**

339

340

```java

341

// Traverse descriptor hierarchy

342

engineDescriptor.accept(new TestDescriptor.Visitor() {

343

@Override

344

public void visit(TestDescriptor descriptor, Runnable remove) {

345

System.out.println("Visiting: " + descriptor.getDisplayName());

346

347

// Conditionally remove descriptors

348

if (shouldRemove(descriptor)) {

349

remove.run();

350

}

351

}

352

});

353

354

// Using composite visitor

355

TestDescriptor.Visitor loggingVisitor = (descriptor, remove) ->

356

System.out.println("Processing: " + descriptor.getDisplayName());

357

358

TestDescriptor.Visitor filteringVisitor = (descriptor, remove) -> {

359

if (descriptor.getTags().contains(TestTag.create("disabled"))) {

360

remove.run();

361

}

362

};

363

364

CompositeTestDescriptorVisitor composite = CompositeTestDescriptorVisitor.of(

365

loggingVisitor, filteringVisitor

366

);

367

368

engineDescriptor.accept(composite);

369

```

370

371

### Hierarchy Navigation

372

373

Utility methods for navigating and querying test descriptor hierarchies.

374

375

**Usage Example:**

376

377

```java

378

// Check if descriptor contains executable tests

379

if (TestDescriptor.containsTests(containerDescriptor)) {

380

// Process container with tests

381

}

382

383

// Find specific descriptors

384

Optional<TestDescriptor> specificTest = engineDescriptor.findByUniqueId(

385

UniqueId.parse("[engine:my-engine]/[class:MyClass]/[method:testMethod]")

386

);

387

388

// Get all leaf test descriptors

389

List<TestDescriptor> allTests = new ArrayList<>();

390

engineDescriptor.accept((descriptor, remove) -> {

391

if (descriptor.getType() == TestDescriptor.Type.TEST &&

392

descriptor.getChildren().isEmpty()) {

393

allTests.add(descriptor);

394

}

395

});

396

397

// Count tests and containers

398

long testCount = allTests.size();

399

long containerCount = getAllDescriptors(engineDescriptor).stream()

400

.filter(d -> d.getType() == TestDescriptor.Type.CONTAINER)

401

.count();

402

```