testng: include @Before/AfterGroups when needed (IDEA-152857)

This commit is contained in:
Anna Kozlova
2016-03-11 17:08:17 +01:00
parent 696663a690
commit a8c9597779
3 changed files with 96 additions and 37 deletions
@@ -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<String> groupDependencies = new LinkedHashSet<String>();
TestNGUtil.collectAnnotationValues(groupDependencies, "dependsOnGroups", methods, classes);
final Set<PsiMember> membersToCheckNow = new LinkedHashSet<PsiMember>();
final Set<String> groupDependencies = new LinkedHashSet<>(), declaredGroups = new LinkedHashSet<>();
final HashMap<String, Collection<String>> 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<String> groups,
final boolean skipUnrelated,
final Map<PsiClass, Map<PsiMethod, List<String>>> results,
final Set<PsiMember> alreadyMarkedToBeChecked,
final GlobalSearchScope searchScope,
final Set<PsiMember> 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<PsiClass, Map<PsiMethod, List<String>>> results,
final Set<PsiMember> alreadyMarkedToBeChecked,
final Set<PsiMember> membersToCheckNow,
@@ -162,7 +191,9 @@ public abstract class TestNGTestObject {
}
for (final PsiClass containingClass : psiClasses) {
final Set<String> testMethodDependencies = new LinkedHashSet<String>();
TestNGUtil.collectAnnotationValues(testMethodDependencies, "dependsOnMethods", methods, containingClass);
final HashMap<String, Collection<String>> valuesMap = new HashMap<>();
valuesMap.put("dependsOnMethods", testMethodDependencies);
TestNGUtil.collectAnnotationValues(valuesMap, methods, containingClass);
if (!testMethodDependencies.isEmpty()) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
@@ -341,15 +341,17 @@ public class TestNGUtil {
}
public static Set<String> getAnnotationValues(String parameter, PsiClass... classes) {
Set<String> results = new HashSet<String>();
collectAnnotationValues(results, parameter, null, classes);
return results;
Map<String, Collection<String>> results = new HashMap<>();
final HashSet<String> set = new HashSet<>();
results.put(parameter, set);
collectAnnotationValues(results, null, classes);
return set;
}
/**
* @return were javadoc params used
*/
public static void collectAnnotationValues(final Set<String> results, final String parameter, PsiMethod[] psiMethods, PsiClass... classes) {
public static void collectAnnotationValues(final Map<String, Collection<String>> results, PsiMethod[] psiMethods, PsiClass... classes) {
final Set<String> test = new HashSet<String>(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<String> results,
private static void appendAnnotationAttributeValues(final Map<String, Collection<String>> 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<String> 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));
}
}
@@ -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<PsiMethod, List<String>> methods = classes.get(aClass);
assertContainsElements(methods.keySet(), expectedMethods);
if (secondaryClass != null) {
final Map<PsiMethod, List<String>> configMethods = classes.get(secondaryClass);
assertTrue(configMethods != null);
assertTrue(configMethods.containsKey(configMethod));
}
}
private void doTestClassConfiguration(PsiClass aClass) throws CantRunException {