Add JUnit 5 @RepeatedTest demo project
Initial commit of a Maven project demonstrating JUnit 5's @RepeatedTest annotation. Includes example tests for basic repetition, custom display names, metadata injection, lifecycle management, and failure thresholds. Project files include .gitignore, README, pom.xml, and test classes under src/test/java/com/ankurm/tutorials/junit/repeated.
This commit is contained in:
27
.gitignore
vendored
Normal file
27
.gitignore
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
replay_pid*
|
||||
|
||||
#IntelliJ IDEA
|
||||
.idea/
|
||||
37
RepeatedTest/README.md
Normal file
37
RepeatedTest/README.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# JUnit 5 @RepeatedTest Demonstration
|
||||
|
||||
This project demonstrates the usage of JUnit 5's `@RepeatedTest` annotation to improve test reliability and handle flaky tests.
|
||||
|
||||
## Concepts Covered
|
||||
|
||||
The code examples in `src/test/java/com/ankurTutorials/junit/repeated` cover the following concepts:
|
||||
|
||||
1. **Basic Repetition**: Repeating a test a specific number of times.
|
||||
- File: `ReliabilityTest.java`
|
||||
2. **Custom Display Names**: Configuring formatted names for each repetition for better reporting in CI/CD.
|
||||
- File: `CustomNameTest.java`
|
||||
3. **Metadata Injection**: Using `RepetitionInfo` to access the current repetition index and total count within the test.
|
||||
- File: `MetadataTest.java`
|
||||
4. **Lifecycle Management**: Understanding how `@BeforeEach` and `@AfterEach` interact with repeated tests (they run for *each* repetition).
|
||||
- File: `LifecycleTest.java`
|
||||
5. **Failure Thresholds**: Using the `failureThreshold` attribute (JUnit 5.10+) to stop execution early if a certain number of failures occur.
|
||||
- File: `FlakyServiceTest.java`
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Java 17 or higher
|
||||
- Maven 3.6+
|
||||
|
||||
## How to Run
|
||||
|
||||
To run all tests, execute the following command in the project root:
|
||||
|
||||
```bash
|
||||
mvn test
|
||||
```
|
||||
|
||||
To run a specific test class:
|
||||
|
||||
```bash
|
||||
mvn -Dtest=BasicUsageTest test
|
||||
```
|
||||
36
RepeatedTest/pom.xml
Normal file
36
RepeatedTest/pom.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.ankurTutorials</groupId>
|
||||
<artifactId>repeated-test-demo</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<junit.version>5.10.1</junit.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.2.3</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.ankurm.tutorials.junit.repeated;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.RepeatedTest;
|
||||
|
||||
public class CustomNameTest {
|
||||
|
||||
@RepeatedTest(value = 3, name = "{displayName} - Run {currentRepetition}/{totalRepetitions}")
|
||||
@DisplayName("Critical API Integration")
|
||||
void customNameTest() {
|
||||
System.out.println("Verifying external API stability...");
|
||||
// Logic to verify external API stability
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.ankurm.tutorials.junit.repeated;
|
||||
|
||||
import org.junit.jupiter.api.RepeatedTest;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
public class FlakyServiceTest {
|
||||
|
||||
// If 2 out of the 10 repetitions fail, JUnit stops further executions.
|
||||
// Note: failureThreshold requires JUnit 5.10+
|
||||
@RepeatedTest(value = 10, failureThreshold = 2)
|
||||
void flakyServiceTest() {
|
||||
// Simulating intermittent failure (mostly passing)
|
||||
// Using a high failure rate here to demonstrate the threshold quickly if run multiple times
|
||||
// or effectively showing it passes mostly.
|
||||
// Let's make it 30% failure chance.
|
||||
if (Math.random() < 0.3) {
|
||||
fail("Simulated random failure");
|
||||
}
|
||||
System.out.println("Test passed");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.ankurm.tutorials.junit.repeated;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.RepeatedTest;
|
||||
import org.junit.jupiter.api.RepetitionInfo;
|
||||
|
||||
public class LifecycleTest {
|
||||
|
||||
@BeforeEach
|
||||
void setUp(RepetitionInfo info) {
|
||||
System.out.println("BeforeEach: Setting up for repetition " + info.getCurrentRepetition());
|
||||
}
|
||||
|
||||
@RepeatedTest(3)
|
||||
void lifecycleTest() {
|
||||
System.out.println("Executing test logic...");
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown(RepetitionInfo info) {
|
||||
System.out.println("AfterEach: Cleaning up after repetition " + info.getCurrentRepetition());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.ankurm.tutorials.junit.repeated;
|
||||
|
||||
import org.junit.jupiter.api.RepeatedTest;
|
||||
import org.junit.jupiter.api.RepetitionInfo;
|
||||
|
||||
class MetadataTest {
|
||||
|
||||
@RepeatedTest(3)
|
||||
void testWithMetadata(RepetitionInfo info) {
|
||||
int current = info.getCurrentRepetition();
|
||||
int total = info.getTotalRepetitions();
|
||||
|
||||
// Log progress or vary data inputs based on 'current'
|
||||
System.out.println("Processing batch: " + current + " of " + total);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.ankurm.tutorials.junit.repeated;
|
||||
|
||||
import org.junit.jupiter.api.RepeatedTest;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class ReliabilityTest {
|
||||
|
||||
@RepeatedTest(5) // The test will run exactly 5 times
|
||||
void simpleRepeatTest() {
|
||||
System.out.println("Executing test...");
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user