Search code examples
javatestingtestngtestng-annotation-test

TestNg grouping


We are using testNg as our test framework, where in we use @groups annotation for running specific tests. How can we customize this annotation to make the groups specified in the build target are considered in 'AND' instead of 'OR'.

@groups({'group1', 'group2'})
public void test1

@groups({'group1', 'group3'})
public void test2

if we pass groups as {group1,group2}, then test1 should be the only test case which gets triggered. Currently, using the default implementation both test1 and test2 get triggered because the annotation considers both groups in 'or' instead of 'and'


Solution

  • The current implementation is such that, If any one of the groups specified in the test method matches with any one group specified in your suite file, then the test is included to run.

    Currently there are no provisions to change this implementation of "any match" to "all match". But you could achieve the same using IMethodInterceptor.

    (Also, for the specific example in question, you could have achieved the desired result by mentioning group3 as an excluded group. But this will not work in many other scenarios).

    import java.util.Arrays;
    
    public class MyInterceptor implements IMethodInterceptor {
        
        @Override
        public List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context) {
            String[] includedGroups = context.getIncludedGroups();
            Arrays.sort(includedGroups);
    
            List<IMethodInstance> newList = new ArrayList<>();
            for(IMethodInstance m : methods) {
                String[] groups = m.getMethod().getGroups();
                Arrays.sort(groups);
    
                // logic could be changed here if exact match is not required.
                if(Arrays.equals(includedGroups, groups)) {
                    newList.add(m);
                }
            }
    
            return newList;
        }
    }    
    

    Then on top of your test class, use the @Listeners annotation.

    @Listeners(value = MyInterceptor.class)
    public class MyTestClass {
    }