I have a bunch of junit 5 Tests, some of which are Parameterized, and I want to call them from a java class.
The test runs successfully through IDE or using gradle clean build when kept in src/test folder but thats not my goal.
I want to be able to call this test from a separate java class(say a controller whose endpoint I can expose and call, whenever I need to trigger these tests)
My ParameterizedTest:
@ParameterizedTest(name = "{0}")
@MethodSource("getAllTestData")
void myParameterizedTestMethod(
String testCaseName, List<String> inputParams, List<String> expectedResults){
// Some Assertions here
Assertions.assertTrue(true);
}
//method source
public Stream<Arguments> getAllTestData() {
return aStreamOfParamsToBeUsedInTests;
}
I tried junit-platform-launcher as below:
LauncherDiscoveryRequest request =
LauncherDiscoveryRequestBuilder.request().selectors(selectClass(DummyTest.class)).build();
Launcher launcher = LauncherFactory.create();
launcher.execute(request);
This is successfully executing test methods annotated with @Test (DummyTest.class here) but not @ParameterizedTest
Also Tried junit-platform-testkit as below:
EngineTestKit.engine("junit-jupiter")
.selectors(selectClass(DummyTest.class))
.execute()
.testEvents()
.assertStatistics(o -> o.failed(0));
but with same result. Not sure if its something I am doing is incorrect or the way to call parameterized test is different.
Any help is appreciated. Thanks.
Edit:
I am not encountering any errors. Its just that any @ParameterizedTest does not get invoked. Only @Test methods are getting run.
Including more code if it helps:
A simple unit test:
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class DummyTest {
@Test
void dummyTest() {
System.out.println("Success1");
Assertions.assertTrue(true);
}
}
ParameterizedTest:
import com.fasterxml.jackson.core.JsonProcessingException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.stream.Stream;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class MyParameterizedTest{
@ParameterizedTest(name = "{0}")
@MethodSource("getAllTestData")
void testProductRequestValidator(
String testCaseName, String inputParams) {
Assertions.assertTrue(true);
System.out.println("<<<<<<>>>>>>>>>>Success");
Assertions.assertTrue(true);
}
public Stream<String> getAllTestData() {
return Stream.of("1","2","2");
}
}
Service Class Where I want to call the tests from:
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import org.junit.platform.launcher.Launcher;
import org.junit.platform.launcher.LauncherDiscoveryRequest;
import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
import org.junit.platform.launcher.core.LauncherFactory;
import org.junit.platform.launcher.listeners.SummaryGeneratingListener;
import org.junit.platform.testkit.engine.EngineTestKit;
import org.springframework.stereotype.Service;
@Service
public class MyTestService{ // TODO Rename
public void runTests() {
LauncherDiscoveryRequest request =
LauncherDiscoveryRequestBuilder.request().selectors(selectClass(DummyTest.class)).build();
Launcher launcher = LauncherFactory.create();
launcher.execute(request);
}
}
IMPORTANT: This works. The test gets executed.
BUT When I try to call tests within MyParameterizedTest class, it simply does not get recognized and there is no call.. No errors.
Same code as above just with class name changed:
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import org.junit.platform.launcher.Launcher;
import org.junit.platform.launcher.LauncherDiscoveryRequest;
import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
import org.junit.platform.launcher.core.LauncherFactory;
import org.junit.platform.launcher.listeners.SummaryGeneratingListener;
import org.junit.platform.testkit.engine.EngineTestKit;
import org.springframework.stereotype.Service;
@Service
public class MyTestService{ // TODO Rename
public void runTests() {
LauncherDiscoveryRequest request =
LauncherDiscoveryRequestBuilder.request().selectors(selectClass(MyParameterizedTest.class)).build();
Launcher launcher = LauncherFactory.create();
launcher.execute(request);
}
}
The above does not work. Test is not getting invoked.
Java: openjdk version "1.8.0_362" gradle: Gradle 8.5
The
ParameterizedTestyou provided is not a valid test, soLauncherwould silently fail to find it. You say that these tests passed in IDE, so maybe there was an error made in the process, but after fixing this test was recognized and finished successfully:All I changed was adding
staticto the source method and reducing test method params to a single string.