The following code started in JUnit4 and has been mostly translated into JUnit5 except for main()
. The reason I'm writing it this way is that I'm demonstrating TDD and I have multiple versions of the StringInverter
implementation, each of which implements more features and passes more tests. Here is the StringInverter
interface:
interface StringInverter {
public String invert(String str);
}
And here's the almost-compiling-with-JUnit5 class:
import java.util.*;
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.platform.runner.JUnitPlatform;
public class StringInverterTest {
static StringInverter inverter;
@Test
public final void basicInversion_Succeed() {
String in = "Exit, Pursued by a Bear.";
String out = "eXIT, pURSUED BY A bEAR.";
assertEquals(inverter.invert(in), out);
}
@Test
public final void basicInversion_Fail() {
expectThrows(RuntimeException.class, () -> {
assertEquals(inverter.invert("X"), "X");
});
}
@Test
public final void allowedCharacters_Fail() {
expectThrows(RuntimeException.class, () -> {
inverter.invert(";-_()*&^%$#@!~`");
inverter.invert("0123456789");
});
}
@Test
public final void allowedCharacters_Succeed() {
inverter.invert("abcdefghijklmnopqrstuvwxyz ,.");
inverter.invert("ABCDEFGHIJKLMNOPQRSTUVWXYZ ,.");
}
@Test
public final void lengthLessThan26_Fail() {
String str = "xxxxxxxxxxxxxxxxxxxxxxxxxx";
assertTrue(str.length() > 25);
expectThrows(RuntimeException.class, () -> {
inverter.invert(str);
});
}
@Test
public final void lengthLessThan26_Succeed() {
String str = "xxxxxxxxxxxxxxxxxxxxxxxxx";
assertTrue(str.length() < 26);
inverter.invert(str);
}
public static void main(String[] args) throws Exception{
assertEquals(args.length, 1);
inverter = (StringInverter)
Class.forName(args[0]).newInstance();
Result result = org.junit.runner.JUnitCore.runClasses(
StringInverterTest.class);
List<Failure> failures = result.getFailures();
System.out.printf("%s has %d FAILURES:\n",
args[0], failures.size());
int count = 1;
for(Failure f : failures) {
System.out.printf("Failure %d:\n", count++);
System.out.println(f.getDescription());
System.out.println(f.getMessage());
}
}
}
main()
worked with JUnit4, so my question is how to convert it to JUnit 5. Thanks!
JUnit 4 came in a single artifact, blending all uses cases into one bundle. The JUnit 5 architecture promotes a better separation of concerns and provides clear APIs for testers (Jupiter) and tools (Platform).
JUnit 4 based Runner which runs tests on the JUnit Platform in a JUnit 4 environment. Annotating a class with @RunWith(JUnitPlatform. class) allows it to be run with IDEs and build systems that support JUnit 4 but do not yet support the JUnit Platform directly.
2.1. Just add the @Suite annotation of a class and start including or excluding the test classes and methods into the suite. When we want to run the suite, simply run it as a normal JUnit test class and it will execute all the included tests in the suite.
In JUnit 5, the @RunWith annotation has been replaced by the more powerful @ExtendWith annotation. However, the @RunWith annotation can still be used in JUnit 5 for the sake of backward compatibility.
I found a solution how to start unit tests from main static method.
Dependencies:
org.junit.jupiter:junit-jupiter-api:5.2.0
org.junit.platform:junit-platform-launcher:1.2.0
org.junit.jupiter:junit-jupiter-engine:5.2.0
Code example:
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.function.Executable;
import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
import org.junit.platform.launcher.Launcher;
import org.junit.platform.launcher.LauncherDiscoveryRequest;
import org.junit.platform.launcher.core.LauncherFactory;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import org.junit.platform.launcher.listeners.SummaryGeneratingListener;
import org.junit.platform.launcher.listeners.TestExecutionSummary;
import org.junit.platform.launcher.listeners.TestExecutionSummary.Failure;
import java.util.List;
public class MyClass {
public static void main(String args[]) {
final LauncherDiscoveryRequest request =
LauncherDiscoveryRequestBuilder.request()
.selectors(selectClass(MyClass.class))
.build();
final Launcher launcher = LauncherFactory.create();
final SummaryGeneratingListener listener = new SummaryGeneratingListener();
launcher.registerTestExecutionListeners(listener);
launcher.execute(request);
TestExecutionSummary summary = listener.getSummary();
long testFoundCount = summary.getTestsFoundCount();
List<Failure> failures = summary.getFailures();
System.out.println("getTestsSucceededCount() - " + summary.getTestsSucceededCount());
failures.forEach(failure -> System.out.println("failure - " + failure.getException()));
}
@Test
void exceptionTesting() {
Executable closureContainingCodeToTest = () -> {throw new IllegalArgumentException("a message");};
Throwable throwable = assertThrows(IllegalArgumentException.class, closureContainingCodeToTest, "a message");
assertEquals("a message", throwable.getMessage());
}
}
JUnit5 has launcher API in junit-platform-launcher module which is for programmatic test discovery and execution.
Detailed example is documented on their user guide chapter7.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With