or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bean-override-framework.mdindex.mdjdbc-testing.mdjunit-integration.mdmock-objects.mdtestcontext-framework.mdtesting-annotations.mdweb-testing.md

testing-annotations.mddocs/

0

# Testing Annotations

1

2

Spring Test provides a comprehensive set of annotations for configuring test behavior, context loading, and transaction management. These annotations enable declarative configuration of test scenarios and integration with the Spring TestContext Framework.

3

4

## Capabilities

5

6

### Context Configuration Annotations

7

8

Annotations for configuring the ApplicationContext in Spring tests.

9

10

```java { .api }

11

/**

12

* @TestPropertySource configures the locations of properties files and inlined properties

13

* to be added to the Environment's set of PropertySources for an ApplicationContext.

14

*/

15

@Target(ElementType.TYPE)

16

@Retention(RetentionPolicy.RUNTIME)

17

@Documented

18

@Inherited

19

public @interface TestPropertySource {

20

21

/**

22

* Alias for locations().

23

* @return an array of resource locations for properties files

24

*/

25

@AliasFor("locations")

26

String[] value() default {};

27

28

/**

29

* The resource locations of properties files to be loaded into the Environment's PropertySources.

30

* @return an array of resource locations

31

*/

32

@AliasFor("value")

33

String[] locations() default {};

34

35

/**

36

* Inlined properties in the form of key=value pairs to be added to the Environment's PropertySources.

37

* @return an array of inlined properties

38

*/

39

String[] properties() default {};

40

41

/**

42

* Whether or not test property source locations should be inherited from superclasses.

43

* @return true if locations should be inherited

44

*/

45

boolean inheritLocations() default true;

46

47

/**

48

* Whether or not inlined test properties should be inherited from superclasses.

49

* @return true if properties should be inherited

50

*/

51

boolean inheritProperties() default true;

52

53

/**

54

* The application context resource loading factory class to use.

55

* @return the factory class

56

*/

57

Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;

58

}

59

60

/**

61

* @DynamicPropertySource is a method-level annotation that can be used to register

62

* dynamic properties to be added to the Environment's set of PropertySources.

63

*/

64

@Target(ElementType.METHOD)

65

@Retention(RetentionPolicy.RUNTIME)

66

@Documented

67

public @interface DynamicPropertySource {

68

69

/**

70

* The name of the dynamic property source.

71

* @return the property source name

72

*/

73

String value() default "";

74

}

75

76

/**

77

* @WebAppConfiguration is a class-level annotation that is used to declare that

78

* the ApplicationContext loaded for an integration test should be a WebApplicationContext.

79

*/

80

@Target(ElementType.TYPE)

81

@Retention(RetentionPolicy.RUNTIME)

82

@Documented

83

@Inherited

84

public @interface WebAppConfiguration {

85

86

/**

87

* The resource path to the root of the web application.

88

* @return the resource path

89

*/

90

String value() default "src/main/webapp";

91

}

92

93

/**

94

* @BootstrapWith is a class-level annotation that is used to configure how the

95

* Spring TestContext Framework is bootstrapped.

96

*/

97

@Target(ElementType.TYPE)

98

@Retention(RetentionPolicy.RUNTIME)

99

@Documented

100

@Inherited

101

public @interface BootstrapWith {

102

103

/**

104

* The TestContextBootstrapper to use to bootstrap the TestContext Framework.

105

* @return the TestContextBootstrapper class

106

*/

107

Class<? extends TestContextBootstrapper> value() default TestContextBootstrapper.class;

108

}

109

```

110

111

### Test Execution Annotations

112

113

Annotations for controlling test execution behavior and lifecycle.

114

115

```java { .api }

116

/**

117

* @DirtiesContext indicates that the underlying Spring ApplicationContext has been

118

* dirtied during the execution of a test and should be closed and removed from the context cache.

119

*/

120

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

121

@Retention(RetentionPolicy.RUNTIME)

122

@Documented

123

@Inherited

124

public @interface DirtiesContext {

125

126

/**

127

* The mode to use when a test method is annotated with @DirtiesContext.

128

* @return the method mode

129

*/

130

MethodMode methodMode() default MethodMode.AFTER_METHOD;

131

132

/**

133

* The mode to use when a test class is annotated with @DirtiesContext.

134

* @return the class mode

135

*/

136

ClassMode classMode() default ClassMode.AFTER_CLASS;

137

138

/**

139

* The context hierarchy mode to use when @DirtiesContext is present on a test class.

140

* @return the hierarchy mode

141

*/

142

HierarchyMode hierarchyMode() default HierarchyMode.EXHAUSTIVE;

143

144

/**

145

* Defines modes which determine when a test class's ApplicationContext should be marked as dirty.

146

*/

147

enum ClassMode {

148

149

/**

150

* The associated ApplicationContext will be marked as dirty before the test class.

151

*/

152

BEFORE_CLASS,

153

154

/**

155

* The associated ApplicationContext will be marked as dirty before each test method in the class.

156

*/

157

BEFORE_EACH_TEST_METHOD,

158

159

/**

160

* The associated ApplicationContext will be marked as dirty after each test method in the class.

161

*/

162

AFTER_EACH_TEST_METHOD,

163

164

/**

165

* The associated ApplicationContext will be marked as dirty after the test class.

166

*/

167

AFTER_CLASS

168

}

169

170

/**

171

* Defines modes which determine when a test method's ApplicationContext should be marked as dirty.

172

*/

173

enum MethodMode {

174

175

/**

176

* The associated ApplicationContext will be marked as dirty before the test method.

177

*/

178

BEFORE_METHOD,

179

180

/**

181

* The associated ApplicationContext will be marked as dirty after the test method.

182

*/

183

AFTER_METHOD

184

}

185

186

/**

187

* Defines modes which determine how @DirtiesContext is interpreted when used in a test class hierarchy.

188

*/

189

enum HierarchyMode {

190

191

/**

192

* The ApplicationContext will be removed from the context cache along with all other

193

* contexts in the same hierarchy.

194

*/

195

EXHAUSTIVE,

196

197

/**

198

* Only the ApplicationContext of the current level in the context hierarchy will be removed from the context cache.

199

*/

200

CURRENT_LEVEL

201

}

202

}

203

204

/**

205

* @TestExecutionListeners defines class-level metadata for configuring which

206

* TestExecutionListeners should be registered with the TestContextManager.

207

*/

208

@Target(ElementType.TYPE)

209

@Retention(RetentionPolicy.RUNTIME)

210

@Documented

211

@Inherited

212

public @interface TestExecutionListeners {

213

214

/**

215

* The TestExecutionListeners to register with the TestContextManager.

216

* @return an array of TestExecutionListener classes

217

*/

218

Class<? extends TestExecutionListener>[] value() default {};

219

220

/**

221

* Alias for value().

222

* @return an array of TestExecutionListener classes

223

*/

224

@AliasFor("value")

225

Class<? extends TestExecutionListener>[] listeners() default {};

226

227

/**

228

* Whether or not TestExecutionListeners from superclasses should be inherited.

229

* @return true if listeners should be inherited

230

*/

231

boolean inheritListeners() default true;

232

233

/**

234

* The merge mode to use when @TestExecutionListeners is declared on a class

235

* that does not inherit listeners from a superclass.

236

* @return the merge mode

237

*/

238

MergeMode mergeMode() default MergeMode.REPLACE_DEFAULTS;

239

240

/**

241

* Enumeration of modes that dictate whether explicitly declared listeners are

242

* merged with the default listeners when @TestExecutionListeners is declared on a class.

243

*/

244

enum MergeMode {

245

246

/**

247

* Locally declared listeners should be merged with the default listeners.

248

*/

249

MERGE_WITH_DEFAULTS,

250

251

/**

252

* Locally declared listeners should replace the default listeners.

253

*/

254

REPLACE_DEFAULTS

255

}

256

}

257

258

/**

259

* @RecordApplicationEvents is a class-level annotation that is used to instruct the

260

* Spring TestContext Framework to record all application events that are published

261

* in the ApplicationContext during the execution of a single test.

262

*/

263

@Target(ElementType.TYPE)

264

@Retention(RetentionPolicy.RUNTIME)

265

@Documented

266

@Inherited

267

public @interface RecordApplicationEvents {

268

}

269

```

270

271

### Transaction Annotations

272

273

Annotations for controlling transactional behavior in tests.

274

275

```java { .api }

276

/**

277

* @Transactional can be used to configure transactional test methods to run within a transaction.

278

* When used at the class level, it establishes default transaction semantics for all test methods.

279

*/

280

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

281

@Retention(RetentionPolicy.RUNTIME)

282

@Documented

283

@Inherited

284

public @interface Transactional {

285

286

/**

287

* Alias for transactionManager().

288

* @return the transaction manager bean name

289

*/

290

@AliasFor("transactionManager")

291

String value() default "";

292

293

/**

294

* The bean name of the PlatformTransactionManager that should be used to drive transactions.

295

* @return the transaction manager bean name

296

*/

297

@AliasFor("value")

298

String transactionManager() default "";

299

300

/**

301

* The transaction propagation type.

302

* @return the propagation type

303

*/

304

Propagation propagation() default Propagation.REQUIRED;

305

306

/**

307

* The transaction isolation level.

308

* @return the isolation level

309

*/

310

Isolation isolation() default Isolation.DEFAULT;

311

312

/**

313

* The timeout for this transaction (in seconds).

314

* @return the timeout value

315

*/

316

int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;

317

318

/**

319

* The timeout for this transaction (in seconds).

320

* @return the timeout value as a String

321

*/

322

String timeoutString() default "";

323

324

/**

325

* A boolean flag that can be set to true if the transaction is effectively read-only.

326

* @return true if the transaction is read-only

327

*/

328

boolean readOnly() default false;

329

330

/**

331

* Defines zero or more exception classes, which must be subclasses of Throwable,

332

* indicating which exception types must cause a transaction rollback.

333

* @return an array of exception classes

334

*/

335

Class<? extends Throwable>[] rollbackFor() default {};

336

337

/**

338

* Defines zero or more exception class names (for exceptions which must be subclasses of Throwable)

339

* indicating which exception types must cause a transaction rollback.

340

* @return an array of exception class names

341

*/

342

String[] rollbackForClassName() default {};

343

344

/**

345

* Defines zero or more exception classes, which must be subclasses of Throwable,

346

* indicating which exception types must not cause a transaction rollback.

347

* @return an array of exception classes

348

*/

349

Class<? extends Throwable>[] noRollbackFor() default {};

350

351

/**

352

* Defines zero or more exception class names (for exceptions which must be subclasses of Throwable)

353

* indicating which exception types must not cause a transaction rollback.

354

* @return an array of exception class names

355

*/

356

String[] noRollbackForClassName() default {};

357

}

358

359

/**

360

* @Rollback indicates whether the transaction for a transactional test method should be rolled back

361

* after the test method has completed.

362

*/

363

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

364

@Retention(RetentionPolicy.RUNTIME)

365

@Documented

366

@Inherited

367

public @interface Rollback {

368

369

/**

370

* Whether the transaction should be rolled back after the test has completed.

371

* @return true if the transaction should be rolled back

372

*/

373

boolean value() default true;

374

}

375

376

/**

377

* @Commit indicates that the transaction for a transactional test method should be committed

378

* after the test method has completed.

379

*/

380

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

381

@Retention(RetentionPolicy.RUNTIME)

382

@Documented

383

@Inherited

384

public @interface Commit {

385

}

386

```

387

388

### Test Method Annotations

389

390

Annotations for individual test method configuration and execution control.

391

392

```java { .api }

393

/**

394

* @Repeat indicates that the annotated test method should be executed repeatedly.

395

*/

396

@Target(ElementType.METHOD)

397

@Retention(RetentionPolicy.RUNTIME)

398

@Documented

399

public @interface Repeat {

400

401

/**

402

* The number of times that the annotated test method should be repeated.

403

* @return the repeat count

404

*/

405

int value() default 1;

406

}

407

408

/**

409

* @Timed indicates that the annotated test method must finish execution in a specified time period.

410

*/

411

@Target(ElementType.METHOD)

412

@Retention(RetentionPolicy.RUNTIME)

413

@Documented

414

public @interface Timed {

415

416

/**

417

* The maximum amount of time (in milliseconds) that the test execution can take

418

* without being marked as failed due to taking too long.

419

* @return the timeout in milliseconds

420

*/

421

long millis() default 0L;

422

}

423

424

/**

425

* @IfProfileValue indicates that the annotated test is enabled for a specific testing environment.

426

*/

427

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

428

@Retention(RetentionPolicy.RUNTIME)

429

@Documented

430

@Inherited

431

public @interface IfProfileValue {

432

433

/**

434

* The name of the profile value against which to test.

435

* @return the profile value name

436

*/

437

String name() default "";

438

439

/**

440

* The expected value of the named profile value.

441

* @return the expected value

442

*/

443

String value() default "";

444

445

/**

446

* A list of all expected values for the named profile value.

447

* @return an array of expected values

448

*/

449

String[] values() default {};

450

}

451

452

/**

453

* @ProfileValueSourceConfiguration is a class-level annotation that is used to specify

454

* what type of ProfileValueSource to use when retrieving profile values configured via @IfProfileValue.

455

*/

456

@Target(ElementType.TYPE)

457

@Retention(RetentionPolicy.RUNTIME)

458

@Documented

459

@Inherited

460

public @interface ProfileValueSourceConfiguration {

461

462

/**

463

* The type of ProfileValueSource to use when retrieving profile values.

464

* @return the ProfileValueSource class

465

*/

466

Class<? extends ProfileValueSource> value() default SystemProfileValueSource.class;

467

}

468

```

469

470

**Usage Examples:**

471

472

```java

473

import org.springframework.test.annotation.*;

474

import org.springframework.test.context.*;

475

import org.springframework.transaction.annotation.Transactional;

476

477

// Basic test configuration

478

@SpringJUnitConfig(TestConfig.class)

479

@TestPropertySource(locations = "/test.properties",

480

properties = {"app.name=TestApp", "debug=true"})

481

@ActiveProfiles("test")

482

class UserServiceTest {

483

484

@Autowired

485

private UserService userService;

486

487

@Test

488

@Transactional

489

@Rollback

490

void shouldCreateUserInTransaction() {

491

User user = new User("John", "john@example.com");

492

User saved = userService.save(user);

493

assertThat(saved.getId()).isNotNull();

494

// Transaction will be rolled back

495

}

496

497

@Test

498

@Transactional

499

@Commit

500

void shouldCommitUserCreation() {

501

User user = new User("Jane", "jane@example.com");

502

userService.save(user);

503

// Transaction will be committed

504

}

505

}

506

507

// Dynamic property configuration

508

@SpringJUnitConfig(DatabaseTestConfig.class)

509

class DatabaseIntegrationTest {

510

511

@DynamicPropertySource

512

static void configureDatabaseProperties(DynamicPropertyRegistry registry) {

513

registry.add("spring.datasource.url", () -> database.getJdbcUrl());

514

registry.add("spring.datasource.username", database::getUsername);

515

registry.add("spring.datasource.password", database::getPassword);

516

}

517

518

@Test

519

void shouldConnectToDatabase() {

520

// Test with dynamic database configuration

521

}

522

}

523

524

// Context dirtying scenarios

525

@SpringJUnitConfig(CacheTestConfig.class)

526

@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)

527

class CacheIntegrationTest {

528

529

@Autowired

530

private CacheManager cacheManager;

531

532

@Test

533

void shouldCacheData() {

534

// Test caching behavior

535

// Context will be marked dirty after this method

536

}

537

538

@Test

539

@DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)

540

void shouldStartWithCleanCache() {

541

// Context will be marked dirty before this method

542

// Test with fresh cache

543

}

544

}

545

546

// Web application configuration

547

@SpringJUnitWebConfig(WebConfig.class)

548

@WebAppConfiguration("src/test/webapp")

549

class WebControllerTest {

550

551

@Autowired

552

private WebApplicationContext webContext;

553

554

@Autowired

555

private MockMvc mockMvc;

556

557

@Test

558

void shouldLoadWebContext() {

559

assertThat(webContext).isNotNull();

560

assertThat(webContext.getServletContext()).isNotNull();

561

}

562

}

563

564

// Profile-based conditional execution

565

@SpringJUnitConfig(ProfileTestConfig.class)

566

@ProfileValueSourceConfiguration(SystemProfileValueSource.class)

567

class ConditionalTest {

568

569

@Test

570

@IfProfileValue(name = "test.environment", value = "integration")

571

void shouldRunOnlyInIntegrationEnvironment() {

572

// This test runs only when system property test.environment=integration

573

}

574

575

@Test

576

@IfProfileValue(name = "os.name", values = {"Linux", "Mac OS X"})

577

void shouldRunOnUnixSystems() {

578

// This test runs only on specified operating systems

579

}

580

}

581

582

// Repeated execution and timing

583

@SpringJUnitConfig(PerformanceTestConfig.class)

584

class PerformanceTest {

585

586

@Test

587

@Repeat(5)

588

@Timed(millis = 1000)

589

void shouldCompleteWithin1Second() {

590

// This test will be repeated 5 times and must complete within 1 second each time

591

performanceService.executeOperation();

592

}

593

}

594

595

// Event recording

596

@SpringJUnitConfig(EventTestConfig.class)

597

@RecordApplicationEvents

598

class EventPublishingTest {

599

600

@Autowired

601

private ApplicationEventPublisher eventPublisher;

602

603

@Autowired

604

private ApplicationEvents events;

605

606

@Test

607

void shouldRecordPublishedEvents() {

608

eventPublisher.publishEvent(new UserCreatedEvent("John"));

609

eventPublisher.publishEvent(new UserUpdatedEvent("John"));

610

611

assertThat(events.stream(UserCreatedEvent.class)).hasSize(1);

612

assertThat(events.stream(UserUpdatedEvent.class)).hasSize(1);

613

assertThat(events.stream().count()).isEqualTo(2);

614

}

615

}

616

617

// Custom test execution listeners

618

@SpringJUnitConfig(CustomTestConfig.class)

619

@TestExecutionListeners(

620

listeners = {CustomTestExecutionListener.class, MetricsCollectionListener.class},

621

mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS

622

)

623

class CustomExecutionTest {

624

625

@Test

626

void shouldUseCustomListeners() {

627

// Test will execute with custom listeners in addition to default ones

628

}

629

}

630

```

631

632

## Types

633

634

```java { .api }

635

/**

636

* Strategy interface for providing profile values programmatically.

637

*/

638

public interface ProfileValueSource {

639

640

/**

641

* Get the profile value indicated by the specified key.

642

* @param key the name of the profile value

643

* @return the String value of the profile value, or null if there is no value with that key

644

*/

645

@Nullable

646

String get(String key);

647

}

648

649

/**

650

* Default implementation of ProfileValueSource which resolves system properties

651

* and system environment variables.

652

*/

653

public class SystemProfileValueSource implements ProfileValueSource {

654

655

/**

656

* Get the profile value for the given key from system properties,

657

* falling back to environment variables if not found.

658

* @param key the profile value key

659

* @return the profile value, or null if not found

660

*/

661

@Nullable

662

@Override

663

public String get(String key);

664

}

665

666

/**

667

* Registry for dynamic properties to be added to the Environment during test execution.

668

*/

669

public interface DynamicPropertyRegistry {

670

671

/**

672

* Add a dynamic property with the given name and Supplier of the value.

673

* @param name the property name

674

* @param valueSupplier a supplier for the property value

675

*/

676

void add(String name, Supplier<Object> valueSupplier);

677

678

/**

679

* Add a dynamic property with the given name and value.

680

* @param name the property name

681

* @param value the property value

682

*/

683

void add(String name, Object value);

684

}

685

686

/**

687

* ApplicationEvents encapsulates all ApplicationEvents that were published

688

* during the execution of a single test and provides methods to interact with those events.

689

*/

690

public interface ApplicationEvents {

691

692

/**

693

* Get a stream of all application events of the specified type that were published during test execution.

694

* @param type the event type

695

* @param <T> the event type

696

* @return a stream of events of the specified type

697

*/

698

<T extends ApplicationEvent> Stream<T> stream(Class<T> type);

699

700

/**

701

* Get a stream of all application events that were published during test execution.

702

* @return a stream of all events

703

*/

704

Stream<ApplicationEvent> stream();

705

706

/**

707

* Clear all recorded events.

708

*/

709

void clear();

710

}

711

712

### Additional Testing Annotations

713

714

Key annotations for advanced test configuration and execution control.

715

716

```java { .api }

717

/**

718

* @RecordApplicationEvents indicates that ApplicationEvents published in the ApplicationContext

719

* should be recorded and made available to the test via ApplicationEvents.

720

*/

721

@Target(ElementType.TYPE)

722

@Retention(RetentionPolicy.RUNTIME)

723

@Documented

724

@Inherited

725

public @interface RecordApplicationEvents {

726

}

727

728

/**

729

* @DisabledInAotMode indicates that the annotated test class or test method should be disabled

730

* when running in AOT (ahead-of-time) processing mode.

731

*/

732

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

733

@Retention(RetentionPolicy.RUNTIME)

734

@Documented

735

public @interface DisabledInAotMode {

736

737

/**

738

* The reason this test is disabled in AOT mode.

739

* @return the reason for disabling in AOT mode

740

*/

741

String value() default "";

742

}

743

744

/**

745

* @NestedTestConfiguration indicates how test configuration should be handled for @Nested test classes.

746

*/

747

@Target(ElementType.TYPE)

748

@Retention(RetentionPolicy.RUNTIME)

749

@Documented

750

@Inherited

751

public @interface NestedTestConfiguration {

752

753

/**

754

* The nested test configuration mode.

755

* @return the configuration mode

756

*/

757

EnclosingConfiguration value();

758

759

/**

760

* Enum defining nested test configuration behavior.

761

*/

762

enum EnclosingConfiguration {

763

/**

764

* Inherit configuration from the enclosing test class.

765

*/

766

INHERIT,

767

768

/**

769

* Override configuration from the enclosing test class.

770

*/

771

OVERRIDE

772

}

773

}

774

775

/**

776

* @DynamicPropertySource can be used to register dynamic properties to be added to

777

* the Environment's set of PropertySources for an ApplicationContext loaded for an integration test.

778

*/

779

@Target(ElementType.METHOD)

780

@Retention(RetentionPolicy.RUNTIME)

781

@Documented

782

public @interface DynamicPropertySource {

783

784

/**

785

* The name that can be used to reference this dynamic property source.

786

* @return the name for this property source

787

*/

788

String value() default "";

789

}

790

```

791

792

### Types

793

794

```java { .api }

795

/**

796

* Functional interface for dynamic property registration.

797

*/

798

@FunctionalInterface

799

public interface DynamicPropertyRegistry {

800

801

/**

802

* Add a Supplier for the given property name to this registry.

803

* @param name the property name

804

* @param valueSupplier the supplier for the property value

805

*/

806

void add(String name, Supplier<Object> valueSupplier);

807

}

808

```

809

810

/**

811

* Utility class for working with test annotations.

812

*/

813

public abstract class TestAnnotationUtils {

814

815

/**

816

* Get the repeat count for the specified test method.

817

* @param testMethod the test method

818

* @return the repeat count, or 1 if no @Repeat annotation is present

819

*/

820

public static int getRepeatCount(Method testMethod);

821

822

/**

823

* Get the timeout for the specified test method.

824

* @param testMethod the test method

825

* @return the timeout in milliseconds, or 0 if no @Timed annotation is present

826

*/

827

public static long getTimeout(Method testMethod);

828

829

/**

830

* Determine if the supplied test method is annotated with @Timed.

831

* @param testMethod the test method to check

832

* @return true if the method is annotated with @Timed

833

*/

834

public static boolean isTimed(Method testMethod);

835

836

/**

837

* Determine if the supplied test method is annotated with @Repeat.

838

* @param testMethod the test method to check

839

* @return true if the method is annotated with @Repeat

840

*/

841

public static boolean isRepeated(Method testMethod);

842

}

843

```