Sig
Sig

Reputation: 133

Disable TestNG tests based on condition and test class annotation

I have a test suite that from time to time needs to be used on prod environment, but due to technical details it is not possible to run some tests on it. My idea is to annotate such test classes with custom annotations and then disable test methods in them if i'm running against prod. Something like this:

    @DisableOnProd
    class SomeTestClass {   
    @BeforeMethod
    void setUp(){
        ...
    }   
    @Test
    void test() {
        ...
    }   
}

I can get something close by implementing IAnnotationTransformer2 like this, but it will disable all test methods:

    @Override
    public void transform(ITestAnnotation iTestAnnotation, Class aClass, Constructor constructor, Method method) {
    if (method.isAnnotationPresent(Test.class) || method.isAnnotationPresent(BeforeMethod.class)) {
        iTestAnnotation.setEnabled(false);
    }
}

}

Is there any way to get test class annotations to check the condition or there is a way to get the same result with other solution?

Upvotes: 0

Views: 2503

Answers (3)

Muzzamil
Muzzamil

Reputation: 2881

You can use testng listener onTestStart with some condition as mentione below:

public class TestListener extends TestListenerAdapter {



      public void onTestStart(ITestResult arg0) {

            super.onTestStart(arg0);



            if (condition)  {

                  throw new SkipException("Testing skip.");

            }



      }

}

or Before method with some condition can be utilized

@BeforeMethod
public void checkCondition() {
  if (condition) {
    throw new SkipException("Skipping tests .");
  }
}

Upvotes: 2

Sig
Sig

Reputation: 133

Thanks for the answers, they've pointed me to the right direction. So far most flexible solution I've got is by using listener that implements IMethodInterceptor:

public class SkipOnProductionListener implements IMethodInterceptor {

    public List<IMethodInstance> intercept(List<IMethodInstance> list, ITestContext iTestContext) {
        if (isProduction()) {
            list.removeIf(method -> method.getMethod().getRealClass().isAnnotationPresent(SkipIfOnProd.class));
            list.removeIf(method -> method.getMethod().getConstructorOrMethod().getMethod().isAnnotationPresent(SkipIfOnProd.class));
        }
        return list;
    }

    private boolean isProduction() {
        //do some env determination logic here
        return true;
    }

}

This way I can place the annotation either on class and skip all test methods, or just individual methods.

Upvotes: 0

user861594
user861594

Reputation: 5908

Try cheking annotation present on class along with other condition. For example:

   if(someCondition && testMethod.getDeclaringClass().isAnnotationPresent(DisableOnProd.class)) {
            iTestAnnotation.setEnabled(false);
   }

Upvotes: 1

Related Questions