RekaB RekaB - 3 months ago 8
Java Question

testng - creating KnownFault and IntermittentFailure annotations

I would like to annotate some of my test cases with KnownFault - which would do pretty much what expectedException does plus some magic using YouTrack's REST API. I would also like to have an IntermittentFailure attribute which would mean that I'm aware that the test might occasionally fail with [exception] [message] but I wouldn't want this to block the rest of my build chain.

After some research I found that my test class should implement IHookable, then I could have something like this:

@Override
public void run(IHookCallBack callBack, ITestResult result) {
callBack.runTestMethod(result);
if (result.getThrowable().getCause() instanceof IllegalArgumentException){
System.out.println("This is expected.");
result.setThrowable(null);
}
else{
System.out.println("Unexpected exception");
}
}


The problem with this is the actual implementation of invokeHookable:

final Throwable[] error = new Throwable[1];

IHookCallBack callback = new IHookCallBack() {
@Override
public void runTestMethod(ITestResult tr) {
try {
invokeMethod(thisMethod, testInstance, parameters);
} catch (Throwable t) {
error[0] = t;
tr.setThrowable(t); // make Throwable available to IHookable
}
}

@Override
public Object[] getParameters() {
return parameters;
}
};
hookable.run(callback, testResult);
if (error[0] != null) {
throw error[0];
}


Unfortunately that last line means that my test case is going to throw an exception no matter what as the
error
array is completely out of my hands in the
run
method.

So, what would be the proper way of intercepting an exception and handling it the way I want to?

Answer

What you are trying to do is really interesting. You should try to propose changes on https://github.com/cbeust/testng/pull/

But maybe IHookable is not the best listener you can use. Did you try IInvokedMethodListener?

void afterInvocation(IInvokedMethod method, ITestResult result) {
    if (result.getThrowable().getCause() instanceof IllegalArgumentException) {
        System.out.println("This is expected.");
        result.setThrowable(null);
        result.setStatus(SUCCESS); // If you want to change the status
    } else {
        System.out.println("Unexpected exception");
    }
}
Comments