How to disable TestNG test based on a condition

我是研究僧i 提交于 2019-11-28 19:19:25

You have two options:

Your annotation transformer would test the condition and then override the @Test annotation to add the attribute "enabled=false" if the condition is not satisfied.

An easier option is to use the @BeforeMethod annotation on a method which checks your condition. If you want to skip the tests, then just throw a SkipException. Like this:

@BeforeMethod
protected void checkEnvironment() {
  if (!resourceAvailable) {
    throw new SkipException("Skipping tests because resource was not available.");
  }
}
Makeen A. Sabree

There are two ways that I know of that allow you the control of "disabling" tests in TestNG.

The differentiation that is very important to note is that SkipException will break out off all subsequent tests while implmenting IAnnotationTransformer uses Reflection to disbale individual tests, based on a condition that you specify. I will explain both SkipException and IAnnotationTransfomer.

SKIP Exception example

import org.testng.*;
import org.testng.annotations.*;

public class TestSuite
{
    // You set this however you like.
    boolean myCondition;

    // Execute before each test is run
    @BeforeMethod
    public void before(Method methodName){
        // check condition, note once you condition is met the rest of the tests will be skipped as well
        if(myCondition)
            throw new SkipException();
    }

    @Test(priority = 1)
    public void test1(){}

    @Test(priority = 2)
    public void test2(){}

    @Test(priority = 3)
    public void test3(){}
}

IAnnotationTransformer example

A bit more complicated but the idea behind it is a concept known as Reflection.

Wiki - http://en.wikipedia.org/wiki/Reflection_(computer_programming)

First implement the IAnnotation interface, save this in a *.java file.

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import org.testng.IAnnotationTransformer;
import org.testng.annotations.ITestAnnotation;

public class Transformer implements IAnnotationTransformer {

// Do not worry about calling this method as testNG calls it behind the scenes before EVERY method (or test).
// It will disable single tests, not the entire suite like SkipException
public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod){

    // If we have chose not to run this test then disable it.
    if (disableMe()){
        annotation.setEnabled(false);
    }
}

// logic YOU control
private boolean disableMe()){
}

Then in you test suite java file do the following in the @BeforeClass function

import org.testng.*;
import org.testng.annotations.*;

/* Execute before the tests run. */    
@BeforeClass
public void before(){

    TestNG testNG = new TestNG();
    testNG.setAnnotationTransformer(new Transformer());
}

@Test(priority = 1)
public void test1(){}

@Test(priority = 2)
public void test2(){}

@Test(priority = 3)
public void test3(){}

One last step is to ensure that you add a listener in your build.xml file. Mine ended up looking like this, this is just a single line from the build.xml:

<testng classpath="${test.classpath}:${build.dir}" outputdir="${report.dir}" 
    haltonfailure="false" useDefaultListeners="true"
    listeners="org.uncommons.reportng.HTMLReporter,org.uncommons.reportng.JUnitXMLReporter,Transformer" 
    classpathref="reportnglibs"></testng>

A Third option also can be Assumption Assumptions for TestNG - When a assumption fails, TestNG will be instructed to ignore the test case and will thus not execute it.

  • Using the @Assumption annotation
  • Using AssumptionListener Using the Assumes.assumeThat(...) method

You can use this example: example

SkipException: It's useful in case of we have only one @Test method in the class. Like for Data Driven Framework, I have only one Test method which need to either executed or skipped on the basis of some condition. Hence I've put the logic for checking the condition inside the @Test method and get desired result. It helped me to get the Extent Report with test case result as Pass/Fail and particular Skip as well.

Throwing a SkipException in a method annotated with @BeforeMethod did not work for me because it skipped all the remaining tests of my test suite with no regards if a SkipException were thrown for those tests.

I did not investigate it thoroughly but I found another way : using the dependsOnMethods attribute on the @Test annotation:

import org.testng.SkipException;
import org.testng.annotations.Test;

public class MyTest {

  private boolean conditionX = true;
  private boolean conditionY = false;

  @Test
  public void isConditionX(){
    if(!conditionX){
      throw new SkipException("skipped because of X is false");
    }
  }

  @Test
  public void isConditionY(){
    if(!conditionY){
      throw new SkipException("skipped because of Y is false");
    }
  }

  @Test(dependsOnMethods="isConditionX")
  public void test1(){

  }

  @Test(dependsOnMethods="isConditionY")
  public void test2(){

  }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!