Unable to pass groups in TestNG as an array of constants #3130
-
I have many test groups, that i want to include in multiple tests. I am not using TestNG.xml file, rather i am specifying these groups directly in @test annotation using groups key as:
I would like to create different test suites for different set of tests and i want the same set of groups to be present on multiple classes, and i don't want to repeatedly add the same set of groups manually in all of the tests, rather i want to pass a constant array of Strings for groups attribute so it is easier for me later to change these groups at single place and still applied to all the test methods.
This seems to be a limitation from Java for annotion attributes that they must be a constant expression that compiler can interpret. However I am unable to find a way to workaround this, or perhaps i am not passing the String array in a right manner? If this is a limitation, could you please suggest a workaround and add this feature in TestNG to allow us to pass list/array of groups as value of groups attribute. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
This is a Java requirement and NOT something that is enforced by TestNG. The rationale behind is that a string array's value can still be altered. You would need to stick to referring to them individually. Trying to put workarounds around this, will seriously hamper readability and so I would suggest that you stick to what is supported in Java. If you are still looking for an alternative, then here's what you can do:
The custom annotationimport java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
@Retention(RetentionPolicy.RUNTIME)
@Target({METHOD, TYPE})
public @interface BelongsToGroups {
String[] groupNames() default "";
} The annotation transformerimport org.testng.IAnnotationTransformer;
import org.testng.annotations.ITestAnnotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class GroupNamesAdder implements IAnnotationTransformer {
private static final Map<String, List<String>> groupMappings =
Map.of(
"p1", List.of("a", "b"),
"p2", List.of("c", "d")
);
@Override
public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {
BelongsToGroups groups = null;
if (testMethod != null) {
//We are trying to parse a test method
groups = testMethod.getAnnotation(BelongsToGroups.class);
} else if (testClass != null) {
Annotation raw = testClass.getAnnotation(BelongsToGroups.class);
if (raw != null) {
groups = (BelongsToGroups) raw;
}
}
if (groups != null) {
String[] groupsToAdd = Arrays.stream(groups.groupNames())
.flatMap(it -> groupMappings.get(it).stream())
.toArray(String[]::new);
annotation.setGroups(groupsToAdd);
}
}
} Sample test classimport org.testng.annotations.Test;
public class SampleTestCase {
@Test
@BelongsToGroups(groupNames = {"p1"})
public void a() {
}
@Test
@BelongsToGroups(groupNames = {"p2"})
public void b() {
}
} Suite file<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="3130_suite" verbose="2">
<test name="3130_test">
<groups>
<run>
<include name="c"/>
</run>
</groups>
<classes>
<class name="com.rationaleemotions.github.issue3130.SampleTestCase"/>
</classes>
</test>
</suite> The listener can be wired in using the |
Beta Was this translation helpful? Give feedback.
This is a Java requirement and NOT something that is enforced by TestNG. The rationale behind is that a string array's value can still be altered. You would need to stick to referring to them individually. Trying to put workarounds around this, will seriously hamper readability and so I would suggest that you stick to what is supported in Java.
If you are still looking for an alternative, then here's what you can do: