or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotations.mdassertions.mdassumptions.mdcategories.mdindex.mdmatchers.mdrules.mdstandard-runners.mdtest-runners.mdtheories.md

annotations.mddocs/

0

# Test Annotations

1

2

Annotations are the primary mechanism in JUnit 4 for marking test methods and controlling test execution lifecycle. They provide a declarative way to define test structure, setup and teardown procedures, test execution rules, and method ordering.

3

4

## Capabilities

5

6

### Test Annotation

7

8

Marks a method as a test method. The test method will be executed by the JUnit runner. Supports optional `expected` parameter for exception testing and `timeout` parameter for performance testing.

9

10

```java { .api }

11

/**

12

* Marks a method as a test method

13

* @param expected - Optional: the exception class that the test is expected to throw

14

* @param timeout - Optional: timeout in milliseconds, test fails if it runs longer

15

*/

16

@Retention(RetentionPolicy.RUNTIME)

17

@Target(ElementType.METHOD)

18

public @interface Test {

19

Class<? extends Throwable> expected() default None.class;

20

long timeout() default 0L;

21

}

22

```

23

24

**Usage Examples:**

25

26

```java

27

import org.junit.Test;

28

import static org.junit.Assert.*;

29

30

public class BasicTest {

31

@Test

32

public void simpleTest() {

33

assertEquals(4, 2 + 2);

34

}

35

36

@Test(expected = IllegalArgumentException.class)

37

public void testException() {

38

throw new IllegalArgumentException("Expected exception");

39

}

40

41

@Test(timeout = 1000)

42

public void testTimeout() {

43

// Test fails if this takes more than 1 second

44

performQuickOperation();

45

}

46

}

47

```

48

49

### Before Annotation

50

51

Marks a method to run before each test method in the class. Use for test setup that needs to be fresh for each test. The method must be public void with no parameters.

52

53

```java { .api }

54

/**

55

* Marks a method to run before each test method

56

* The annotated method must be public, void, and take no parameters

57

*/

58

@Retention(RetentionPolicy.RUNTIME)

59

@Target(ElementType.METHOD)

60

public @interface Before {}

61

```

62

63

**Usage Examples:**

64

65

```java

66

import org.junit.Before;

67

import org.junit.Test;

68

import java.util.ArrayList;

69

import java.util.List;

70

71

public class ListTest {

72

private List<String> list;

73

74

@Before

75

public void setUp() {

76

list = new ArrayList<>();

77

list.add("initial");

78

}

79

80

@Test

81

public void testListSize() {

82

assertEquals(1, list.size());

83

}

84

85

@Test

86

public void testListAdd() {

87

list.add("second");

88

assertEquals(2, list.size());

89

}

90

}

91

```

92

93

### After Annotation

94

95

Marks a method to run after each test method in the class. Use for test cleanup and resource disposal. Runs even if the test or `@Before` method throws an exception.

96

97

```java { .api }

98

/**

99

* Marks a method to run after each test method

100

* The annotated method must be public, void, and take no parameters

101

* Runs even if the test or @Before method fails

102

*/

103

@Retention(RetentionPolicy.RUNTIME)

104

@Target(ElementType.METHOD)

105

public @interface After {}

106

```

107

108

**Usage Examples:**

109

110

```java

111

import org.junit.After;

112

import org.junit.Before;

113

import org.junit.Test;

114

import java.io.File;

115

import java.io.FileWriter;

116

import java.io.IOException;

117

118

public class FileTest {

119

private File tempFile;

120

121

@Before

122

public void createFile() throws IOException {

123

tempFile = File.createTempFile("test", ".txt");

124

}

125

126

@Test

127

public void testFileWrite() throws IOException {

128

FileWriter writer = new FileWriter(tempFile);

129

writer.write("test data");

130

writer.close();

131

assertTrue(tempFile.length() > 0);

132

}

133

134

@After

135

public void cleanup() {

136

if (tempFile != null && tempFile.exists()) {

137

tempFile.delete();

138

}

139

}

140

}

141

```

142

143

### BeforeClass Annotation

144

145

Marks a static method to run once before all test methods in the class. Use for expensive setup that can be shared across tests. The method must be public static void with no parameters.

146

147

```java { .api }

148

/**

149

* Marks a static method to run once before all test methods in the class

150

* The annotated method must be public, static, void, and take no parameters

151

*/

152

@Retention(RetentionPolicy.RUNTIME)

153

@Target(ElementType.METHOD)

154

public @interface BeforeClass {}

155

```

156

157

**Usage Examples:**

158

159

```java

160

import org.junit.BeforeClass;

161

import org.junit.Test;

162

import java.sql.Connection;

163

import java.sql.DriverManager;

164

165

public class DatabaseTest {

166

private static Connection connection;

167

168

@BeforeClass

169

public static void connectToDatabase() throws Exception {

170

// Expensive operation done once for all tests

171

connection = DriverManager.getConnection("jdbc:h2:mem:test");

172

connection.createStatement().execute("CREATE TABLE users (id INT, name VARCHAR(255))");

173

}

174

175

@Test

176

public void testInsert() throws Exception {

177

connection.createStatement().execute("INSERT INTO users VALUES (1, 'Alice')");

178

}

179

180

@Test

181

public void testQuery() throws Exception {

182

// Connection is already established

183

var result = connection.createStatement().executeQuery("SELECT COUNT(*) FROM users");

184

assertTrue(result.next());

185

}

186

}

187

```

188

189

### AfterClass Annotation

190

191

Marks a static method to run once after all test methods in the class. Use for cleanup of resources established in `@BeforeClass`. Runs even if tests fail.

192

193

```java { .api }

194

/**

195

* Marks a static method to run once after all test methods in the class

196

* The annotated method must be public, static, void, and take no parameters

197

* Runs even if tests or @BeforeClass method fail

198

*/

199

@Retention(RetentionPolicy.RUNTIME)

200

@Target(ElementType.METHOD)

201

public @interface AfterClass {}

202

```

203

204

**Usage Examples:**

205

206

```java

207

import org.junit.AfterClass;

208

import org.junit.BeforeClass;

209

import org.junit.Test;

210

211

public class ResourceTest {

212

private static ExpensiveResource resource;

213

214

@BeforeClass

215

public static void setUp() {

216

resource = new ExpensiveResource();

217

resource.initialize();

218

}

219

220

@Test

221

public void testOperation1() {

222

resource.performOperation();

223

}

224

225

@Test

226

public void testOperation2() {

227

resource.performAnotherOperation();

228

}

229

230

@AfterClass

231

public static void tearDown() {

232

if (resource != null) {

233

resource.cleanup();

234

resource = null;

235

}

236

}

237

}

238

```

239

240

### Ignore Annotation

241

242

Marks a test method or test class to be ignored (not executed). Useful for temporarily disabling tests without deleting them. Can include an optional message explaining why the test is ignored.

243

244

```java { .api }

245

/**

246

* Marks a test method or test class to be ignored

247

* @param value - Optional message explaining why the test is ignored

248

*/

249

@Retention(RetentionPolicy.RUNTIME)

250

@Target({ElementType.METHOD, ElementType.TYPE})

251

public @interface Ignore {

252

String value() default "";

253

}

254

```

255

256

**Usage Examples:**

257

258

```java

259

import org.junit.Ignore;

260

import org.junit.Test;

261

262

public class FeatureTest {

263

@Test

264

public void testWorkingFeature() {

265

// This test runs normally

266

assertTrue(true);

267

}

268

269

@Test

270

@Ignore("Feature not yet implemented")

271

public void testNewFeature() {

272

// This test is skipped

273

implementNewFeature();

274

}

275

276

@Test

277

@Ignore

278

public void testBrokenFeature() {

279

// This test is skipped without a message

280

brokenFunction();

281

}

282

}

283

284

// Ignore entire test class

285

@Ignore("Deprecated functionality, will be removed")

286

public class LegacyTest {

287

@Test

288

public void test1() {

289

// All tests in this class are ignored

290

}

291

292

@Test

293

public void test2() {

294

// This is also ignored

295

}

296

}

297

```

298

299

### Rule Annotation

300

301

Marks a field or method that returns a `TestRule` to be applied to each test method. Rules add behavior around test execution such as timeout enforcement, exception handling, or resource management.

302

303

```java { .api }

304

/**

305

* Marks a field or method that returns a TestRule

306

* The field must be public and of type TestRule or MethodRule

307

* If a method, it must be public and return TestRule or MethodRule

308

* @param order - Optional order for rule execution (default -1)

309

*/

310

@Retention(RetentionPolicy.RUNTIME)

311

@Target({ElementType.FIELD, ElementType.METHOD})

312

public @interface Rule {

313

int order() default -1;

314

}

315

```

316

317

**Usage Examples:**

318

319

```java

320

import org.junit.Rule;

321

import org.junit.Test;

322

import org.junit.rules.TemporaryFolder;

323

import org.junit.rules.Timeout;

324

import java.io.File;

325

import java.io.IOException;

326

327

public class RuleTest {

328

@Rule

329

public TemporaryFolder folder = new TemporaryFolder();

330

331

@Rule

332

public Timeout globalTimeout = Timeout.seconds(10);

333

334

@Test

335

public void testUsingTempFolder() throws IOException {

336

File file = folder.newFile("test.txt");

337

assertTrue(file.exists());

338

// File automatically deleted after test

339

}

340

341

@Test

342

public void testWithTimeout() {

343

// This test must complete within 10 seconds

344

performOperation();

345

}

346

}

347

```

348

349

### ClassRule Annotation

350

351

Marks a static field or method that returns a `TestRule` to be applied once for the entire test class. Useful for expensive setup that should be shared across all tests.

352

353

```java { .api }

354

/**

355

* Marks a static field or method that returns a TestRule for the entire class

356

* The field must be public static and of type TestRule

357

* If a method, it must be public static and return TestRule

358

* @param order - Optional order for rule execution (default -1)

359

*/

360

@Retention(RetentionPolicy.RUNTIME)

361

@Target({ElementType.FIELD, ElementType.METHOD})

362

public @interface ClassRule {

363

int order() default -1;

364

}

365

```

366

367

**Usage Examples:**

368

369

```java

370

import org.junit.ClassRule;

371

import org.junit.Test;

372

import org.junit.rules.ExternalResource;

373

import org.junit.rules.TemporaryFolder;

374

375

public class ClassRuleTest {

376

@ClassRule

377

public static TemporaryFolder folder = new TemporaryFolder();

378

379

@ClassRule

380

public static ExternalResource resource = new ExternalResource() {

381

@Override

382

protected void before() throws Throwable {

383

// Setup once for all tests

384

System.out.println("Starting test class");

385

}

386

387

@Override

388

protected void after() {

389

// Cleanup once after all tests

390

System.out.println("Finished test class");

391

}

392

};

393

394

@Test

395

public void test1() {

396

// Both rules are applied

397

}

398

399

@Test

400

public void test2() {

401

// Same rule instances used

402

}

403

}

404

```

405

406

### FixMethodOrder Annotation

407

408

Specifies the order in which test methods in a class should be executed. By default, JUnit executes methods in an unpredictable order for test isolation.

409

410

```java { .api }

411

/**

412

* Specifies the execution order for test methods in a class

413

* @param value - The ordering strategy to use

414

*/

415

@Retention(RetentionPolicy.RUNTIME)

416

@Target(ElementType.TYPE)

417

public @interface FixMethodOrder {

418

MethodSorters value();

419

}

420

```

421

422

**Usage Examples:**

423

424

```java

425

import org.junit.FixMethodOrder;

426

import org.junit.Test;

427

import org.junit.runners.MethodSorters;

428

429

@FixMethodOrder(MethodSorters.NAME_ASCENDING)

430

public class OrderedTest {

431

@Test

432

public void test1_first() {

433

System.out.println("Runs first (alphabetically)");

434

}

435

436

@Test

437

public void test2_second() {

438

System.out.println("Runs second");

439

}

440

441

@Test

442

public void test3_third() {

443

System.out.println("Runs third");

444

}

445

}

446

447

@FixMethodOrder(MethodSorters.JVM)

448

public class JvmOrderTest {

449

// Tests run in JVM-returned order (varies by JVM)

450

@Test

451

public void testA() {}

452

453

@Test

454

public void testB() {}

455

}

456

```

457

458

### RunWith Annotation

459

460

Specifies a custom runner class to execute the tests instead of the default JUnit 4 runner. Essential for using alternative runners like `Suite`, `Parameterized`, or `Theories`.

461

462

```java { .api }

463

/**

464

* Specifies a custom runner class for executing tests

465

* @param value - The Runner class to use

466

*/

467

@Retention(RetentionPolicy.RUNTIME)

468

@Target(ElementType.TYPE)

469

@Inherited

470

public @interface RunWith {

471

Class<? extends Runner> value();

472

}

473

```

474

475

**Usage Examples:**

476

477

```java

478

import org.junit.runner.RunWith;

479

import org.junit.runners.Suite;

480

import org.junit.runners.Suite.SuiteClasses;

481

import org.junit.runners.Parameterized;

482

import org.junit.Test;

483

484

// Using Suite runner

485

@RunWith(Suite.class)

486

@SuiteClasses({TestClass1.class, TestClass2.class, TestClass3.class})

487

public class AllTests {

488

// Runs all tests from the specified classes

489

}

490

491

// Using Parameterized runner

492

@RunWith(Parameterized.class)

493

public class FibonacciTest {

494

@Parameterized.Parameter(0)

495

public int input;

496

497

@Parameterized.Parameter(1)

498

public int expected;

499

500

@Parameterized.Parameters

501

public static Collection<Object[]> data() {

502

return Arrays.asList(new Object[][] {

503

{0, 0}, {1, 1}, {2, 1}, {3, 2}, {4, 3}, {5, 5}

504

});

505

}

506

507

@Test

508

public void testFibonacci() {

509

assertEquals(expected, Fibonacci.compute(input));

510

}

511

}

512

```

513

514

### ValidateWith Annotation

515

516

Allows for a custom validator to be attached to an annotation. When attached to an annotation, the validator will be instantiated and invoked by the test runner.

517

518

```java { .api }

519

/**

520

* Attaches an AnnotationValidator to an annotation

521

* @param value - The AnnotationValidator class to use

522

* @since 4.12

523

*/

524

@Retention(RetentionPolicy.RUNTIME)

525

@Target(ElementType.ANNOTATION_TYPE)

526

@Inherited

527

public @interface ValidateWith {

528

Class<? extends AnnotationValidator> value();

529

}

530

531

/**

532

* Validates annotations on classes, methods, and fields.

533

* Instances must be immutable and thread-safe as they are shared by multiple test runners.

534

* @since 4.12

535

*/

536

public abstract class AnnotationValidator {

537

/**

538

* Validates annotation on the given class

539

* @param testClass - Class being validated

540

* @return List of validation exceptions (empty if valid)

541

*/

542

public List<Exception> validateAnnotatedClass(TestClass testClass);

543

544

/**

545

* Validates annotation on the given field

546

* @param field - Field being validated

547

* @return List of validation exceptions (empty if valid)

548

*/

549

public List<Exception> validateAnnotatedField(FrameworkField field);

550

551

/**

552

* Validates annotation on the given method

553

* @param method - Method being validated

554

* @return List of validation exceptions (empty if valid)

555

*/

556

public List<Exception> validateAnnotatedMethod(FrameworkMethod method);

557

}

558

```

559

560

**Usage Examples:**

561

562

```java

563

import org.junit.validator.ValidateWith;

564

import org.junit.validator.AnnotationValidator;

565

import org.junit.runners.model.TestClass;

566

567

import java.lang.annotation.*;

568

import java.util.ArrayList;

569

import java.util.List;

570

571

// Define custom annotation with validator

572

@Retention(RetentionPolicy.RUNTIME)

573

@Target(ElementType.TYPE)

574

@ValidateWith(RequiresJava8Validator.class)

575

public @interface RequiresJava8 {}

576

577

// Implement the validator

578

public class RequiresJava8Validator extends AnnotationValidator {

579

@Override

580

public List<Exception> validateAnnotatedClass(TestClass testClass) {

581

List<Exception> errors = new ArrayList<>();

582

String javaVersion = System.getProperty("java.version");

583

if (!javaVersion.startsWith("1.8") && !javaVersion.startsWith("8")) {

584

errors.add(new Exception(

585

"Test requires Java 8 but running on " + javaVersion));

586

}

587

return errors;

588

}

589

}

590

591

// Use the validated annotation

592

@RequiresJava8

593

public class Java8OnlyTest {

594

@Test

595

public void testStreamApi() {

596

// Test will only run on Java 8+

597

}

598

}

599

```

600

601

### OrderWith Annotation

602

603

Specifies a custom ordering for test methods. Allows fine-grained control over test execution order beyond the basic alphabetical or JVM ordering.

604

605

```java { .api }

606

/**

607

* Specifies an ordering for test methods

608

* @param value - The Ordering.Factory class to use

609

*/

610

@Retention(RetentionPolicy.RUNTIME)

611

@Target(ElementType.TYPE)

612

@Inherited

613

@ValidateWith(OrderWithValidator.class)

614

public @interface OrderWith {

615

Class<? extends Ordering.Factory> value();

616

}

617

```

618

619

**Usage Examples:**

620

621

```java

622

import org.junit.runner.OrderWith;

623

import org.junit.runner.manipulation.Alphanumeric;

624

import org.junit.Test;

625

626

@OrderWith(Alphanumeric.class)

627

public class CustomOrderedTest {

628

@Test

629

public void testA() {

630

// Tests run in alphanumeric order

631

System.out.println("Test A");

632

}

633

634

@Test

635

public void testB() {

636

System.out.println("Test B");

637

}

638

}

639

```

640

641

## Types

642

643

```java { .api }

644

/**

645

* Method ordering strategies for @FixMethodOrder

646

*/

647

public enum MethodSorters {

648

/**

649

* Sorts methods by method name, in lexicographic order

650

*/

651

NAME_ASCENDING,

652

653

/**

654

* Leaves test methods in order returned by JVM (may vary)

655

*/

656

JVM,

657

658

/**

659

* Default - pseudo-random order that changes between runs

660

*/

661

DEFAULT

662

}

663

664

/**

665

* Placeholder class for @Test annotation's default expected value

666

*/

667

public class None extends Throwable {

668

private None() {}

669

}

670

```

671