org.testng.internal.TestInvoker Maven / Gradle / Ivy
Show all versions of testng Show documentation
package org.testng.internal;
import static org.testng.internal.Invoker.CAN_RUN_FROM_CLASS;
import static org.testng.internal.invokers.InvokedMethodListenerMethod.AFTER_INVOCATION;
import static org.testng.internal.invokers.InvokedMethodListenerMethod.BEFORE_INVOCATION;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import org.testng.DataProviderHolder;
import org.testng.DataProviderInvocationException;
import org.testng.IClassListener;
import org.testng.IDataProviderListener;
import org.testng.IHookable;
import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.IRetryAnalyzer;
import org.testng.ISuite;
import org.testng.ITestClass;
import org.testng.ITestContext;
import org.testng.ITestNGMethod;
import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.SuiteRunState;
import org.testng.SuiteRunner;
import org.testng.TestException;
import org.testng.TestNGException;
import org.testng.collections.Lists;
import org.testng.collections.Maps;
import org.testng.collections.Sets;
import org.testng.internal.GroupConfigMethodArguments.Builder;
import org.testng.internal.InvokeMethodRunnable.TestNGRuntimeException;
import org.testng.internal.ParameterHandler.ParameterBag;
import org.testng.internal.thread.ThreadExecutionException;
import org.testng.internal.thread.ThreadUtil;
import org.testng.thread.IWorker;
import org.testng.xml.XmlSuite;
class TestInvoker extends BaseInvoker implements ITestInvoker {
private final ConfigInvoker invoker;
private final DataProviderHolder holder;
private final List m_classListeners;
private final boolean m_skipFailedInvocationCounts;
public TestInvoker(ITestResultNotifier m_notifier,
ITestContext m_testContext, SuiteRunState m_suiteState,
IConfiguration m_configuration, Collection m_invokedMethodListeners,
DataProviderHolder holder, List m_classListeners,
boolean m_skipFailedInvocationCounts,
ConfigInvoker invoker) {
super(m_notifier, m_invokedMethodListeners, m_testContext, m_suiteState, m_configuration
);
this.holder = holder;
this.m_classListeners = m_classListeners;
this.m_skipFailedInvocationCounts = m_skipFailedInvocationCounts;
this.invoker = invoker;
}
@Override
public ITestResultNotifier getNotifier() {
return m_notifier;
}
public List invokeTestMethods(ITestNGMethod testMethod,
ConfigurationGroupMethods groupMethods,
Object instance,
ITestContext context) {
// Potential bug here if the test method was declared on a parent class
if (testMethod.getTestClass() == null) {
throw new IllegalArgumentException(
"COULDN'T FIND TESTCLASS FOR " + testMethod.getRealClass());
}
XmlSuite suite = context.getSuite().getXmlSuite();
if (!MethodHelper.isEnabled(
testMethod.getConstructorOrMethod().getMethod(), annotationFinder())) {
// return if the method is not enabled. No need to do any more calculations
return Collections.emptyList();
}
Map parameters = testMethod.findMethodParameters(context.getCurrentXmlTest());
// By the time this testMethod to be invoked,
// all dependencies should be already run or we need to skip this method,
// so invocation count should not affect dependencies check
String okToProceed = checkDependencies(testMethod, context.getAllTestMethods());
if (okToProceed != null) {
//
// Not okToProceed. Test is being skipped
//
ITestResult result =
registerSkippedTestResult(
testMethod, System.currentTimeMillis(), new Throwable(okToProceed));
m_notifier.addSkippedTest(testMethod, result);
InvokedMethod invokedMethod = new InvokedMethod(result.getInstance(), testMethod,
System.currentTimeMillis(), result);
invokeListenersForSkippedTestResult(result, invokedMethod);
testMethod.incrementCurrentInvocationCount();
GroupConfigMethodArguments args = new Builder()
.forTestMethod(testMethod)
.withGroupConfigMethods(groupMethods)
.forInstance(instance)
.withParameters(parameters)
.build();
this.invoker.invokeAfterGroupsConfigurations(args);
return Collections.singletonList(result);
}
// For invocationCount > 1 and threadPoolSize > 1 run this method in its own pool thread.
if (testMethod.getInvocationCount() > 1 && testMethod.getThreadPoolSize() > 1) {
return invokePooledTestMethods(testMethod, suite, parameters, groupMethods, context);
}
long timeOutInvocationCount = testMethod.getInvocationTimeOut();
// FIXME: Is this correct?
boolean onlyOne = testMethod.getThreadPoolSize() > 1 || timeOutInvocationCount > 0;
ITestClass testClass = testMethod.getTestClass();
ITestNGMethod[] beforeMethods =
TestNgMethodUtils.filterBeforeTestMethods(testClass, CAN_RUN_FROM_CLASS);
ITestNGMethod[] afterMethods =
TestNgMethodUtils.filterAfterTestMethods(testClass, CAN_RUN_FROM_CLASS);
int invocationCount = onlyOne ? 1 : testMethod.getInvocationCount();
TestMethodArguments arguments = new TestMethodArguments.Builder()
.usingInstance(instance)
.forTestMethod(testMethod)
.withParameters(parameters)
.forTestClass(testClass)
.usingBeforeMethods(beforeMethods)
.usingAfterMethods(afterMethods)
.usingGroupMethods(groupMethods)
.build();
MethodInvocationAgent agent = new MethodInvocationAgent(arguments, this, context);
while (invocationCount-- > 0) {
invocationCount = agent.invoke(invocationCount);
}
return agent.getResult();
}
/**
* invokeTestMethods() eventually converge here to invoke a single @Test method.
*
* This method is responsible for actually invoking the method. It decides if the invocation
* must be done:
*
*
* - through an
IHookable
* - directly (through reflection)
*
- in a separate thread (in case it needs to timeout)
*
*
* This method is also responsible for
* invoking @BeforeGroup, @BeforeMethod, @AfterMethod, @AfterGroup if it is the case for the
* passed in @Test method.
*/
public ITestResult invokeTestMethod(TestMethodArguments arguments,
XmlSuite suite, FailureContext failureContext) {
// Mark this method with the current thread id
arguments.getTestMethod().setId(ThreadUtil.currentThreadInfo());
return invokeMethod(arguments, suite, failureContext);
}
public FailureContext retryFailed(
TestMethodArguments arguments, List result,
int failureCount,
ITestContext testContext) {
FailureContext failure = new FailureContext();
failure.count = failureCount;
failure.representsRetriedMethod = true;
do {
failure.instances = Lists.newArrayList();
Map allParameters = Maps.newHashMap();
// TODO: This recreates all the parameters every time when we only need
// one specific set. Should optimize it by only recreating the set needed.
ParameterHandler handler = new ParameterHandler(annotationFinder(), this.holder);
ParameterBag bag = handler.createParameters(arguments.getTestMethod(),
arguments.getParameters(), allParameters, testContext);
ITestResult errorResult = bag.errorResult;
if (errorResult != null ) {
Throwable cause = errorResult.getThrowable();
String m = errorResult.getMethod().getMethodName();
String msg = String.format("Encountered problems when gathering parameter values for [%s]. Root cause: ", m);
throw new DataProviderInvocationException(msg, cause);
}
Object[] parameterValues =
Parameters.getParametersFromIndex(Objects.requireNonNull(bag.parameterHolder).parameters,
arguments.getParametersIndex());
if (bag.parameterHolder.origin == ParameterHolder.ParameterOrigin.NATIVE) {
parameterValues = arguments.getParameterValues();
}
TestMethodArguments tma = new TestMethodArguments.Builder()
.usingArguments(arguments)
.withParameterValues(parameterValues)
.withParameters(allParameters)
.build();
result.add(invokeMethod(tma, testContext.getSuite().getXmlSuite(), failure));
} while (!failure.instances.isEmpty());
return failure;
}
public void runTestResultListener(ITestResult tr) {
TestListenerHelper.runTestListeners(tr, m_notifier.getTestListeners());
}
private Collection dataProviderListeners() {
ISuite suite = this.m_testContext.getSuite();
Collection dpListeners = Sets.newHashSet(this.holder.getListeners());
if (suite instanceof SuiteRunner) {
Collection listeners = ((SuiteRunner) suite)
.getDataProviderListeners();
dpListeners.addAll(listeners);
}
return dpListeners;
}
private DataProviderHolder buildDataProviderHolder() {
DataProviderHolder holder = new DataProviderHolder();
holder.addListeners(dataProviderListeners());
holder.addInterceptors(this.holder.getInterceptors());
return holder;
}
/**
* Checks to see of the test method has certain dependencies that prevents TestNG from executing
* it
*
* @param testMethod test method being checked for
* @return error message or null if dependencies have been run successfully
*/
private String checkDependencies(ITestNGMethod testMethod, ITestNGMethod[] allTestMethods) {
// If this method is marked alwaysRun, no need to check for its dependencies
if (testMethod.isAlwaysRun()) {
return null;
}
// Any missing group?
if (testMethod.getMissingGroup() != null && !testMethod.ignoreMissingDependencies()) {
return "Method "
+ testMethod
+ " depends on nonexistent group \""
+ testMethod.getMissingGroup()
+ "\"";
}
// If this method depends on groups, collect all the methods that
// belong to these groups and make sure they have been run successfully
String[] groups = testMethod.getGroupsDependedUpon();
if (null != groups && groups.length > 0) {
// Get all the methods that belong to the group depended upon
for (String element : groups) {
ITestNGMethod[] methods =
MethodGroupsHelper.findMethodsThatBelongToGroup(
testMethod, m_testContext.getAllTestMethods(), element);
if (methods.length == 0 && !testMethod.ignoreMissingDependencies()) {
// Group is missing
return "Method " + testMethod + " depends on nonexistent group \"" + element + "\"";
}
if (failuresPresentInUpstreamDependency(testMethod, methods)) {
return "Method "
+ testMethod
+ " depends on not successfully finished methods in group \""
+ element
+ "\"";
}
}
} // depends on groups
// If this method depends on other methods, make sure all these other
// methods have been run successfully
if (TestNgMethodUtils.cannotRunMethodIndependently(testMethod)) {
ITestNGMethod[] methods = MethodHelper.findDependedUponMethods(testMethod, allTestMethods);
if (failuresPresentInUpstreamDependency(testMethod, methods)) {
return "Method " + testMethod + " depends on not successfully finished methods";
}
}
return null;
}
/**
* To reduce thread contention and also to correctly handle thread-confinement this method invokes
* the @BeforeGroups and @AfterGroups corresponding to the current @Test method.
*/
private List runWorkers(
ITestNGMethod testMethod,
List> workers,
int threadPoolSize,
ConfigurationGroupMethods groupMethods,
XmlSuite suite,
Map parameters) {
// Invoke @BeforeGroups on the original method (reduce thread contention,
// and also solve thread confinement)
ITestClass testClass = testMethod.getTestClass();
Object[] instances = testClass.getInstances(true);
for (Object instance : instances) {
GroupConfigMethodArguments arguments = new GroupConfigMethodArguments.Builder()
.forTestMethod(testMethod)
.withGroupConfigMethods(groupMethods)
.withParameters(parameters)
.forInstance(instance)
.build();
invoker.invokeBeforeGroupsConfigurations(arguments);
}
long maxTimeOut = -1; // 10 seconds
for (IWorker tmw : workers) {
long mt = tmw.getTimeOut();
if (mt > maxTimeOut) {
maxTimeOut = mt;
}
}
ThreadUtil.execute("methods", workers, threadPoolSize, maxTimeOut, true);
//
// Collect all the TestResults
//
List result = Lists.newArrayList();
for (IWorker tmw : workers) {
if (tmw instanceof TestMethodWorker) {
result.addAll(((TestMethodWorker) tmw).getTestResults());
}
}
for (Object instance : instances) {
GroupConfigMethodArguments arguments = new GroupConfigMethodArguments.Builder()
.forTestMethod(testMethod)
.withGroupConfigMethods(groupMethods)
.withParameters(parameters)
.forInstance(instance)
.build();
invoker.invokeAfterGroupsConfigurations(arguments);
}
return result;
}
private boolean failuresPresentInUpstreamDependency(ITestNGMethod testMethod, ITestNGMethod[] methods) {
// Make sure the method has been run successfully
for (ITestNGMethod method : methods) {
Set results = keepSameInstances(testMethod, m_notifier.getPassedTests(method));
Set failedAndSkippedMethods = Sets.newHashSet();
Set skippedAttempts = m_notifier.getSkippedTests(method);
failedAndSkippedMethods.addAll(m_notifier.getFailedTests(method));
failedAndSkippedMethods.addAll(skippedAttempts);
Set failedresults = keepSameInstances(testMethod, failedAndSkippedMethods);
boolean wasMethodRetried = !results.isEmpty() && !skippedAttempts.isEmpty();
if (!wasMethodRetried && !failedresults.isEmpty()) {
// If failed results were returned on the same instance, then these tests didn't pass
return true;
}
for (ITestResult result : results) {
if (!result.isSuccess()) {
return true;
}
}
}
return false;
}
/** @return the test results that apply to one of the instances of the testMethod. */
private Set keepSameInstances(ITestNGMethod method, Set results) {
Set result = Sets.newHashSet();
for (ITestResult r : results) {
Object o = method.getInstance();
// Keep this instance if 1) It's on a different class or 2) It's on the same class
// and on the same instance
Object instance = r.getInstance() != null ? r.getInstance() : r.getMethod().getInstance();
if (r.getTestClass() != method.getTestClass() || instance == o) {
result.add(r);
}
}
return result;
}
/** Invokes a method that has a specified threadPoolSize. */
private List invokePooledTestMethods(
ITestNGMethod testMethod,
XmlSuite suite,
Map parameters,
ConfigurationGroupMethods groupMethods,
ITestContext testContext) {
//
// Create the workers
//
List> workers = Lists.newArrayList();
// Create one worker per invocationCount
for (int i = 0; i < testMethod.getInvocationCount(); i++) {
// we use clones for reporting purposes
ITestNGMethod clonedMethod = testMethod.clone();
clonedMethod.setInvocationCount(1);
clonedMethod.setThreadPoolSize(1);
MethodInstance mi = new MethodInstance(clonedMethod);
workers.add(new SingleTestMethodWorker(this, invoker, mi, parameters, testContext, m_classListeners));
}
return runWorkers(
testMethod, workers, testMethod.getThreadPoolSize(), groupMethods, suite, parameters);
}
private void collectResults(ITestNGMethod testMethod, ITestResult result) {
// Collect the results
int status = result.getStatus();
if (ITestResult.SUCCESS == status) {
m_notifier.addPassedTest(testMethod, result);
} else if (ITestResult.SKIP == status) {
m_notifier.addSkippedTest(testMethod, result);
} else if (ITestResult.FAILURE == status) {
m_notifier.addFailedTest(testMethod, result);
} else if (ITestResult.SUCCESS_PERCENTAGE_FAILURE == status) {
m_notifier.addFailedButWithinSuccessPercentageTest(testMethod, result);
} else {
assert false : "UNKNOWN STATUS:" + status;
}
}
public void invokeListenersForSkippedTestResult(ITestResult r, IInvokedMethod invokedMethod) {
if (m_configuration.alwaysRunListeners()) {
runInvokedMethodListeners(BEFORE_INVOCATION, invokedMethod, r);
runInvokedMethodListeners(AFTER_INVOCATION, invokedMethod, r);
}
runTestResultListener(r);
}
private static void setTestStatus(ITestResult result, int status) {
// set the test to success as long as the testResult hasn't been changed by the user via
// Reporter.getCurrentTestResult
if (result.getStatus() == ITestResult.STARTED) {
result.setStatus(status);
}
}
private static class StatusHolder {
boolean handled = false;
int status;
}
private void handleInvocationResults(
ITestNGMethod testMethod,
ITestResult testResult,
FailureContext failure,
StatusHolder holder,
boolean wasResultUnaltered) {
//
// Go through all the results and create a TestResult for each of them
//
List resultsToRetry = Lists.newArrayList();
Throwable ite = testResult.getThrowable();
int status =
computeTestStatusComparingTestResultAndStatusHolder(testResult, holder, wasResultUnaltered);
boolean handled = holder.handled;
IRetryAnalyzer retryAnalyzer = testMethod.getRetryAnalyzer(testResult);
boolean willRetry =
retryAnalyzer != null
&& status == ITestResult.FAILURE
&& failure.instances != null
&& retryAnalyzer.retry(testResult);
if (willRetry) {
resultsToRetry.add(testResult);
Object instance = testResult.getInstance();
if (!failure.instances.contains(instance)) {
failure.instances.add(instance);
}
testResult.setStatus(ITestResult.SKIP);
testResult.setWasRetried(true);
} else {
testResult.setStatus(status);
if (status == ITestResult.FAILURE && !handled) {
int count = failure.count++;
if (testMethod.isDataDriven()) {
count = 0;
}
handleException(ite, testMethod, testResult, count);
}
}
}
// pass both paramValues and paramIndex to be thread safe in case parallel=true + dataprovider.
private ITestResult invokeMethod(
TestMethodArguments arguments, XmlSuite suite, FailureContext failureContext) {
TestResult testResult = TestResult.newEmptyTestResult();
GroupConfigMethodArguments cfgArgs = new GroupConfigMethodArguments.Builder()
.forTestMethod(arguments.getTestMethod())
.withGroupConfigMethods(arguments.getGroupMethods())
.withParameters(arguments.getParameters())
.forInstance(arguments.getInstance())
.build();
invoker.invokeBeforeGroupsConfigurations(cfgArgs);
ITestNGMethod[] setupConfigMethods =
TestNgMethodUtils.filterSetupConfigurationMethods(arguments.getTestMethod(),
arguments.getBeforeMethods());
runConfigMethods(arguments, suite, testResult, setupConfigMethods);
long startTime = System.currentTimeMillis();
InvokedMethod invokedMethod = new InvokedMethod(arguments.getInstance(),
arguments.getTestMethod(), startTime, testResult);
if (!failureContext.representsRetriedMethod && invoker.hasConfigurationFailureFor(
arguments.getTestMethod(), arguments.getTestMethod().getGroups() ,
arguments.getTestClass(),
arguments.getInstance())) {
Throwable exception = ExceptionUtils.getExceptionDetails(m_testContext,
arguments.getInstance());
ITestResult result = registerSkippedTestResult(arguments.getTestMethod(), System.currentTimeMillis(), exception);
TestResult.copyAttributes(testResult, result);
m_notifier.addSkippedTest(arguments.getTestMethod(), result);
arguments.getTestMethod().incrementCurrentInvocationCount();
testResult.setMethod(arguments.getTestMethod());
invokedMethod = new InvokedMethod(arguments.getInstance(),
arguments.getTestMethod(), startTime, result);
invokeListenersForSkippedTestResult(result, invokedMethod);
runAfterGroupsConfigurations(arguments, suite, testResult);
return result;
}
//
// Create the ExtraOutput for this method
//
try {
testResult = TestResult
.newTestResultFrom(testResult, arguments.getTestMethod(), m_testContext, System.currentTimeMillis());
//Recreate the invoked method object again, because we now have a new test result object
invokedMethod = new InvokedMethod(arguments.getInstance(),
arguments.getTestMethod(), invokedMethod.getDate(), testResult);
testResult.setParameters(arguments.getParameterValues());
testResult.setParameterIndex(arguments.getParametersIndex());
testResult.setHost(m_testContext.getHost());
testResult.setStatus(ITestResult.STARTED);
Reporter.setCurrentTestResult(testResult);
// Fix from ansgarkonermann
// invokedMethod is used in the finally, which can be invoked if
// any of the test listeners throws an exception, therefore,
// invokedMethod must have a value before we get here
if (!m_suiteState.isFailed()) {
runTestResultListener(testResult);
}
log(3, "Invoking " + arguments.getTestMethod().getQualifiedName());
runInvokedMethodListeners(BEFORE_INVOCATION, invokedMethod, testResult);
m_notifier.addInvokedMethod(invokedMethod);
Method thisMethod = arguments.getTestMethod().getConstructorOrMethod().getMethod();
if (RuntimeBehavior.isDryRun()) {
setTestStatus(testResult, ITestResult.SUCCESS);
return testResult;
}
// If this method is a IHookable, invoke its run() method
IHookable hookableInstance =
IHookable.class.isAssignableFrom(arguments.getTestMethod().getRealClass())
? (IHookable) arguments.getInstance()
: m_configuration.getHookable();
if (MethodHelper.calculateTimeOut(arguments.getTestMethod()) <= 0) {
if (hookableInstance != null) {
MethodInvocationHelper.invokeHookable(
arguments.getInstance(), arguments.getParameterValues(), hookableInstance, thisMethod, testResult);
} else {
// Not a IHookable, invoke directly
MethodInvocationHelper.invokeMethod(thisMethod, arguments.getInstance(),
arguments.getParameterValues());
}
setTestStatus(testResult, ITestResult.SUCCESS);
} else {
// Method with a timeout
MethodInvocationHelper.invokeWithTimeout(
arguments.getTestMethod(), arguments.getInstance(),
arguments.getParameterValues(), testResult, hookableInstance);
}
} catch (InvocationTargetException ite) {
testResult.setThrowable(ite.getCause());
setTestStatus(testResult, ITestResult.FAILURE);
} catch (ThreadExecutionException tee) { // wrapper for TestNGRuntimeException
Throwable cause = tee.getCause();
if (TestNGRuntimeException.class.equals(cause.getClass())) {
testResult.setThrowable(cause.getCause());
} else {
testResult.setThrowable(cause);
}
setTestStatus(testResult, ITestResult.FAILURE);
} catch (Throwable thr) { // covers the non-wrapper exceptions
testResult.setThrowable(thr);
setTestStatus(testResult, ITestResult.FAILURE);
} finally {
// Set end time ASAP
testResult.setEndMillis(System.currentTimeMillis());
ExpectedExceptionsHolder expectedExceptionClasses =
new ExpectedExceptionsHolder(
annotationFinder(), arguments.getTestMethod(), new RegexpExpectedExceptionsHolder(annotationFinder(),
arguments.getTestMethod()));
StatusHolder holder =
considerExceptions(arguments.getTestMethod(), testResult, expectedExceptionClasses, failureContext);
int statusBeforeListenerInvocation = testResult.getStatus();
runInvokedMethodListeners(AFTER_INVOCATION, invokedMethod, testResult);
boolean wasResultUnaltered = statusBeforeListenerInvocation == testResult.getStatus();
handleInvocationResults(arguments.getTestMethod(), testResult, failureContext, holder, wasResultUnaltered);
// If this method has a data provider and just failed, memorize the number
// at which it failed.
// Note: we're not exactly testing that this method has a data provider, just
// that it has parameters, so might have to revisit this if bugs get reported
// for the case where this method has parameters that don't come from a data
// provider
if (testResult.getThrowable() != null && arguments.getParameterValues().length > 0) {
arguments.getTestMethod()
.addFailedInvocationNumber(arguments.getParametersIndex());
}
//
// Increment the invocation count for this method
//
arguments.getTestMethod().incrementCurrentInvocationCount();
runTestResultListener(testResult);
collectResults(arguments.getTestMethod(), testResult);
runAfterGroupsConfigurations(
arguments, suite, testResult);
// Reset the test result last. If we do this too early, Reporter.log()
// invocations from listeners will be discarded
Reporter.setCurrentTestResult(null);
}
return testResult;
}
private void runAfterGroupsConfigurations(TestMethodArguments arguments,
XmlSuite suite, TestResult testResult) {
ITestNGMethod[] teardownConfigMethods =
TestNgMethodUtils.filterTeardownConfigurationMethods(arguments.getTestMethod(),
arguments.getAfterMethods());
runConfigMethods(arguments, suite, testResult, teardownConfigMethods);
GroupConfigMethodArguments grpArgs = new GroupConfigMethodArguments.Builder()
.forTestMethod(arguments.getTestMethod())
.withGroupConfigMethods(arguments.getGroupMethods())
.withParameters(arguments.getParameters())
.forInstance(arguments.getInstance())
.build();
invoker.invokeAfterGroupsConfigurations(grpArgs);
}
private void runConfigMethods(TestMethodArguments arguments,
XmlSuite suite, TestResult testResult, ITestNGMethod[] teardownConfigMethods) {
ConfigMethodArguments cfgArgs = new ConfigMethodArguments.Builder()
.forTestClass(arguments.getTestClass())
.forTestMethod(arguments.getTestMethod())
.usingConfigMethodsAs(teardownConfigMethods)
.forSuite(suite)
.usingParameters(arguments.getParameters())
.usingParameterValues(arguments.getParameterValues())
.usingInstance(arguments.getInstance())
.withResult(testResult)
.build();
invoker.invokeConfigurations(cfgArgs);
}
public ITestResult registerSkippedTestResult(
ITestNGMethod testMethod, long start, Throwable throwable) {
ITestResult result =
TestResult.newEndTimeAwareTestResult(testMethod, m_testContext, throwable, start);
result.setStatus(ITestResult.STARTED);
runTestResultListener(result);
result.setStatus(TestResult.SKIP);
Reporter.setCurrentTestResult(result);
return result;
}
private StatusHolder considerExceptions(
ITestNGMethod tm,
ITestResult testresult,
ExpectedExceptionsHolder exceptionsHolder,
FailureContext failure) {
StatusHolder holder = new StatusHolder();
holder.status = testresult.getStatus();
holder.handled = false;
Throwable ite = testresult.getThrowable();
if (holder.status == ITestResult.FAILURE && ite != null) {
// Invocation caused an exception, see if the method was annotated with @ExpectedException
if (exceptionsHolder != null) {
if (exceptionsHolder.isExpectedException(ite)) {
testresult.setStatus(ITestResult.SUCCESS);
holder.status = ITestResult.SUCCESS;
} else {
if (isSkipExceptionAndSkip(ite)) {
holder.status = ITestResult.SKIP;
} else {
testresult.setThrowable(exceptionsHolder.wrongException(ite));
holder.status = ITestResult.FAILURE;
}
}
} else {
handleException(ite, tm, testresult, failure.count++);
holder.handled = true;
holder.status = testresult.getStatus();
}
} else if (holder.status != ITestResult.SKIP && exceptionsHolder != null) {
TestException exception = exceptionsHolder.noException(tm);
if (exception != null) {
testresult.setThrowable(exception);
holder.status = ITestResult.FAILURE;
}
}
return holder;
}
private static int computeTestStatusComparingTestResultAndStatusHolder(
ITestResult testResult, StatusHolder holder, boolean wasResultUnaltered) {
if (wasResultUnaltered) {
return holder.status;
}
return testResult.getStatus();
}
private class MethodInvocationAgent {
private final ITestContext context;
private final List result = Lists.newArrayList();
private final FailureContext failure = new FailureContext();
private final ITestInvoker invoker;
private final TestMethodArguments arguments;
public MethodInvocationAgent(TestMethodArguments arguments, ITestInvoker invoker, ITestContext context) {
this.arguments = arguments;
this.invoker = invoker;
this.context = context;
}
public List getResult() {
return result;
}
public int invoke(int invCount) {
AtomicInteger invocationCount = new AtomicInteger(invCount);
long start = System.currentTimeMillis();
Map allParameterNames = Maps.newHashMap();
ParameterHandler handler = new ParameterHandler(annotationFinder(), buildDataProviderHolder());
ParameterBag bag = handler.createParameters(
arguments.getTestMethod(),
arguments.getParameters(),
allParameterNames,
context,
arguments.getInstance());
if (bag.hasErrors()) {
ITestResult tr = bag.errorResult;
Throwable throwable = Objects.requireNonNull(tr).getThrowable();
if (throwable instanceof TestNGException) {
tr.setStatus(ITestResult.FAILURE);
m_notifier.addFailedTest(arguments.getTestMethod(), tr);
} else {
tr.setStatus(ITestResult.SKIP);
m_notifier.addSkippedTest(arguments.getTestMethod(), tr);
}
runTestResultListener(tr);
result.add(tr);
return invocationCount.get();
}
Iterator