diff --git a/plugins/junit5_rt_tests/test/com/intellij/junit5/JUnit5IntegrationTest.java b/plugins/junit5_rt_tests/test/com/intellij/junit5/JUnit5IntegrationTest.java new file mode 100644 index 000000000000..198462f5b06a --- /dev/null +++ b/plugins/junit5_rt_tests/test/com/intellij/junit5/JUnit5IntegrationTest.java @@ -0,0 +1,328 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.junit5; + +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.java.execution.AbstractTestFrameworkCompilingIntegrationTest; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.roots.ModuleRootModificationUtil; +import com.intellij.openapi.vfs.VfsUtilCore; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.JavaPsiFacade; +import com.intellij.psi.PsiClass; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.testFramework.IdeaTestUtil; +import com.intellij.testFramework.PlatformTestUtil; +import jetbrains.buildServer.messages.serviceMessages.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.idea.maven.aether.ArtifactRepositoryManager; +import org.jetbrains.jps.model.library.JpsMavenRepositoryLibraryDescriptor; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +public class JUnit5IntegrationTest extends AbstractTestFrameworkCompilingIntegrationTest { + + @Override + protected String getTestContentRoot() { + return VfsUtilCore.pathToUrl(PlatformTestUtil.getCommunityPath() + "/plugins/junit5_rt_tests/testData/integration/junit5Project"); + } + + @Override + protected Sdk getTestProjectJdk() { + return IdeaTestUtil.getMockJdk21(); + } + + @Override + protected @NotNull LanguageLevel getProjectLanguageLevel() { + return LanguageLevel.JDK_21; + } + + @Override + protected void setupModule() throws Exception { + super.setupModule(); + ModuleRootModificationUtil.updateModel(myModule, model -> model.addContentEntry(getTestContentRoot()) + .addSourceFolder(getTestContentRoot() + "/test", true)); + final ArtifactRepositoryManager repoManager = getRepoManager(); + + addMavenLibs(myModule, new JpsMavenRepositoryLibraryDescriptor("org.junit.jupiter", "junit-jupiter-api", "5.13.0"), repoManager); + addMavenLibs(myModule, new JpsMavenRepositoryLibraryDescriptor("org.junit.jupiter", "junit-jupiter-params", "5.13.0"), repoManager); + addMavenLibs(myModule, new JpsMavenRepositoryLibraryDescriptor("org.junit.platform", "junit-platform-suite-api", "1.13.1"), + repoManager); + } + + public void testConditionalExecution() throws Exception { + PsiClass aClass = + JavaPsiFacade.getInstance(myProject).findClass("conditional.ConditionalTests", GlobalSearchScope.projectScope(myProject)); + assertNotNull(aClass); + RunConfiguration configuration = createConfiguration(aClass); + assertNotNull("Run configuration is null", configuration); + ProcessOutput output = doStartTestsProcess(configuration); + + assertEmpty(output.err); + assertTestsStarted(output, "enabled()", "disabled()"); + assertTestsFinished(output, "enabled()", "disabled()"); + assertTestsIgnored(output, "disabled()"); + } + + public void testInterfaceDynamicTestsDemo() throws Exception { + PsiClass testClass = JavaPsiFacade.getInstance(myProject).findClass("dynamicTests.A", GlobalSearchScope.projectScope(myProject)); + assertNotNull("Test class not found", testClass); + + RunConfiguration configuration = createConfiguration(testClass); + ProcessOutput output = doStartTestsProcess(configuration); + + assertEmpty(output.err); + assertTrue("Should use JUnit 5", output.sys.toString().contains("-junit5")); + + List messages = output.messages; + + var testNames = messages.stream().filter(TestStarted.class::isInstance).map(m -> m.getAttributes().get("name")).toList(); + + assertEquals(7, testNames.size()); + assertEquals(7, messages.stream().filter(TestFinished.class::isInstance).count()); + assertTestsFailed(output, "false", "false"); + assertEquals(4, testNames.stream().filter(name -> name.contains("true")).count()); + } + + public void testMetaAnnotationDiscoveryAndExecution() throws Exception { + PsiClass testClass = + JavaPsiFacade.getInstance(myProject).findClass("metaAnnotation.MetaAnnotationTest", GlobalSearchScope.projectScope(myProject)); + assertNotNull("Test class not found", testClass); + + RunConfiguration configuration = createConfiguration(testClass); + ProcessOutput output = doStartTestsProcess(configuration); + + assertEmpty(output.err); + assertTrue("Should use JUnit 5", output.sys.toString().contains("-junit5")); + + List messages = output.messages; + assertEquals(7, messages.stream().filter(TestFinished.class::isInstance).count()); + assertEquals(0, messages.stream().filter(TestFailed.class::isInstance).count()); + + assertTestsStarted(output, "integrationTest()", "Retry 1/3", "Retry 2/3", "Retry 3/3", "Retry 1/3", "Retry 2/3", "Retry 3/3"); + assertTestSuitesStarted(output, "retryTest()", "combinedTest()"); + } + + public void testMetaAnnotationSuiteDiscoveryAndExecution() throws Exception { + PsiClass testClass = + JavaPsiFacade.getInstance(myProject).findClass("metaAnnotation.IntegrationTestSuite", GlobalSearchScope.projectScope(myProject)); + assertNotNull("Test class not found", testClass); + + RunConfiguration configuration = createConfiguration(testClass); + ProcessOutput output = doStartTestsProcess(configuration); + + assertEmpty(output.err); + assertTrue("Should use JUnit 5", output.sys.toString().contains("-junit5")); + + List messages = output.messages; + assertEquals(7, messages.stream().filter(TestStarted.class::isInstance).count()); + assertEquals(7, messages.stream().filter(TestFinished.class::isInstance).count()); + assertEquals(0, messages.stream().filter(TestFailed.class::isInstance).count()); + + assertTestsStarted(output, "integrationTest()", "Retry 1/3", "Retry 2/3", "Retry 3/3", "integrationTest()", "nestedIntegrationTest()", + "testWithoutIntegrationTagTest()"); + assertTestSuitesStarted(output, "Meta-annotation demonstration", "NestedIntegrationTests", "combinedTest()"); + } + + public void testSuiteExecution() throws Exception { + PsiClass testClass = JavaPsiFacade.getInstance(myProject).findClass("testSuite.TestSuite", GlobalSearchScope.projectScope(myProject)); + assertNotNull("Test suite class not found", testClass); + + RunConfiguration configuration = createConfiguration(testClass); + ProcessOutput output = doStartTestsProcess(configuration); + + assertEmpty(output.err); + assertTrue("Should use JUnit 5", output.sys.toString().contains("-junit5")); + + assertTestsStarted(output, "executed()", "test1()", "test1()", "test2()"); + assertTestsFinished(output, "executed()", "test1()", "test1()", "test2()"); + assertTestsFailed(output, "test2()"); + + assertTestSuitesStarted(output, "RecordSuiteTest", "SecondSuiteTest", "SuiteTest"); + } + + public void testDisabledTests() throws Exception { + PsiClass aClass = JavaPsiFacade.getInstance(myProject).findClass("various.DisabledTests", GlobalSearchScope.projectScope(myProject)); + assertNotNull(aClass); + + RunConfiguration configuration = createConfiguration(aClass); + ProcessOutput output = doStartTestsProcess(configuration); + + assertEmpty(output.out); + assertEmpty(output.err); + List messages = output.messages; + + assertTestsStarted(output, "testWillBeExecuted()", "testWillBeSkipped()", "testInNestedClassWillBeSkipped()"); + assertTestsFinished(output, "testWillBeExecuted()", "testWillBeSkipped()", "testInNestedClassWillBeSkipped()"); + assertEquals(0, messages.stream().filter(TestFailed.class::isInstance).count()); + assertTestsIgnored(output, "testWillBeSkipped()", "testInNestedClassWillBeSkipped()"); + } + + public void testDisplayNames() throws Exception { + PsiClass fragmentClass = + JavaPsiFacade.getInstance(myProject).findClass("various.DisplayNameGenerators", GlobalSearchScope.projectScope(myProject)); + assertNotNull("Test class not found", fragmentClass); + + RunConfiguration fragmentConfig = createConfiguration(fragmentClass); + ProcessOutput fragmentOutput = doStartTestsProcess(fragmentConfig); + + assertEmpty(fragmentOutput.err); + assertTrue("Should use JUnit 5", fragmentOutput.sys.toString().contains("-junit5")); + + assertEquals(8, fragmentOutput.messages.stream().filter(TestStarted.class::isInstance).count()); + assertEquals(0, fragmentOutput.messages.stream().filter(TestFailed.class::isInstance).count()); + assertEquals(8, fragmentOutput.messages.stream().filter(TestFinished.class::isInstance).count()); + + assertTestSuitesStarted(fragmentOutput, "Fragment1", "Fragment1, fragment3", "Replace underscores in class", + "parameterized test (int)"); + assertTestsStarted(fragmentOutput, "1", "2", "3", "Fragment1, fragment2", "Display_name_with_underscores", + "replace underscores in method", "Parameterized test name works 1", "Parameterized test name works 2"); + } + + public void testOrderedNestedClassesExecution() throws Exception { + PsiClass testClass = + JavaPsiFacade.getInstance(myProject).findClass("various.OrderedNestedTestClassesDemo", GlobalSearchScope.projectScope(myProject)); + assertNotNull("Test class not found", testClass); + + RunConfiguration configuration = createConfiguration(testClass); + ProcessOutput output = doStartTestsProcess(configuration); + + assertEmpty(output.err); + assertTrue("Should use JUnit 5", output.sys.toString().contains("-junit5")); + + assertTestsOrder(output, "test0()", "test1()", "test2()"); + + assertEquals(0, output.messages.stream().filter(TestFailed.class::isInstance).count()); + assertEquals(3, output.messages.stream().filter(TestFinished.class::isInstance).count()); + } + + public void testMethodOrderExecution() throws Exception { + PsiClass testClass = + JavaPsiFacade.getInstance(myProject).findClass("various.OrderedTestsDemo", GlobalSearchScope.projectScope(myProject)); + assertNotNull("Test class not found", testClass); + + RunConfiguration configuration = createConfiguration(testClass); + ProcessOutput output = doStartTestsProcess(configuration); + + assertEmpty(output.err); + assertTrue("Should use JUnit 5", output.sys.toString().contains("-junit5")); + + assertTestsOrder(output, "test1()", "test2()", "test4()"); + + assertEquals(3, output.messages.stream().filter(TestFinished.class::isInstance).count()); + assertEquals(0, output.messages.stream().filter(TestFailed.class::isInstance).count()); + } + + public void testParameterizedMethod() throws Exception { + PsiClass aClass = + JavaPsiFacade.getInstance(myProject).findClass("various.ParameterizedTests", GlobalSearchScope.projectScope(myProject)); + assertNotNull(aClass); + RunConfiguration configuration = createConfiguration(aClass); + + ProcessOutput processOutput = doStartTestsProcess(configuration); + String systemOutput = processOutput.sys.toString(); //command line + + assertEmpty(processOutput.out); + assertEmpty(processOutput.err); + + assertEquals(4, processOutput.messages.stream().filter(TestStarted.class::isInstance).count()); + assertEquals(4, processOutput.messages.stream().filter(TestFinished.class::isInstance).count()); + assertTrue(systemOutput.contains("-junit5")); + + assertTestsFailed(processOutput, "49 + 51 = 101"); + } + + public void testRepeatedTests() throws Exception { + PsiClass aClass = JavaPsiFacade.getInstance(myProject).findClass("various.RepeatedTests", GlobalSearchScope.projectScope(myProject)); + assertNotNull(aClass); + + RunConfiguration configuration = createConfiguration(aClass); + ProcessOutput output = doStartTestsProcess(configuration); + + assertEmpty(output.err); + assertTestsStarted(output, "repetition 1 of 3", "repetition 2 of 3", "repetition 3 of 3"); + } + + public void testFactoryTests() throws Exception { + PsiClass testClass = + JavaPsiFacade.getInstance(myProject).findClass("various.TestFactoryTests", GlobalSearchScope.projectScope(myProject)); + assertNotNull("Test class not found", testClass); + + RunConfiguration configuration = createConfiguration(testClass); + ProcessOutput output = doStartTestsProcess(configuration); + + assertEmpty(output.err); + assertTrue("Should use JUnit 5", output.sys.toString().contains("-junit5")); + + List messages = output.messages; + + assertEquals(8, messages.stream().filter(TestStarted.class::isInstance).count()); + + assertTestsStarted(output, "test 1", "test 1", "test 2", "test 2", "test 3", "test 3", "1st dynamic test", "2nd dynamic test"); + assertTestSuitesStarted(output, "Container A", "Container B", "container level 2", "container level 2", "dynamicTestsWithContainers()", + "testsFromCollection()"); + } + + public void testTemplateTests() throws Exception { + PsiClass aClass = JavaPsiFacade.getInstance(myProject).findClass("various.TestTemplateDemo", GlobalSearchScope.projectScope(myProject)); + assertNotNull(aClass); + + RunConfiguration configuration = createConfiguration(aClass); + ProcessOutput output = doStartTestsProcess(configuration); + + assertEmpty(output.err); + List messages = output.messages; + assertEquals(0, messages.stream().filter(TestFailed.class::isInstance).count()); + assertTestsStarted(output, "first test 1", "second test 2"); + assertTestsFinished(output, "first test 1", "second test 2"); + } + + public void testUnhandledException() throws Exception { + PsiClass aClass = + JavaPsiFacade.getInstance(myProject).findClass("various.UncaughtExceptionHandlingDemo", GlobalSearchScope.projectScope(myProject)); + assertNotNull(aClass); + + RunConfiguration configuration = createConfiguration(aClass); + ProcessOutput output = doStartTestsProcess(configuration); + + assertTestsStarted(output, "passes()", "failsDueToUncaughtException()"); + assertTestsFinished(output, "passes()", "failsDueToUncaughtException()"); + assertTestsFailed(output, "failsDueToUncaughtException()"); + assertEmpty(output.err); + } + + private static void assertTestsStatus(ProcessOutput output, Predicate predicate, String... testNames) { + var actualNames = + output.messages.stream().filter(predicate).map(m -> m.getAttributes().get("name")).sorted().collect(Collectors.toList()); + assertEquals(Arrays.stream(testNames).sorted().toList(), actualNames); + } + + private static void assertTestsStarted(ProcessOutput output, String... testNames) { + assertTestsStatus(output, TestStarted.class::isInstance, testNames); + } + + private static void assertTestsFinished(ProcessOutput output, String... testNames) { + assertTestsStatus(output, TestFinished.class::isInstance, testNames); + } + + private static void assertTestsFailed(ProcessOutput output, String... testNames) { + assertTestsStatus(output, TestFailed.class::isInstance, testNames); + } + + private static void assertTestsIgnored(ProcessOutput output, String... testNames) { + assertTestsStatus(output, TestIgnored.class::isInstance, testNames); + } + + private static void assertTestSuitesStarted(ProcessOutput output, String... suiteNames) { + assertTestsStatus(output, TestSuiteStarted.class::isInstance, suiteNames); + } + + private static void assertTestsOrder(ProcessOutput output, String... expectedOrder) { + List executionOrder = + output.messages.stream().filter(TestStarted.class::isInstance).map(m -> m.getAttributes().get("name")).toList(); + + assertEquals("execution order is wrong", List.of(expectedOrder), executionOrder); + } +} \ No newline at end of file diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/conditional/ConditionalTests.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/conditional/ConditionalTests.java new file mode 100644 index 000000000000..eec2f6268f29 --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/conditional/ConditionalTests.java @@ -0,0 +1,17 @@ +package conditional; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledIf; + +class ConditionalTests { + + @Test + @EnabledIf("conditional.ExternalCondition#customConditionTrue") + void enabled() {} + + @Test + @EnabledIf("conditional.ExternalCondition#customConditionFalse") + void disabled() {} +} + + diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/conditional/ExternalCondition.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/conditional/ExternalCondition.java new file mode 100644 index 000000000000..dcd57049e29e --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/conditional/ExternalCondition.java @@ -0,0 +1,10 @@ +package conditional; + +class ExternalCondition { + static boolean customConditionTrue() { + return true; + } + static boolean customConditionFalse() { + return false; + } +} \ No newline at end of file diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/dynamicTests/A.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/dynamicTests/A.java new file mode 100644 index 000000000000..92184736d419 --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/dynamicTests/A.java @@ -0,0 +1,23 @@ +package dynamicTests; + +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestFactory; + +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.DynamicTest.dynamicTest; + +class A implements InterfaceDynamicTestTests { + @Override + @Test + public void testMethod() {} + + @TestFactory + @Override + public Stream classTestFactoryMethod() { + return Stream.of(true, false, true) + .map(value -> dynamicTest(value.toString(), () -> assertTrue(value))); + } +} \ No newline at end of file diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/dynamicTests/InterfaceDynamicTestTests.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/dynamicTests/InterfaceDynamicTestTests.java new file mode 100644 index 000000000000..312fb7f995e4 --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/dynamicTests/InterfaceDynamicTestTests.java @@ -0,0 +1,26 @@ +package dynamicTests; + +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestFactory; + +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.DynamicTest.dynamicTest; + +interface InterfaceDynamicTestTests { + + @TestFactory + default Stream defaultTestFactoryMethod() { + return Stream.of(true, false, true) + .map(value -> dynamicTest(value.toString(), () -> assertTrue(value))); + } + + @Test + void testMethod(); + + @TestFactory + Stream classTestFactoryMethod(); +} + diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/metaAnnotation/IntegrationSuite.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/metaAnnotation/IntegrationSuite.java new file mode 100644 index 000000000000..fa2f64c29c0b --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/metaAnnotation/IntegrationSuite.java @@ -0,0 +1,20 @@ +package metaAnnotation; + +import org.junit.jupiter.api.*; +import org.junit.platform.suite.api.*; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ ElementType.TYPE, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@SuiteDisplayName("Metaannotated Test Suite") +@SelectPackages("metaAnnotation") +@IncludeClassNamePatterns(".*Test") +@IncludeTags("integration") +@Suite +@interface IntegrationSuite { +} + diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/metaAnnotation/IntegrationTest.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/metaAnnotation/IntegrationTest.java new file mode 100644 index 000000000000..38e9bb14a9b0 --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/metaAnnotation/IntegrationTest.java @@ -0,0 +1,15 @@ +package metaAnnotation; + +import org.junit.jupiter.api.*; +import org.junit.platform.suite.api.*; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ ElementType.TYPE, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@Tag("integration") +@Test +@interface IntegrationTest { } diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/metaAnnotation/IntegrationTestSuite.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/metaAnnotation/IntegrationTestSuite.java new file mode 100644 index 000000000000..99ae7606556f --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/metaAnnotation/IntegrationTestSuite.java @@ -0,0 +1,27 @@ +package metaAnnotation; + +import org.junit.jupiter.api.*; +import org.junit.platform.suite.api.*; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@IntegrationSuite +@DisplayName("Integration Test Suite") +class IntegrationTestSuite { + + @Test void testWithoutIntegrationTagTest() {} + + @Nested + class NestedIntegrationTests { + @IntegrationTest + void nestedIntegrationTest() {} + } + + @IntegrationTest + void integrationTest() {} +} + + diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/metaAnnotation/MetaAnnotationTest.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/metaAnnotation/MetaAnnotationTest.java new file mode 100644 index 000000000000..200af6740236 --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/metaAnnotation/MetaAnnotationTest.java @@ -0,0 +1,23 @@ +package metaAnnotation; + +import org.junit.jupiter.api.*; +import org.junit.platform.suite.api.*; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@DisplayName("Meta-annotation demonstration") +public class MetaAnnotationTest { + @IntegrationTest void integrationTest() {} + + @Retry void retryTest() {} + + @Retry + @Tag("integration") + void combinedTest() {} +} + + + diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/metaAnnotation/Retry.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/metaAnnotation/Retry.java new file mode 100644 index 000000000000..d2e71712dee2 --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/metaAnnotation/Retry.java @@ -0,0 +1,15 @@ +package metaAnnotation; + +import org.junit.jupiter.api.*; +import org.junit.platform.suite.api.*; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@RepeatedTest(value = 3, name = "Retry {currentRepetition}/{totalRepetitions}") +@interface Retry { +} \ No newline at end of file diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/testSuite/InterfaceSuiteTest.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/testSuite/InterfaceSuiteTest.java new file mode 100644 index 000000000000..743911b3aab5 --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/testSuite/InterfaceSuiteTest.java @@ -0,0 +1,17 @@ +package testSuite; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.platform.suite.api.*; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +@Tag("important") +interface InterfaceSuiteTest { + @Test + @Tag("skip") + default void excluded() {} + + @Test + default void interfaceMethod() {} +} diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/testSuite/NotATestClass.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/testSuite/NotATestClass.java new file mode 100644 index 000000000000..afddaf2de3d1 --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/testSuite/NotATestClass.java @@ -0,0 +1,12 @@ +package testSuite; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.platform.suite.api.*; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +class NotATestClass { + @Test + void helperMethod() {} +} \ No newline at end of file diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/testSuite/RecordSuiteTest.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/testSuite/RecordSuiteTest.java new file mode 100644 index 000000000000..8e1b3449f742 --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/testSuite/RecordSuiteTest.java @@ -0,0 +1,17 @@ +package testSuite; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.platform.suite.api.*; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +@Tag("important") +record RecordSuiteTest() { + @Test + void executed() {} + + @Test + @Tag("skip") + void excluded() {} +} diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/testSuite/SecondSuiteTest.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/testSuite/SecondSuiteTest.java new file mode 100644 index 000000000000..6e03a6b51a65 --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/testSuite/SecondSuiteTest.java @@ -0,0 +1,13 @@ +package testSuite; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.platform.suite.api.*; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +class SecondSuiteTest { + @Test + @Tag("important") + void test1() {} +} diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/testSuite/SkippedSuiteTest.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/testSuite/SkippedSuiteTest.java new file mode 100644 index 000000000000..84e37fc98ca9 --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/testSuite/SkippedSuiteTest.java @@ -0,0 +1,15 @@ +package testSuite; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.platform.suite.api.*; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +@Tag("important") +@Tag("skip") +class SkippedSuiteTest { + @Test + void excludedTest() {} +} + diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/testSuite/SuiteTest.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/testSuite/SuiteTest.java new file mode 100644 index 000000000000..7f58474b4ca9 --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/testSuite/SuiteTest.java @@ -0,0 +1,22 @@ +package testSuite; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.platform.suite.api.*; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +@Tag("important") +class SuiteTest { + @Test + void test1() {} + + @Test + void test2() { + assertTrue(false); + } + + @Test + @Tag("skip") + void skippedTest() {} +} diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/testSuite/TestSuite.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/testSuite/TestSuite.java new file mode 100644 index 000000000000..2b2e97ba7a5d --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/testSuite/TestSuite.java @@ -0,0 +1,15 @@ +package testSuite; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.platform.suite.api.*; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +@Suite +@SuiteDisplayName("Example Test Suite") +@SelectPackages("testSuite") +@IncludeClassNamePatterns(".*SuiteTest") +@IncludeTags("important") +@ExcludeTags("skip") +public class TestSuite { } \ No newline at end of file diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/DisabledTests.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/DisabledTests.java new file mode 100644 index 000000000000..8a7706cf0d6b --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/DisabledTests.java @@ -0,0 +1,25 @@ +package various; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +class DisabledTests { + + @Disabled("Disabled until bug #42 has been resolved") + @Test + void testWillBeSkipped() { + } + + @Test + void testWillBeExecuted() { + } + + @Nested + @Disabled("Disabled nested class") + class NestedDisabled { + @Test + void testInNestedClassWillBeSkipped() { + } + } +} diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/DisplayNameGenerators.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/DisplayNameGenerators.java new file mode 100644 index 000000000000..bf733699dd96 --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/DisplayNameGenerators.java @@ -0,0 +1,42 @@ +package various; + +import org.junit.jupiter.api.*; +import org.junit.jupiter.api.DisplayNameGenerator.IndicativeSentences.SentenceFragment; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class DisplayNameGenerators { + + @Nested + @DisplayNameGeneration(ReplaceUnderscores.class) + class Replace_underscores_in_class { + + @Test + void replace_underscores_in_method() {} + + @Test + @DisplayName("Display_name_with_underscores") + void test_with_display_name() {} + + @ParameterizedTest(name = "Parameterized test name works {0}") + @ValueSource(ints = {1, 2}) + void parameterized_test(int val) { + } + } + + @Nested + @SentenceFragment("Fragment1") + @IndicativeSentencesGeneration + class SentenceFragmentTests { + + @SentenceFragment("fragment2") + @Test + void fragmentTest() {} + + @SentenceFragment("fragment3") + @ParameterizedTest(name = "{0}") + @ValueSource(ints = {1, 2, 3}) + void parameterizedFragmentTest(int year) {} + } +} diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/OrderedNestedTestClassesDemo.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/OrderedNestedTestClassesDemo.java new file mode 100644 index 000000000000..5d32464d65ac --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/OrderedNestedTestClassesDemo.java @@ -0,0 +1,25 @@ +package various; + +import org.junit.jupiter.api.*; + +@TestClassOrder(ClassOrderer.OrderAnnotation.class) +class OrderedNestedTestClassesDemo { + @Nested + @DisplayName("Named nested class (SecondClass)") + @Order(2) + class SecondTests { + @Test + void test2() {} + } + + @Nested + @Order(1) + class FirstTests { + @Test + void test1() {} + } + + @Test + void test0() {} +} + diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/OrderedTestsDemo.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/OrderedTestsDemo.java new file mode 100644 index 000000000000..756020dbc8a5 --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/OrderedTestsDemo.java @@ -0,0 +1,22 @@ +package various; + +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; + +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +class OrderedTestsDemo { + @Test + @Order(2) + void test2() {} + + @Test + @Order(1) + void test1() {} + + @Test + @Order(4) + void test4() {} +} + diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/ParameterizedTests.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/ParameterizedTests.java new file mode 100644 index 000000000000..838278b438e9 --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/ParameterizedTests.java @@ -0,0 +1,19 @@ +package various; + +import org.junit.jupiter.params.provider.CsvSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ParameterizedTests { + @org.junit.jupiter.params.ParameterizedTest(name = "{0} + {1} = {2}") + @CsvSource({ + "0, 1, 1", + "1, 2, 3", + "49, 51, 101", + "1, 100, 101" + }) + void add(int first, int second, int expectedResult) { + assertEquals(expectedResult, first + second, + () -> first + " + " + second + " should equal " + expectedResult); + } +} diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/RepeatedTests.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/RepeatedTests.java new file mode 100644 index 000000000000..5513c7e9e39d --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/RepeatedTests.java @@ -0,0 +1,6 @@ +package various; + +public class RepeatedTests { + @org.junit.jupiter.api.RepeatedTest(3) + void repeatedTest() { } +} \ No newline at end of file diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/TestFactoryTests.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/TestFactoryTests.java new file mode 100644 index 000000000000..7ed3d2c1476d --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/TestFactoryTests.java @@ -0,0 +1,30 @@ +package various; + +import org.junit.jupiter.api.DynamicNode; +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.TestFactory; + +import java.util.Arrays; +import java.util.Collection; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.DynamicContainer.dynamicContainer; +import static org.junit.jupiter.api.DynamicTest.dynamicTest; + +class TestFactoryTests { + + @TestFactory + Collection testsFromCollection() { + return Arrays.asList(dynamicTest("1st dynamic test", () -> assertTrue(true)), + dynamicTest("2nd dynamic test", () -> fail())); + } + + @TestFactory + Stream dynamicTestsWithContainers() { + return Stream.of("A", "B").map(input -> dynamicContainer("Container " + input, + Stream.of(dynamicTest("test 1", () -> assertNotNull(input)), dynamicContainer("container level 2", + Stream.of(dynamicTest("test 2", () -> {}), + dynamicTest("test 3", () -> {})))))); + } +} diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/TestTemplateDemo.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/TestTemplateDemo.java new file mode 100644 index 000000000000..23299982187a --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/TestTemplateDemo.java @@ -0,0 +1,45 @@ +package various; + +import org.junit.jupiter.api.TestTemplate; +import org.junit.jupiter.api.extension.*; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Stream; + +class TestTemplateDemo { + + @TestTemplate + @ExtendWith(ContextProvider.class) + void testTemplateMethod(String text) {} + + static public class ContextProvider implements TestTemplateInvocationContextProvider { + + @Override + public boolean supportsTestTemplate(ExtensionContext context) { return true; } + + @Override + public Stream provideTestTemplateInvocationContexts(ExtensionContext context) { + return Stream.of(invocationContext("first test "), invocationContext("second test ")); + } + + private TestTemplateInvocationContext invocationContext(String parameter) { + return new TestTemplateInvocationContext() { + @Override + public String getDisplayName(int i) {return parameter + i;} + + @Override + public List getAdditionalExtensions() { + return Collections.singletonList(new ParameterResolver() { + @Override + public boolean supportsParameter(ParameterContext p, ExtensionContext e) { return true; } + + @Override + public Object resolveParameter(ParameterContext p, ExtensionContext e) { return parameter;} + }); + } + }; + } + } + +} diff --git a/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/UncaughtExceptionHandlingDemo.java b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/UncaughtExceptionHandlingDemo.java new file mode 100644 index 000000000000..057d47a6af82 --- /dev/null +++ b/plugins/junit5_rt_tests/testData/integration/junit5Project/test/various/UncaughtExceptionHandlingDemo.java @@ -0,0 +1,13 @@ +package various; + +import org.junit.jupiter.api.Test; + +class UncaughtExceptionHandlingDemo { + @Test + void failsDueToUncaughtException() { + throw new RuntimeException("Boom!"); + } + + @Test + void passes() {} +}