Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to put a condition to TestNG to run the test if that is member of two groups?

I know you can define in your xml which groups that you want to run, but I want to know whether it is possible to say run these methods if they are both member of groups A & B.

Let's say I have the following test cases;

@Test(groups={"A","B"})
public testA() {}

@Test(groups={"B","C"})
public testB(){}

and following configuration;

<test name="Test A|B">
<groups>
       <run>
           <include name="B" />
       </run>
    </groups>

    <classes>
        <class name="com.test.Test" />
    </classes>
</test>

This will run both testA and testB since they are both members of group B. I want to run the test only if it is member of both groups A & B.

Is it possible to do such thing with TestNG?

Thanks in advance

like image 509
Jail Avatar asked May 15 '14 19:05

Jail


People also ask

Can we use multiple groups in TestNG?

Thus, TestNG can be asked to include a certain set of groups while excluding another set of groups. It provides you maximum flexibility by partitioning your test methods in groups and does not require recompilation of test cases if you run your two different sets of test cases back to back.

How do you add two groups in TestNG?

To run a group of test cases from the collection of test cases, we have to define <groups> in the testng xml file. Here the testNG xml contains multiple groups QuestionAnswer and Jobs to be associated to a single Test.

How do you run test cases in group by TestNG?

Group test is a new innovative feature in TestNG, which doesn't exist in JUnit framework. It permits you to dispatch methods into proper portions and perform sophisticated groupings of test methods. Not only can you declare those methods that belong to groups, but you can also specify groups that contain other groups.

How do you test one dependent on another TestNG?

Using 'dependsOnMethod' attribute within @Test annotation, we can specify the name of parent test method on which the test should be dependent. On execution of the whole test class or test suite, the parentTest method will run before the dependentTest.


2 Answers

You can create a listener implementing IMethodInterceptor interface. Which will give you an ability to access groups list from your @Test and manage your "tests to execute list" as you need. At same time ITestContext parameter allows you to access the data from testNg xml. So, you can set groups to run in default testNg manner (suite xml file); but run them depending on algorithm you implement. Something like:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.testng.IMethodInstance;
import org.testng.IMethodInterceptor;
import org.testng.ITestContext;
import org.testng.annotations.Test;

public class Interceptor implements IMethodInterceptor
{

    @Override
    public List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context)
    {
        int methCount = methods.size();
        List<IMethodInstance> result = new ArrayList<IMethodInstance>();

        for (int i = 0; i < methCount; i++)
        {
            IMethodInstance instns = methods.get(i);
            List<String> grps = Arrays.asList(instns.getMethod().getConstructorOrMethod().getMethod().getAnnotation(Test.class).groups());
//get these groups from testng.xml via context method parameter                         
            if (grps.contains("A") && grps.contains("B"))
            {
                result.add(instns);
            }                       
        }                       
        return result;
    }
}
like image 171
user1058106 Avatar answered Oct 06 '22 00:10

user1058106


You can do this with the TestNG beanshell support: http://testng.org/doc/documentation-main.html#beanshell (you are getting access to method, testngMethod, and groups)

In your particular case, it would be something like this:

<method-selectors>
  <method-selector>
    <script language="beanshell"><![CDATA[
       return groups.containsKey("A") && groups.containsKey("B");
     ]]></script>
  </method-selector>
</method-selectors>

You could also do a System.out.println() if you wanted to debug stuff.

The catch here is that you need to define the "method-selectors" in the "test" block. For some reason, if you define the "method-selectors" in "suite" (which is syntactically correct), the filter is not applied.

Debugging this with System.out.println() is going to help you understand whether the stuff even runs, or which methods it filters, so e.g.:

<method-selectors>
  <method-selector>
    <script language="beanshell"><![CDATA[
      runMethod = groups.containsKey("A") && groups.containsKey("B");
      System.out.println("run '" + testngMethod.getMethodName() + "'? -> " + runMethod);
      return runMethod;
    ]]></script>
  </method-selector>
</method-selectors>
like image 25
mac Avatar answered Oct 05 '22 23:10

mac