diff --git a/plugins/testng/src/com/theoryinpractice/testng/model/TestNGTestObject.java b/plugins/testng/src/com/theoryinpractice/testng/model/TestNGTestObject.java index e645c7eb1b68..21eef64eca03 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/model/TestNGTestObject.java +++ b/plugins/testng/src/com/theoryinpractice/testng/model/TestNGTestObject.java @@ -33,10 +33,15 @@ import com.theoryinpractice.testng.configuration.TestNGConfiguration; import com.theoryinpractice.testng.util.TestNGUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.testng.annotations.AfterGroups; +import org.testng.annotations.BeforeGroups; import java.util.*; public abstract class TestNGTestObject { + + public static final String[] GROUPS_CONFIGURATION = {BeforeGroups.class.getName(), AfterGroups.class.getName()}; + private static final Logger LOG = Logger.getInstance("#" + TestNGTestObject.class.getName()); protected final TestNGConfiguration myConfig; @@ -93,29 +98,23 @@ public abstract class TestNGTestObject { final GlobalSearchScope searchScope, @Nullable final PsiClass... classes) { if (classes != null && classes.length > 0) { - final Set groupDependencies = new LinkedHashSet(); - TestNGUtil.collectAnnotationValues(groupDependencies, "dependsOnGroups", methods, classes); final Set membersToCheckNow = new LinkedHashSet(); + + final Set groupDependencies = new LinkedHashSet<>(), declaredGroups = new LinkedHashSet<>(); + final HashMap> valuesMap = new HashMap<>(); + valuesMap.put("dependsOnGroups", groupDependencies); + valuesMap.put("groups", declaredGroups); + //find all mentioned groups and dependsOnGroup values + TestNGUtil.collectAnnotationValues(valuesMap, methods, classes); + if (!groupDependencies.isEmpty()) { - ApplicationManager.getApplication().runReadAction(new Runnable() { - public void run() { - final Project project = classes[0].getProject(); - final PsiClass testAnnotation = - JavaPsiFacade.getInstance(project).findClass(TestNGUtil.TEST_ANNOTATION_FQN, GlobalSearchScope.allScope(project)); - LOG.assertTrue(testAnnotation != null); - for (PsiMember psiMember : AnnotatedMembersSearch.search(testAnnotation, searchScope)) { - final PsiClass containingClass = psiMember.getContainingClass(); - if (containingClass == null) continue; - if (ArrayUtil.find(classes, containingClass) < 0) continue; - final PsiAnnotation annotation = AnnotationUtil.findAnnotation(psiMember, TestNGUtil.TEST_ANNOTATION_FQN); - if (TestNGUtil.isAnnotatedWithParameter(annotation, "groups", groupDependencies)) { - if (appendMember(psiMember, alreadyMarkedToBeChecked, results)) { - membersToCheckNow.add(psiMember); - } - } - } - } - }); + collectGroupsMembers(TestNGUtil.TEST_ANNOTATION_FQN, groupDependencies, true, results, alreadyMarkedToBeChecked, searchScope, membersToCheckNow, classes); + } + + if (!declaredGroups.isEmpty()) { + for (String annotationFqn : GROUPS_CONFIGURATION) { + collectGroupsMembers(annotationFqn, declaredGroups, false, results, alreadyMarkedToBeChecked, searchScope, membersToCheckNow, classes); + } } collectDependsOnMethods(results, alreadyMarkedToBeChecked, membersToCheckNow, methods, classes); @@ -140,6 +139,36 @@ public abstract class TestNGTestObject { } } + private static void collectGroupsMembers(final String annotationFqn, + final Set groups, + final boolean skipUnrelated, + final Map>> results, + final Set alreadyMarkedToBeChecked, + final GlobalSearchScope searchScope, + final Set membersToCheckNow, + final PsiClass... classes) { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + final Project project = classes[0].getProject(); + final PsiClass testAnnotation = JavaPsiFacade.getInstance(project).findClass(annotationFqn, GlobalSearchScope.allScope(project)); + if (testAnnotation == null) { + return; + } + for (PsiMember psiMember : AnnotatedMembersSearch.search(testAnnotation, searchScope)) { + final PsiClass containingClass = psiMember.getContainingClass(); + if (containingClass == null) continue; + if (skipUnrelated && ArrayUtil.find(classes, containingClass) < 0) continue; + final PsiAnnotation annotation = AnnotationUtil.findAnnotation(psiMember, annotationFqn); + if (TestNGUtil.isAnnotatedWithParameter(annotation, "groups", groups)) { + if (appendMember(psiMember, alreadyMarkedToBeChecked, results)) { + membersToCheckNow.add(psiMember); + } + } + } + } + }); + } + private static void collectDependsOnMethods(final Map>> results, final Set alreadyMarkedToBeChecked, final Set membersToCheckNow, @@ -162,7 +191,9 @@ public abstract class TestNGTestObject { } for (final PsiClass containingClass : psiClasses) { final Set testMethodDependencies = new LinkedHashSet(); - TestNGUtil.collectAnnotationValues(testMethodDependencies, "dependsOnMethods", methods, containingClass); + final HashMap> valuesMap = new HashMap<>(); + valuesMap.put("dependsOnMethods", testMethodDependencies); + TestNGUtil.collectAnnotationValues(valuesMap, methods, containingClass); if (!testMethodDependencies.isEmpty()) { ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { diff --git a/plugins/testng/src/com/theoryinpractice/testng/util/TestNGUtil.java b/plugins/testng/src/com/theoryinpractice/testng/util/TestNGUtil.java index 1540698cbc29..d36c4c049ef0 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/util/TestNGUtil.java +++ b/plugins/testng/src/com/theoryinpractice/testng/util/TestNGUtil.java @@ -341,15 +341,17 @@ public class TestNGUtil { } public static Set getAnnotationValues(String parameter, PsiClass... classes) { - Set results = new HashSet(); - collectAnnotationValues(results, parameter, null, classes); - return results; + Map> results = new HashMap<>(); + final HashSet set = new HashSet<>(); + results.put(parameter, set); + collectAnnotationValues(results, null, classes); + return set; } /** * @return were javadoc params used */ - public static void collectAnnotationValues(final Set results, final String parameter, PsiMethod[] psiMethods, PsiClass... classes) { + public static void collectAnnotationValues(final Map> results, PsiMethod[] psiMethods, PsiClass... classes) { final Set test = new HashSet(1); test.add(TEST_ANNOTATION_FQN); ContainerUtil.addAll(test, CONFIG_ANNOTATIONS_FQN); @@ -358,7 +360,7 @@ public class TestNGUtil { ApplicationManager.getApplication().runReadAction( new Runnable() { public void run() { - appendAnnotationAttributeValues(parameter, results, AnnotationUtil.findAnnotation(psiMethod, test), psiMethod); + appendAnnotationAttributeValues(results, AnnotationUtil.findAnnotation(psiMethod, test), psiMethod); } } ); @@ -369,11 +371,11 @@ public class TestNGUtil { ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { if (psiClass != null && hasTest(psiClass)) { - appendAnnotationAttributeValues(parameter, results, AnnotationUtil.findAnnotation(psiClass, test), psiClass); + appendAnnotationAttributeValues(results, AnnotationUtil.findAnnotation(psiClass, test), psiClass); PsiMethod[] methods = psiClass.getMethods(); for (PsiMethod method : methods) { if (method != null) { - appendAnnotationAttributeValues(parameter, results, AnnotationUtil.findAnnotation(method, test), method); + appendAnnotationAttributeValues(results, AnnotationUtil.findAnnotation(method, test), method); } } } @@ -383,17 +385,19 @@ public class TestNGUtil { } } - private static void appendAnnotationAttributeValues(final String parameter, - final Collection results, + private static void appendAnnotationAttributeValues(final Map> results, final PsiAnnotation annotation, final PsiDocCommentOwner commentOwner) { - if (annotation != null) { - final PsiAnnotationMemberValue value = annotation.findDeclaredAttributeValue(parameter); - if (value != null) { - results.addAll(extractValuesFromParameter(value)); + for (String parameter : results.keySet()) { + final Collection values = results.get(parameter); + if (annotation != null) { + final PsiAnnotationMemberValue value = annotation.findDeclaredAttributeValue(parameter); + if (value != null) { + values.addAll(extractValuesFromParameter(value)); + } + } else { + values.addAll(extractAnnotationValuesFromJavaDoc(getTextJavaDoc(commentOwner), parameter)); } - } else { - results.addAll(extractAnnotationValuesFromJavaDoc(getTextJavaDoc(commentOwner), parameter)); } } diff --git a/plugins/testng/testSources/com/theoryinpractice/testng/configuration/DetectClassesToRunTest.java b/plugins/testng/testSources/com/theoryinpractice/testng/configuration/DetectClassesToRunTest.java index aee1063b42c7..e8b633386e14 100644 --- a/plugins/testng/testSources/com/theoryinpractice/testng/configuration/DetectClassesToRunTest.java +++ b/plugins/testng/testSources/com/theoryinpractice/testng/configuration/DetectClassesToRunTest.java @@ -43,6 +43,7 @@ public class DetectClassesToRunTest extends LightCodeInsightFixtureTestCase { super.setUp(); myFixture.addClass("package org.testng.annotations; @interface Test {public String[] dependsOnMethods() default {};}"); myFixture.addClass("package org.testng.annotations; @interface BeforeClass {}"); + myFixture.addClass("package org.testng.annotations; @interface BeforeGroups {public String[] value() default {};}"); } @AfterMethod @@ -117,6 +118,20 @@ public class DetectClassesToRunTest extends LightCodeInsightFixtureTestCase { doTestClassConfiguration(aClass); } + @Test + public void testBeforeGroups() throws Exception { + final PsiClass aClass = + myFixture.addClass("package a; public class ATest {" + + " @org.testng.annotations.Test(groups = { \"g1\" })\n" + + " public void testOne(){}\n" + + "}"); + final PsiClass configClass = myFixture.addClass("package a; public class ConfigTest {" + + " @org.testng.annotations.BeforeGroups(groups = { \"g1\" })\n" + + " public void testTwo(){}\n " + + "}"); + doTestMethodConfiguration(aClass, configClass, configClass.getMethods()[0], aClass.getMethods()); + } + public void testRerunFailedTestWithDependency() throws Exception { final PsiClass aClass = myFixture.addClass("package a; public class ATest {" + @@ -186,6 +201,10 @@ public class DetectClassesToRunTest extends LightCodeInsightFixtureTestCase { } private void doTestMethodConfiguration(PsiClass aClass, PsiMethod... expectedMethods) throws CantRunException { + doTestMethodConfiguration(aClass, null, null, expectedMethods); + } + + private void doTestMethodConfiguration(PsiClass aClass, PsiClass secondaryClass, PsiMethod configMethod, PsiMethod... expectedMethods) throws CantRunException { final TestNGConfiguration configuration = new TestNGConfiguration("testOne", getProject(), TestNGConfigurationType.getInstance().getConfigurationFactories()[0]); final TestData data = configuration.getPersistantData(); @@ -201,6 +220,11 @@ public class DetectClassesToRunTest extends LightCodeInsightFixtureTestCase { assertContainsElements(classes.keySet(), aClass); final Map> methods = classes.get(aClass); assertContainsElements(methods.keySet(), expectedMethods); + if (secondaryClass != null) { + final Map> configMethods = classes.get(secondaryClass); + assertTrue(configMethods != null); + assertTrue(configMethods.containsKey(configMethod)); + } } private void doTestClassConfiguration(PsiClass aClass) throws CantRunException {