diff --git a/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java b/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java index bbf5f37fc6eb..77878a2fae70 100644 --- a/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java +++ b/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java @@ -98,6 +98,7 @@ public class JUnitUtil { @NonNls public static final String PARAMETERIZED_CLASS_NAME = "org.junit.runners.Parameterized"; @NonNls public static final String SUITE_CLASS_NAME = "org.junit.runners.Suite"; public static final String JUNIT5_NESTED = "org.junit.jupiter.api.Nested"; + private static final String[] KNOWN_RUNNERS = {"org.junit.runners.Parameterized", "org.junit.runners.BlockJUnit4ClassRunner", "org.junit.runners.JUnit4"}; public static boolean isSuiteMethod(@NotNull PsiMethod psiMethod) { if (!psiMethod.hasModifierProperty(PsiModifier.PUBLIC)) return false; @@ -135,7 +136,7 @@ public class JUnitUtil { if (checkClass && checkRunWith) { PsiAnnotation annotation = getRunWithAnnotation(aClass); if (annotation != null) { - return !isRunnerWithRequiredAnnotationOnTestMethod(annotation, "org.junit.runners.Parameterized", "org.junit.runners.BlockJUnit4ClassRunner"); + return !isRunnerWithRequiredAnnotationOnTestMethod(annotation, KNOWN_RUNNERS); } } if (psiMethod.getParameterList().getParametersCount() > 0) return false; @@ -216,7 +217,19 @@ public class JUnitUtil { final PsiModifierList modifierList = psiClass.getModifierList(); if (modifierList == null) return false; final PsiClass topLevelClass = PsiTreeUtil.getTopmostParentOfType(modifierList, PsiClass.class); - if (topLevelClass != null && AnnotationUtil.isAnnotated(topLevelClass, RUN_WITH, true)) return true; + if (topLevelClass != null) { + if (AnnotationUtil.isAnnotated(topLevelClass, RUN_WITH, true)) { + PsiAnnotation annotation = getRunWithAnnotation(topLevelClass); + if (topLevelClass == psiClass) { + return true; + } + + //default runners do not implicitly run inner classes + if (!isRunnerWithRequiredAnnotationOnTestMethod(annotation, KNOWN_RUNNERS)) { + return true; + } + } + } if (!PsiClassUtil.isRunnableClass(psiClass, true, checkAbstract)) return false; diff --git a/plugins/junit/test/com/intellij/execution/junit/JUnitDetectionTest.java b/plugins/junit/test/com/intellij/execution/junit/JUnitDetectionTest.java new file mode 100644 index 000000000000..46b417b19fbe --- /dev/null +++ b/plugins/junit/test/com/intellij/execution/junit/JUnitDetectionTest.java @@ -0,0 +1,50 @@ +// Copyright 2000-2017 JetBrains s.r.o. +// Use of this source code is governed by the Apache 2.0 license that can be +// found in the LICENSE file. +package com.intellij.execution.junit; + +import com.intellij.codeInsight.TestFrameworks; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiClassOwner; +import com.intellij.psi.PsiFile; +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; +import com.intellij.testIntegration.TestFramework; + +public class JUnitDetectionTest extends LightCodeInsightFixtureTestCase { + + @Override + protected void setUp() throws Exception { + super.setUp(); + myFixture.addClass("package org.junit; public @interface Test {}"); + myFixture.addClass("package org.junit.runners; public class Parameterized { public @interface Parameters {} public @interface Parameter {}}"); + myFixture.addClass("package org.junit.runner; public @interface RunWith {Class value();}"); + } + + public void testInnerClassesForKnownRunners() { + PsiFile file = myFixture.configureByText("A.java", "import org.junit.Test;\n" + + "import org.junit.runner.RunWith;\n" + + "import org.junit.runners.Parameterized;\n" + + "import java.util.*;\n" + + "@RunWith(Parameterized.class)\n" + + "public class A {\n" + + " @Parameterized.Parameters\n" + + " public static Collection data() {\n" + + " return Arrays.asList(new Object[] {\"11\"}, new Object[] {\"12\"});\n" + + " }\n" + + " @Parameterized.Parameter\n" + + " public String myJUnitVersion;\n" + + " @Test\n" + + " public void ignoredTestMethod() throws Exception {}\n" + + " public class Foo {\n" + + " public void testMe() {}\n " + + " }\n" + + "}\n"); + PsiClass aClass = ((PsiClassOwner)file).getClasses()[0]; + TestFramework framework = TestFrameworks.detectFramework(aClass); + assertTrue(framework != null); + assertTrue(framework.isTestClass(aClass)); + PsiClass innerClass = aClass.getInnerClasses()[0]; + assertFalse(framework.isTestClass(innerClass)); + assertFalse(framework.isTestMethod(innerClass.getMethods()[0])); + } +}