[testng] 01/02: Import upstream version 6.8.17
Eugene Zhukov
eugene-guest at moszumanska.debian.org
Sat Jan 24 20:21:51 UTC 2015
This is an automated email from the git hooks/post-receive script.
eugene-guest pushed a commit to branch master
in repository testng.
commit 24006fbed5a964515ba0f0dd6e1c05b06af5ba57
Author: Eugene Zhukov <jevgeni.zh at gmail.com>
Date: Fri Jan 23 20:28:59 2015 +0000
Import upstream version 6.8.17
---
CHANGES.txt | 7 +-
README.dev | 16 +-
build.properties | 2 +-
build.xml | 1 +
doc/documentation-main.html | 4 +-
doc/index.html | 4 +-
pom-test.xml | 2 +-
pom.xml | 2 +-
src/main/java/org/testng/Reporter.java | 21 +-
src/main/java/org/testng/TestRunner.java | 2 -
src/main/java/org/testng/collections/Lists.java | 5 +-
src/main/java/org/testng/internal/ClassHelper.java | 22 +-
src/main/java/org/testng/internal/IInvoker.java | 6 +-
src/main/java/org/testng/internal/Invoker.java | 507 +++++++++------------
.../org/testng/internal/MethodGroupsHelper.java | 55 ++-
.../testng/internal/MethodInvocationHelper.java | 28 +-
src/main/java/org/testng/internal/Parameters.java | 52 +--
.../TestMethodWithDataProviderMethodWorker.java | 45 +-
.../java/org/testng/internal/TestMethodWorker.java | 15 +-
.../internal/annotations/JDK15TagFactory.java | 25 +-
.../org/testng/reporters/FileStringBuffer.java | 6 +
.../java/org/testng/reporters/XMLStringBuffer.java | 4 +-
src/main/java/org/testng/xml/XmlSuite.java | 20 +-
src/main/java/org/testng/xml/XmlTest.java | 18 +-
.../test/InvocationAndSuccessPercentageTest.java | 4 +-
.../test/dataprovider/DataProviderWithError.java | 25 +
.../test/dataprovider/FailingDataProviderTest.java | 15 +-
src/test/java/test/testng106/TestNG106.java | 6 +-
src/test/resources/testng-single.xml | 9 +-
29 files changed, 460 insertions(+), 468 deletions(-)
diff --git a/CHANGES.txt b/CHANGES.txt
index 3f18f1d..e1e85ec 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,6 +1,11 @@
Current
-Fixed: GITHUB-376: Some results can be lost (Konstantin Savin)
+6.8.15:
+
+Fixed: OutOfMemoryException while generating reports.
+Fixed: GITHUB-566: Build does not fail when successPercentage for @Test is not met
+Fixed: XmlTest#setGroupInstances was not being shown in toXml().
+Fixed: GITHUB-376: Some results can be lost (Konstantin Savin).
Fixed: Handle relative paths of Suite XML files properly (Nalin Makar)
6.8.5:
diff --git a/README.dev b/README.dev
index a26a7e9..c74f7e5 100644
--- a/README.dev
+++ b/README.dev
@@ -13,12 +13,24 @@ Send the public key:
Configure ~/.m2/settings.xml with Nexus user/password:
+
<settings>
<servers>
<server>
+ <id>sonatype-nexus-snapshots</id>
+ <username>***</username>
+ <password>***</password>
+ </server>
+ <server>
<id>sonatype-nexus-staging</id>
- <username>xxx</username>
- <password>xxx</password>
+ <username>***</username>
+ <password>***</password>
</server>
</servers>
</settings>
+
+Snaphot deploy:
+mvn -Dgpg.passphrase= -Dgpg.keyname=<public_key> deploy
+
+Staging deploy:
+mvn -Dgpg.passphrase= -Dgpg.keyname=<public_key> release:clean release:prepare release:perform
diff --git a/build.properties b/build.properties
index 085a02d..f4309d8 100644
--- a/build.properties
+++ b/build.properties
@@ -2,7 +2,7 @@
# TestNG distribution
#
testng.basename=testng
-testng.version=6.8.8
+testng.version=6.8.14-SNAPSHOT
testng.fullname=${testng.basename}-${testng.version}
#
diff --git a/build.xml b/build.xml
index 63477cc..7f8059c 100644
--- a/build.xml
+++ b/build.xml
@@ -33,6 +33,7 @@
<!-- java greater than 1.5 required to build -->
<condition property="requiredJavaVersion">
<or>
+ <equals arg1="${ant.java.version}" arg2="1.8" />
<equals arg1="${ant.java.version}" arg2="1.7" />
<equals arg1="${ant.java.version}" arg2="1.6" />
</or>
diff --git a/doc/documentation-main.html b/doc/documentation-main.html
index 9a372bf..36a661a 100644
--- a/doc/documentation-main.html
+++ b/doc/documentation-main.html
@@ -1425,9 +1425,9 @@ signOut("uk")
For this ordering, you can use the XML attribute <tt>group-by-instances</tt>. This attribute is valid either on <suite> or <test>:
<pre class="brush: xml">
- <suite name="Factory" order-by-instances="true">
+ <suite name="Factory" group-by-instances="true">
or
- <test name="Factory" order-by-instances="true">
+ <test name="Factory" group-by-instances="true">
</pre>
diff --git a/doc/index.html b/doc/index.html
index 1b07c94..cae6a27 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -42,9 +42,9 @@
<p align="right"><font size="-2"><em>Cédric Beust (cedric at beust.com)<br>
-Current version: 6.8.1<br>
+Current version: 6.8.15<br>
Created: April 27th, 2004<br>
-Last Modified: March 30th, 2013</em></font></p>
+Last Modified: January 14th, 2015</em></font></p>
<p>TestNG is a testing framework inspired from JUnit and NUnit but introducing
diff --git a/pom-test.xml b/pom-test.xml
index d318865..bf83d94 100644
--- a/pom-test.xml
+++ b/pom-test.xml
@@ -72,7 +72,7 @@
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
- <version>6.8.9-SNAPSHOT</version>
+ <version>6.8.13</version>
<scope>test</scope>
</dependency>
</dependencies>
diff --git a/pom.xml b/pom.xml
index ac16a84..7c26d90 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
<artifactId>testng</artifactId>
<packaging>jar</packaging>
<name>TestNG</name>
- <version>6.8.13</version>
+ <version>6.8.17</version>
<description>TestNG is a testing framework.</description>
<url>http://testng.org</url>
diff --git a/src/main/java/org/testng/Reporter.java b/src/main/java/org/testng/Reporter.java
index 01f8f36..b2f30eb 100755
--- a/src/main/java/org/testng/Reporter.java
+++ b/src/main/java/org/testng/Reporter.java
@@ -1,13 +1,13 @@
package org.testng;
-import org.testng.collections.Lists;
-import org.testng.collections.Maps;
-import org.testng.util.Strings;
-
import java.util.List;
import java.util.Map;
import java.util.Vector;
+import org.testng.collections.Lists;
+import org.testng.collections.Maps;
+import org.testng.util.Strings;
+
/**
* This class is used for test methods to log messages that will be
* included in the HTML reports generated by TestNG.
@@ -18,8 +18,8 @@ import java.util.Vector;
* <br>
* The reporter keeps a combined output of strings (in m_output) and also
* a record of which method output which line. In order to do this, callers
- * specify what the current method is with setCurrentMethod() and the
- * Reporter maintaing a mapping of each method with a list of integers.
+ * specify what the current method is with setCurrentTestResult() and the
+ * Reporter maintaing a mapping of each test result with a list of integers.
* These integers are indices in the combined output (avoids duplicating
* the output).
*
@@ -37,7 +37,8 @@ public class Reporter {
*/
private static List<String> m_output = new Vector<String>();
- private static Map<ITestResult, List<Integer>> m_methodOutputMap = Maps.newHashMap();
+ /** The key is the hashCode of the ITestResult */
+ private static Map<Integer, List<Integer>> m_methodOutputMap = Maps.newHashMap();
private static boolean m_escapeHtml = false;
@@ -72,10 +73,10 @@ public class Reporter {
// synchronization needed to ensure the line number and m_output are updated atomically
int n = getOutput().size();
- List<Integer> lines = m_methodOutputMap.get(m);
+ List<Integer> lines = m_methodOutputMap.get(m.hashCode());
if (lines == null) {
lines = Lists.newArrayList();
- m_methodOutputMap.put(m, lines);
+ m_methodOutputMap.put(m.hashCode(), lines);
}
lines.add(n);
getOutput().add(s);
@@ -144,7 +145,7 @@ public class Reporter {
public static synchronized List<String> getOutput(ITestResult tr) {
List<String> result = Lists.newArrayList();
- List<Integer> lines = m_methodOutputMap.get(tr);
+ List<Integer> lines = m_methodOutputMap.get(tr.hashCode());
if (lines != null) {
for (Integer n : lines) {
result.add(getOutput().get(n));
diff --git a/src/main/java/org/testng/TestRunner.java b/src/main/java/org/testng/TestRunner.java
index 1f2936b..49daa5f 100644
--- a/src/main/java/org/testng/TestRunner.java
+++ b/src/main/java/org/testng/TestRunner.java
@@ -899,7 +899,6 @@ public class TestRunner
methodInstances.toArray(new IMethodInstance[methodInstances.size()]),
m_xmlTest.getSuite(),
m_xmlTest.getAllParameters(),
- m_allTestMethods,
m_groupMethods,
m_classMethodMap,
this);
@@ -938,7 +937,6 @@ public class TestRunner
findClasses(methodInstances, c),
m_xmlTest.getSuite(),
params,
- m_allTestMethods,
m_groupMethods,
m_classMethodMap,
this);
diff --git a/src/main/java/org/testng/collections/Lists.java b/src/main/java/org/testng/collections/Lists.java
index a0cba2d..2b5eaec 100755
--- a/src/main/java/org/testng/collections/Lists.java
+++ b/src/main/java/org/testng/collections/Lists.java
@@ -2,6 +2,7 @@ package org.testng.collections;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
public class Lists {
@@ -16,9 +17,7 @@ public class Lists {
public static <K> List<K> newArrayList(K... elements) {
List<K> result = new ArrayList<K>();
- for (K e : elements) {
- result.add(e);
- }
+ Collections.addAll(result, elements);
return result;
}
diff --git a/src/main/java/org/testng/internal/ClassHelper.java b/src/main/java/org/testng/internal/ClassHelper.java
index b919d55..42b4eb4 100644
--- a/src/main/java/org/testng/internal/ClassHelper.java
+++ b/src/main/java/org/testng/internal/ClassHelper.java
@@ -86,9 +86,7 @@ public final class ClassHelper {
allClassLoaders.addAll(m_classLoaders);
}
- int count = 0;
for (ClassLoader classLoader : allClassLoaders) {
- ++count;
if (null == classLoader) {
continue;
}
@@ -133,13 +131,9 @@ public final class ClassHelper {
ConstructorOrMethod result = null;
for (Method method : cls.getMethods()) {
- IFactoryAnnotation f = (IFactoryAnnotation) finder.findAnnotation(method,
- IFactoryAnnotation.class);
+ IFactoryAnnotation f = finder.findAnnotation(method, IFactoryAnnotation.class);
if (null != f) {
- if (result != null) {
- throw new TestNGException(cls.getName() + ": only one @Factory method allowed");
- }
result = new ConstructorOrMethod(method);
result.setEnabled(f.getEnabled());
break;
@@ -323,8 +317,7 @@ public final class ClassHelper {
//
Constructor<?> constructor = findAnnotatedConstructor(finder, declaringClass);
if (null != constructor) {
- IParametersAnnotation annotation = (IParametersAnnotation) finder.findAnnotation(constructor,
- IParametersAnnotation.class);
+ IParametersAnnotation annotation = finder.findAnnotation(constructor, IParametersAnnotation.class);
String[] parameterNames = annotation.getValue();
Object[] parameters = Parameters.createInstantiationParameters(constructor,
@@ -374,12 +367,12 @@ public final class ClassHelper {
parameters = new Object[] { enclosingClassInstance };
} // isStatic
- Constructor<?> ct = null;
+ Constructor<?> ct;
try {
ct = declaringClass.getDeclaredConstructor(parameterTypes);
}
catch (NoSuchMethodException ex) {
- ct = declaringClass.getDeclaredConstructor(new Class[] {String.class});
+ ct = declaringClass.getDeclaredConstructor(String.class);
parameters = new Object[] { "Default test name" };
// If ct == null here, we'll pass a null
// constructor to the factory and hope it can deal with it
@@ -442,8 +435,7 @@ public final class ClassHelper {
Constructor<?>[] constructors = declaringClass.getDeclaredConstructors();
for (Constructor<?> result : constructors) {
- IParametersAnnotation annotation = (IParametersAnnotation)
- finder.findAnnotation(result, IParametersAnnotation.class);
+ IParametersAnnotation annotation = finder.findAnnotation(result, IParametersAnnotation.class);
if (null != annotation) {
String[] parameters = annotation.getValue();
@@ -471,8 +463,8 @@ public final class ClassHelper {
return null;
}
- Constructor<T> ctor = declaringClass.getConstructor(new Class[] { String.class });
- result = ctor.newInstance(new Object[] { "Default test name" });
+ Constructor<T> ctor = declaringClass.getConstructor(String.class);
+ result = ctor.newInstance("Default test name");
}
catch (Exception e) {
String message = e.getMessage();
diff --git a/src/main/java/org/testng/internal/IInvoker.java b/src/main/java/org/testng/internal/IInvoker.java
index b3ad180..98cda2e 100755
--- a/src/main/java/org/testng/internal/IInvoker.java
+++ b/src/main/java/org/testng/internal/IInvoker.java
@@ -37,8 +37,6 @@ public interface IInvoker {
* Invoke the given method
*
* @param testMethod
- * @param allTestMethods The list of all the test methods
- * @param methodIndex The index of testMethod in the allTestMethods array
* @param suite
* @param parameters
* @param groupMethods
@@ -46,12 +44,10 @@ public interface IInvoker {
* @return a list containing the results of the test methods invocations
*/
public List<ITestResult> invokeTestMethods(ITestNGMethod testMethod,
- ITestNGMethod[] allTestMethods,
- int methodIndex,
XmlSuite suite,
Map<String, String> parameters,
ConfigurationGroupMethods groupMethods,
- Object[] instances,
+ Object instance,
ITestContext testContext);
}
diff --git a/src/main/java/org/testng/internal/Invoker.java b/src/main/java/org/testng/internal/Invoker.java
index 6d55292..4b46ac9 100644
--- a/src/main/java/org/testng/internal/Invoker.java
+++ b/src/main/java/org/testng/internal/Invoker.java
@@ -43,6 +43,8 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -171,11 +173,11 @@ public class Invoker implements IInvoker {
IConfigurationAnnotation configurationAnnotation= null;
try {
- Object[] instances= tm.getInstances();
- if (instances == null || instances.length == 0) {
- instances = new Object[] { instance };
+ Object inst = tm.getInstance();
+ if (inst == null) {
+ inst = instance;
}
- Class<?> objectClass= instances[0].getClass();
+ Class<?> objectClass= inst.getClass();
Method method= tm.getMethod();
// Only run the configuration if
@@ -206,11 +208,11 @@ public class Invoker implements IInvoker {
testMethodResult);
testResult.setParameters(parameters);
- Object[] newInstances= (null != instance) ? new Object[] { instance } : instances;
+ Object newInstance = null != instance ? instance: inst;
runConfigurationListeners(testResult, true /* before */);
- invokeConfigurationMethod(newInstances, tm,
+ invokeConfigurationMethod(newInstance, tm,
parameters, isClassConfiguration, isSuiteConfiguration, testResult);
// TODO: probably we should trigger the event for each instance???
@@ -320,13 +322,10 @@ public class Invoker implements IInvoker {
{
Throwable cause= ite.getCause() != null ? ite.getCause() : ite;
- if(SkipException.class.isAssignableFrom(cause.getClass())) {
- SkipException skipEx= (SkipException) cause;
- if(skipEx.isSkip()) {
- testResult.setThrowable(skipEx);
- handleConfigurationSkip(tm, testResult, annotation, currentTestMethod, instance, suite);
- return;
- }
+ if(isSkipExceptionAndSkip(cause)) {
+ testResult.setThrowable(cause);
+ handleConfigurationSkip(tm, testResult, annotation, currentTestMethod, instance, suite);
+ return;
}
Utils.log("", 3, "Failed to invoke configuration method "
+ tm.getRealClass().getName() + "." + tm.getMethodName() + ":" + cause.getMessage());
@@ -501,7 +500,7 @@ public class Invoker implements IInvoker {
* TODO: Should change this method to be more like invokeMethod() so that we can
* handle calls to {@code IInvokedMethodListener} better.
*
- * @param instances the instances to invoke the configuration method on
+ * @param targetInstance the instance to invoke the configuration method on
* @param tm the configuration method
* @param params the parameters needed for method invocation
* @param isClass flag if the configuration method is a class level method // FIXME: this looks like a missusage
@@ -509,7 +508,7 @@ public class Invoker implements IInvoker {
* @throws InvocationTargetException
* @throws IllegalAccessException
*/
- private void invokeConfigurationMethod(Object[] instances,
+ private void invokeConfigurationMethod(Object targetInstance,
ITestNGMethod tm,
Object[] params,
boolean isClass,
@@ -520,15 +519,7 @@ public class Invoker implements IInvoker {
// Mark this method with the current thread id
tm.setId(ThreadUtil.currentThreadInfo());
- // Only a @BeforeMethod/@AfterMethod needs to be run before each instance, all the other
- // configuration methods only need to be run once
- List<Object> actualInstances = Lists.newArrayList();
- if (tm.isBeforeMethodConfiguration() || tm.isAfterMethodConfiguration()) {
- actualInstances.addAll(Arrays.asList(instances));
- } else {
- actualInstances.add(instances[0]);
- }
- for(Object targetInstance : actualInstances) {
+ {
InvokedMethod invokedMethod= new InvokedMethod(targetInstance,
tm,
params,
@@ -544,15 +535,12 @@ public class Invoker implements IInvoker {
Method method = tm.getMethod();
//
- // If this method is a IHookable, invoke its run() method
+ // If this method is a IConfigurable, invoke its run() method
//
IConfigurable configurableInstance =
IConfigurable.class.isAssignableFrom(tm.getMethod().getDeclaringClass()) ?
(IConfigurable) targetInstance : m_configuration.getConfigurable();
if (configurableInstance != null) {
- //
- // If this method is a IConfigurable, invoke its run() method
- //
MethodInvocationHelper.invokeConfigurable(targetInstance, params, configurableInstance, method,
testResult);
}
@@ -572,10 +560,6 @@ public class Invoker implements IInvoker {
}
}
}
- // Only run the method once if it's @BeforeSuite or @AfterSuite
- if (isSuite) {
- break;
- }
}
catch (InvocationTargetException ex) {
throwConfigurationFailure(testResult, ex);
@@ -625,8 +609,7 @@ public class Invoker implements IInvoker {
}
// pass both paramValues and paramIndex to be thread safe in case parallel=true + dataprovider.
- private ITestResult invokeMethod(Object[] instances,
- int instanceIndex,
+ private ITestResult invokeMethod(Object instance,
final ITestNGMethod tm,
Object[] parameterValues,
int parametersIndex,
@@ -635,13 +618,13 @@ public class Invoker implements IInvoker {
ITestClass testClass,
ITestNGMethod[] beforeMethods,
ITestNGMethod[] afterMethods,
- ConfigurationGroupMethods groupMethods) {
+ ConfigurationGroupMethods groupMethods,
+ FailureContext failureContext) {
TestResult testResult = new TestResult();
//
// Invoke beforeGroups configurations
//
- Object instance = instances[instanceIndex];
invokeBeforeGroupsConfigurations(testClass, tm, groupMethods, suite, params,
instance);
@@ -688,11 +671,10 @@ public class Invoker implements IInvoker {
m_notifier.addInvokedMethod(invokedMethod);
- Method thisMethod= tm.getMethod();
+ Method thisMethod = tm.getConstructorOrMethod().getMethod();
if(confInvocationPassed(tm, tm, testClass, instance)) {
- log(3, "Invoking " + thisMethod.getDeclaringClass().getName() + "." +
- thisMethod.getName());
+ log(3, "Invoking " + tm.getRealClass().getName() + "." + tm.getMethodName());
// If no timeOut, just invoke the method
if (MethodHelper.calculateTimeOut(tm) <= 0) {
@@ -701,7 +683,7 @@ public class Invoker implements IInvoker {
// If this method is a IHookable, invoke its run() method
//
IHookable hookableInstance =
- IHookable.class.isAssignableFrom(thisMethod.getDeclaringClass()) ?
+ IHookable.class.isAssignableFrom(tm.getRealClass()) ?
(IHookable) instance : m_configuration.getHookable();
if (hookableInstance != null) {
MethodInvocationHelper.invokeHookable(instance,
@@ -747,12 +729,14 @@ public class Invoker implements IInvoker {
testResult.setStatus(ITestResult.FAILURE);
}
finally {
+ // Set end time ASAP
+ testResult.setEndMillis(System.currentTimeMillis());
+
ExpectedExceptionsHolder expectedExceptionClasses
= MethodHelper.findExpectedExceptions(m_annotationFinder, tm.getMethod());
- List<ITestResult> results = Lists.newArrayList();
- results.add(testResult);
- handleInvocationResults(tm, results, null, 0, expectedExceptionClasses, false,
- false /* collect results */);
+ List<ITestResult> results = Lists.<ITestResult>newArrayList(testResult);
+ handleInvocationResults(tm, results, expectedExceptionClasses, false,
+ false /* collect results */, failureContext);
// If this method has a data provider and just failed, memorize the number
// at which it failed.
@@ -769,14 +753,13 @@ public class Invoker implements IInvoker {
//
tm.incrementCurrentInvocationCount();
- if (testResult != null) {
- testResult.setEndMillis(System.currentTimeMillis());
- }
-
// Run invokedMethodListeners after updating TestResult
runInvokedMethodListeners(AFTER_INVOCATION, invokedMethod, testResult);
runTestListeners(testResult);
- collectResults(tm, results, testResult);
+ // Do not notify if will retry.
+ if (!results.isEmpty()) {
+ collectResults(tm, Collections.<ITestResult>singleton(testResult));
+ }
//
// Invoke afterMethods only if
@@ -803,21 +786,21 @@ public class Invoker implements IInvoker {
return testResult;
}
- private void collectResults(ITestNGMethod testMethod, List<ITestResult> results, TestResult testResult) {
- for (int i = 0; i < results.size(); i++) {
+ void collectResults(ITestNGMethod testMethod, Collection<ITestResult> results) {
+ for (ITestResult result : results) {
// Collect the results
- int status = results.get(i).getStatus();
+ final int status = result.getStatus();
if(ITestResult.SUCCESS == status) {
- m_notifier.addPassedTest(testMethod, testResult);
+ m_notifier.addPassedTest(testMethod, result);
}
else if(ITestResult.SKIP == status) {
- m_notifier.addSkippedTest(testMethod, testResult);
+ m_notifier.addSkippedTest(testMethod, result);
}
else if(ITestResult.FAILURE == status) {
- m_notifier.addFailedTest(testMethod, testResult);
+ m_notifier.addFailedTest(testMethod, result);
}
else if(ITestResult.SUCCESS_PERCENTAGE_FAILURE == status) {
- m_notifier.addFailedButWithinSuccessPercentageTest(testMethod, testResult);
+ m_notifier.addFailedButWithinSuccessPercentageTest(testMethod, result);
}
else {
assert false : "UNKNOWN STATUS:" + status;
@@ -878,10 +861,10 @@ public class Invoker implements IInvoker {
* </ul>
*
* <p/>
- * This method is also reponsible for invoking @BeforeGroup, @BeforeMethod, @AfterMethod, @AfterGroup
+ * This method is also responsible for invoking @BeforeGroup, @BeforeMethod, @AfterMethod, @AfterGroup
* if it is the case for the passed in @Test method.
*/
- protected List<ITestResult> invokeTestMethod(Object[] instances,
+ protected ITestResult invokeTestMethod(Object instance,
final ITestNGMethod tm,
Object[] parameterValues,
int parametersIndex,
@@ -890,19 +873,16 @@ public class Invoker implements IInvoker {
ITestClass testClass,
ITestNGMethod[] beforeMethods,
ITestNGMethod[] afterMethods,
- ConfigurationGroupMethods groupMethods)
+ ConfigurationGroupMethods groupMethods,
+ FailureContext failureContext)
{
- List<ITestResult> results = Lists.newArrayList();
-
// Mark this method with the current thread id
tm.setId(ThreadUtil.currentThreadInfo());
- for(int i= 0; i < instances.length; i++) {
- results.add(invokeMethod(instances, i, tm, parameterValues, parametersIndex, suite, params,
- testClass, beforeMethods, afterMethods, groupMethods));
- }
+ ITestResult result = invokeMethod(instance, tm, parameterValues, parametersIndex, suite, params,
+ testClass, beforeMethods, afterMethods, groupMethods, failureContext);
- return results;
+ return result;
}
/**
@@ -1018,8 +998,7 @@ public class Invoker implements IInvoker {
return null;
}
- int retryFailed(Object[] instances,
- int instanceIndex,
+ int retryFailed(Object instance,
final ITestNGMethod tm,
XmlSuite suite,
ITestClass testClass,
@@ -1032,37 +1011,34 @@ public class Invoker implements IInvoker {
ITestContext testContext,
Map<String, String> parameters,
int parametersIndex) {
- List<Object> failedInstances;
-
+ final FailureContext failure = new FailureContext();
+ failure.count = failureCount;
do {
- failedInstances = Lists.newArrayList();
Map<String, String> 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.
*/
ParameterBag bag = createParameters(tm, parameters,
- allParameters, null, suite, testContext, null /* fedInstance */, null /* testResult */);
+ allParameters, suite, testContext, null /* fedInstance */);
Object[] parameterValues =
getParametersFromIndex(bag.parameterHolder.parameters, parametersIndex);
- result.add(invokeMethod(instances, instanceIndex, tm, parameterValues,parametersIndex, suite,
- allParameters, testClass, beforeMethods, afterMethods, groupMethods));
- failureCount = handleInvocationResults(tm, result, failedInstances,
- failureCount, expectedExceptionHolder, true, true /* collect results */);
+ result.add(invokeMethod(instance, tm, parameterValues, parametersIndex, suite,
+ allParameters, testClass, beforeMethods, afterMethods, groupMethods, failure));
+ // It's already handled inside 'invokeMethod' but results not collected
+ handleInvocationResults(tm, result, expectedExceptionHolder, true, true/* collect results */, failure);
}
- while (!failedInstances.isEmpty());
- return failureCount;
+ while (!failure.instances.isEmpty());
+ return failure.count;
}
private ParameterBag createParameters(ITestNGMethod testMethod,
Map<String, String> parameters,
Map<String, String> allParameterNames,
- Object[] parameterValues,
XmlSuite suite,
ITestContext testContext,
- Object fedInstance,
- ITestResult testResult)
+ Object fedInstance)
{
Object instance;
if (fedInstance != null) {
@@ -1072,9 +1048,8 @@ public class Invoker implements IInvoker {
instance = testMethod.getInstance();
}
- ParameterBag bag= handleParameters(testMethod,
- instance, allParameterNames, parameters, parameterValues, suite, testContext, fedInstance,
- testResult);
+ ParameterBag bag = handleParameters(testMethod,
+ instance, allParameterNames, parameters, null, suite, testContext, fedInstance, null);
return bag;
}
@@ -1092,101 +1067,84 @@ public class Invoker implements IInvoker {
*
* Note (alex): this method can be refactored to use a SingleTestMethodWorker that
* directly invokes
- * {@link #invokeTestMethod(Object[], ITestNGMethod, Object[], XmlSuite, Map, ITestClass, ITestNGMethod[], ITestNGMethod[], ConfigurationGroupMethods)}
+ * {@link #invokeTestMethod(Object, ITestNGMethod, Object[], int, XmlSuite, Map, ITestClass, ITestNGMethod[], ITestNGMethod[], ConfigurationGroupMethods, FailureContext)}
* and this would simplify the implementation (see how DataTestMethodWorker is used)
*/
@Override
public List<ITestResult> invokeTestMethods(ITestNGMethod testMethod,
- ITestNGMethod[] allTestMethods,
- int testMethodIndex,
XmlSuite suite,
Map<String, String> testParameters,
ConfigurationGroupMethods groupMethods,
- Object[] instances,
+ Object instance,
ITestContext testContext)
{
// Potential bug here if the test method was declared on a parent class
assert null != testMethod.getTestClass()
- : "COULDN'T FIND TESTCLASS FOR " + testMethod.getMethod().getDeclaringClass();
-
- List<ITestResult> result = Lists.newArrayList();
+ : "COULDN'T FIND TESTCLASS FOR " + testMethod.getRealClass();
if (!MethodHelper.isEnabled(testMethod.getMethod(), m_annotationFinder)) {
- /*
- * return if the method is not enabled. No need to do any more calculations
- */
- return result;
+ // return if the method is not enabled. No need to do any more calculations
+ return Collections.emptyList();
}
- ITestClass testClass= testMethod.getTestClass();
- long start = System.currentTimeMillis();
+ // 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
+ final String okToProceed = checkDependencies(testMethod, testContext.getAllTestMethods());
+
+ if (okToProceed != null) {
+ //
+ // Not okToProceed. Test is being skipped
+ //
+ ITestResult result = registerSkippedTestResult(testMethod, null, System.currentTimeMillis(),
+ new Throwable(okToProceed));
+ m_notifier.addSkippedTest(testMethod, result);
+ return Collections.singletonList(result);
+ }
+
+
+ final Map<String, String> parameters =
+ testMethod.findMethodParameters(testContext.getCurrentXmlTest());
+
+ // 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, testContext);
+ }
- // For invocationCount > 1 and threadPoolSize > 1 the method will be invoked on a thread pool
long timeOutInvocationCount = testMethod.getInvocationTimeOut();
//FIXME: Is this correct?
boolean onlyOne = testMethod.getThreadPoolSize() > 1 ||
timeOutInvocationCount > 0;
int invocationCount = onlyOne ? 1 : testMethod.getInvocationCount();
- int failureCount = 0;
ExpectedExceptionsHolder expectedExceptionHolder =
MethodHelper.findExpectedExceptions(m_annotationFinder, testMethod.getMethod());
+ final ITestClass testClass= testMethod.getTestClass();
+ final List<ITestResult> result = Lists.newArrayList();
+ final FailureContext failure = new FailureContext();
+ final ITestNGMethod[] beforeMethods = filterMethods(testClass, testClass.getBeforeTestMethods(), CAN_RUN_FROM_CLASS);
+ final ITestNGMethod[] afterMethods = filterMethods(testClass, testClass.getAfterTestMethods(), CAN_RUN_FROM_CLASS);
while(invocationCount-- > 0) {
- boolean okToProceed = checkDependencies(testMethod, allTestMethods);
-
- if (!okToProceed) {
- //
- // Not okToProceed. Test is being skipped
- //
- ITestResult testResult = new TestResult(testClass, null /* instance */,
- testMethod,
- null /* cause */,
- start,
- System.currentTimeMillis(),
- m_testContext);
- String missingGroup = testMethod.getMissingGroup();
- if (missingGroup != null) {
- testResult.setThrowable(new Throwable("Method " + testMethod
- + " depends on nonexistent group \"" + missingGroup + "\""));
- }
-
- testResult.setStatus(ITestResult.SKIP);
- result.add(testResult);
- m_notifier.addSkippedTest(testMethod, testResult);
- runTestListeners(testResult);
- return result;
- }
-
- //
- // If threadPoolSize specified, run this method in its own pool thread.
- //
- Map<String, String> parameters =
- testMethod.findMethodParameters(testContext.getCurrentXmlTest());
- if (testMethod.getThreadPoolSize() > 1 && testMethod.getInvocationCount() > 1) {
- return invokePooledTestMethods(testMethod, allTestMethods, suite,
- parameters, groupMethods, testContext);
+ if(false) {
+ // Prevent code formatting
}
//
// No threads, regular invocation
//
else {
- ITestNGMethod[] beforeMethods = filterMethods(testClass, testClass.getBeforeTestMethods(),
- CAN_RUN_FROM_CLASS);
- ITestNGMethod[] afterMethods = filterMethods(testClass, testClass.getAfterTestMethods(),
- CAN_RUN_FROM_CLASS);
+ // Used in catch statement
+ long start = System.currentTimeMillis();
Map<String, String> allParameterNames = Maps.newHashMap();
ParameterBag bag = createParameters(testMethod,
- parameters, allParameterNames, null, suite, testContext, instances[0],
- null);
+ parameters, allParameterNames, suite, testContext, instance);
if (bag.hasErrors()) {
- failureCount = handleInvocationResults(testMethod,
- bag.errorResults, null, failureCount, expectedExceptionHolder, true,
- true /* collect results */);
- ITestResult tr = registerSkippedTestResult(testMethod, instances[0], start,
- bag.errorResults.get(0).getThrowable());
+ final ITestResult tr = bag.errorResult;
+ tr.setStatus(ITestResult.SKIP);
+ runTestListeners(tr);
+ m_notifier.addSkippedTest(testMethod, tr);
result.add(tr);
continue;
}
@@ -1205,10 +1163,10 @@ public class Invoker implements IInvoker {
TestMethodWithDataProviderMethodWorker w =
new TestMethodWithDataProviderMethodWorker(this,
testMethod, parametersIndex,
- parameterValues, instances, suite, parameters, testClass,
+ parameterValues, instance, suite, parameters, testClass,
beforeMethods, afterMethods, groupMethods,
expectedExceptionHolder, testContext, m_skipFailedInvocationCounts,
- invocationCount, failureCount, m_notifier);
+ invocationCount, failure.count, m_notifier);
workers.add(w);
// testng387: increment the param index in the bag.
parametersIndex++;
@@ -1228,34 +1186,28 @@ public class Invoker implements IInvoker {
List<ITestResult> tmpResults = Lists.newArrayList();
try {
- tmpResults.addAll(invokeTestMethod(instances,
- testMethod,
- parameterValues,
- parametersIndex,
- suite,
- parameters,
- testClass,
- beforeMethods,
- afterMethods,
- groupMethods));
+ tmpResults.add(invokeTestMethod(instance,
+ testMethod,
+ parameterValues,
+ parametersIndex,
+ suite,
+ parameters,
+ testClass,
+ beforeMethods,
+ afterMethods,
+ groupMethods, failure));
}
finally {
- List<Object> failedInstances = Lists.newArrayList();
-
- failureCount = handleInvocationResults(testMethod, tmpResults,
- failedInstances, failureCount, expectedExceptionHolder, true,
- false /* don't collect results */);
- if (failedInstances.isEmpty()) {
+ if (failure.instances.isEmpty()) {
result.addAll(tmpResults);
} else {
- for (int i = 0; i < failedInstances.size(); i++) {
+ for (Object failedInstance : failure.instances) {
List<ITestResult> retryResults = Lists.newArrayList();
- failureCount =
- retryFailed(failedInstances.toArray(),
- i, testMethod, suite, testClass, beforeMethods,
+ failure.count = retryFailed(
+ failedInstance, testMethod, suite, testClass, beforeMethods,
afterMethods, groupMethods, retryResults,
- failureCount, expectedExceptionHolder,
+ failure.count, expectedExceptionHolder,
testContext, parameters, parametersIndex);
result.addAll(retryResults);
}
@@ -1265,11 +1217,11 @@ public class Invoker implements IInvoker {
// If we have a failure, skip all the
// other invocationCounts
//
- if (failureCount > 0
+ if (failure.count > 0
&& (m_skipFailedInvocationCounts
|| testMethod.skipFailedInvocations())) {
while (invocationCount-- > 0) {
- result.add(registerSkippedTestResult(testMethod, instances[0], start, null));
+ result.add(registerSkippedTestResult(testMethod, instance, System.currentTimeMillis(), null));
}
break;
}
@@ -1281,7 +1233,7 @@ public class Invoker implements IInvoker {
catch (Throwable cause) {
ITestResult r =
new TestResult(testMethod.getTestClass(),
- instances[0],
+ instance,
testMethod,
cause,
start,
@@ -1390,14 +1342,13 @@ public class Invoker implements IInvoker {
testMethod.getMethod(), testContext, testResult),
suite,
m_annotationFinder,
- fedInstance),
- null /* TestResult */);
+ fedInstance));
}
// catch(TestNGException ex) {
// throw ex;
// }
catch(Throwable cause) {
- return new ParameterBag(null /* ParameterHolder */,
+ return new ParameterBag(
new TestResult(
testMethod.getTestClass(),
instance,
@@ -1413,7 +1364,6 @@ public class Invoker implements IInvoker {
* Invokes a method that has a specified threadPoolSize.
*/
private List<ITestResult> invokePooledTestMethods(ITestNGMethod testMethod,
- ITestNGMethod[] allTestMethods,
XmlSuite suite,
Map<String, String> parameters,
ConfigurationGroupMethods groupMethods,
@@ -1436,38 +1386,42 @@ public class Invoker implements IInvoker {
mi,
suite,
parameters,
- allTestMethods,
testContext));
}
return runWorkers(testMethod, workers, testMethod.getThreadPoolSize(), groupMethods, suite, parameters);
}
+ static class FailureContext {
+ int count = 0;
+ List<Object> instances = Lists.newArrayList();
+ }
+
/**
* @param testMethod
* @param result
- * @param failureCount
* @param expectedExceptionsHolder
+ * @param failure
* @return
*/
- int handleInvocationResults(ITestNGMethod testMethod,
- List<ITestResult> result,
- List<Object> failedInstances,
- int failureCount,
- ExpectedExceptionsHolder expectedExceptionsHolder,
- boolean triggerListeners,
- boolean collectResults)
+ void handleInvocationResults(ITestNGMethod testMethod,
+ List<ITestResult> result,
+ ExpectedExceptionsHolder expectedExceptionsHolder,
+ boolean triggerListeners,
+ boolean collectResults,
+ FailureContext failure)
{
//
// Go through all the results and create a TestResult for each of them
//
List<ITestResult> resultsToRetry = Lists.newArrayList();
- for (int i = 0; i < result.size(); i++) {
- ITestResult testResult = result.get(i);
+ for (ITestResult testResult : result) {
Throwable ite= testResult.getThrowable();
int status= testResult.getStatus();
+ boolean handled = false;
+
// Exception thrown?
if (ite != null) {
@@ -1484,24 +1438,18 @@ public class Invoker implements IInvoker {
" but got \"" + ite.getMessage() + "\"", ite));
status= ITestResult.FAILURE;
}
- } else if (SkipException.class.isAssignableFrom(ite.getClass())){
- SkipException skipEx= (SkipException) ite;
- if(skipEx.isSkip()) {
- status = ITestResult.SKIP;
- }
- else {
- handleException(ite, testMethod, testResult, failureCount++);
- status = ITestResult.FAILURE;
- }
- } else if (ite != null && expectedExceptionsHolder != null) {
+ } else if (isSkipExceptionAndSkip(ite)){
+ status = ITestResult.SKIP;
+ } else if (expectedExceptionsHolder != null) {
testResult.setThrowable(
- new TestException("Expected exception "
- + expectedExceptionsHolder.expectedClasses[0].getName()
- + " but got " + ite, ite));
+ new TestException("Expected exception of " +
+ getExpectedExceptionsPluralize(expectedExceptionsHolder)
+ + " but got " + ite, ite));
status= ITestResult.FAILURE;
} else {
- handleException(ite, testMethod, testResult, failureCount++);
- status= testResult.getStatus();
+ handleException(ite, testMethod, testResult, failure.count++);
+ handled = true;
+ status = testResult.getStatus();
}
}
@@ -1511,53 +1459,52 @@ public class Invoker implements IInvoker {
if (classes != null && classes.length > 0) {
testResult.setThrowable(
new TestException("Method " + testMethod + " should have thrown an exception of "
- + expectedExceptionsHolder.expectedClasses[0]));
+ + getExpectedExceptionsPluralize(expectedExceptionsHolder)));
status= ITestResult.FAILURE;
}
}
testResult.setStatus(status);
- boolean retry = false;
+ if (status == ITestResult.FAILURE && !handled) {
+ handleException(ite, testMethod, testResult, failure.count++);
+ status = testResult.getStatus();
+ }
- if (testResult.getStatus() == ITestResult.FAILURE) {
+ if (status == ITestResult.FAILURE) {
IRetryAnalyzer retryAnalyzer = testMethod.getRetryAnalyzer();
- if (retryAnalyzer != null && failedInstances != null) {
- retry = retryAnalyzer.retry(testResult);
- }
-
- if (retry) {
+ if (retryAnalyzer != null && failure.instances != null && retryAnalyzer.retry(testResult)) {
resultsToRetry.add(testResult);
- if (failedInstances != null) {
- failedInstances.add(testResult.getInstance());
- }
+ failure.instances.add(testResult.getInstance());
}
}
if (collectResults) {
// Collect the results
- if(ITestResult.SUCCESS == status) {
- m_notifier.addPassedTest(testMethod, testResult);
- }
- else if(ITestResult.SKIP == status) {
- m_notifier.addSkippedTest(testMethod, testResult);
- }
- else if(ITestResult.FAILURE == status) {
- m_notifier.addFailedTest(testMethod, testResult);
- }
- else if(ITestResult.SUCCESS_PERCENTAGE_FAILURE == status) {
- m_notifier.addFailedButWithinSuccessPercentageTest(testMethod, testResult);
- }
- else {
- assert false : "UNKNOWN STATUS:" + status;
- }
+ collectResults(testMethod, Collections.singleton(testResult));
// if (triggerListeners && status != ITestResult.SUCCESS) {
// runTestListeners(testResult);
// }
}
} // for results
- return removeResultsToRetryFromResult(resultsToRetry, result, failureCount);
+ removeResultsToRetryFromResult(resultsToRetry, result, failure);
+ }
+
+ private String getExpectedExceptionsPluralize(final ExpectedExceptionsHolder holder) {
+ StringBuilder sb = new StringBuilder();
+ if (holder.expectedClasses.length > 1) {
+ sb.append("any of types ");
+ sb.append(Arrays.toString(holder.expectedClasses));
+ } else {
+ sb.append("type ");
+ sb.append(holder.expectedClasses[0]);
+ }
+ return sb.toString();
+ }
+
+ private boolean isSkipExceptionAndSkip(Throwable ite) {
+ return SkipException.class.isAssignableFrom(ite.getClass()) && ((SkipException) ite).isSkip();
}
/**
@@ -1569,23 +1516,19 @@ public class Invoker implements IInvoker {
if (".*".equals(messageRegExp)) {
return true;
} else {
- if (ite.getMessage() == null) {
- return false;
- } else {
- return Pattern.matches(messageRegExp, ite.getMessage());
- }
+ final String message = ite.getMessage();
+ return message != null && Pattern.matches(messageRegExp, message);
}
}
- private int removeResultsToRetryFromResult(List<ITestResult> resultsToRetry,
- List<ITestResult> result, int failureCount) {
+ private void removeResultsToRetryFromResult(List<ITestResult> resultsToRetry,
+ List<ITestResult> result, FailureContext failure) {
if (resultsToRetry != null) {
for (ITestResult res : resultsToRetry) {
result.remove(res);
- failureCount--;
+ failure.count--;
}
}
- return failureCount;
}
/**
@@ -1640,51 +1583,55 @@ public class Invoker implements IInvoker {
* Checks to see of the test method has certain dependencies that prevents
* TestNG from executing it
* @param testMethod test method being checked for
- * @param testClass
- * @return dependencies have been run successfully
+ * @return error message or null if dependencies have been run successfully
*/
- private boolean checkDependencies(ITestNGMethod testMethod,
- ITestNGMethod[] allTestMethods)
+ private String checkDependencies(ITestNGMethod testMethod,
+ ITestNGMethod[] allTestMethods)
{
- boolean result = true;
-
// If this method is marked alwaysRun, no need to check for its dependencies
if (testMethod.isAlwaysRun()) {
- return true;
+ return null;
}
// Any missing group?
if (testMethod.getMissingGroup() != null
- && !testMethod.ignoreMissingDependencies()) {
- return false;
+ && !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
- if (dependsOnGroups(testMethod)) {
- String[] groupsDependedUpon = testMethod.getGroupsDependedUpon();
-
+ final String[] groups = testMethod.getGroupsDependedUpon();
+ if (null != groups && groups.length > 0) {
// Get all the methods that belong to the group depended upon
- for (String element : groupsDependedUpon) {
+ for (String element : groups) {
ITestNGMethod[] methods =
- MethodGroupsHelper.findMethodsThatBelongToGroup(testMethod,
- m_testContext.getAllTestMethods(),
- element);
-
- result = result && haveBeenRunSuccessfully(testMethod, 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 (!haveBeenRunSuccessfully(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 (result && dependsOnMethods(testMethod)) {
+ if (dependsOnMethods(testMethod)) {
ITestNGMethod[] methods =
- MethodHelper.findDependedUponMethods(testMethod, allTestMethods);
+ MethodHelper.findDependedUponMethods(testMethod, allTestMethods);
- result = result && haveBeenRunSuccessfully(testMethod, methods);
+ if (!haveBeenRunSuccessfully(testMethod, methods)) {
+ return "Method " + testMethod + " depends on not successfully finished methods";
+ }
}
- return result;
+ return null;
}
/**
@@ -1693,13 +1640,12 @@ public class Invoker implements IInvoker {
private Set<ITestResult> keepSameInstances(ITestNGMethod method, Set<ITestResult> results) {
Set<ITestResult> result = Sets.newHashSet();
for (ITestResult r : results) {
- for (Object o : method.getInstances()) {
+ final 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().getInstances()[0];
+ ? r.getInstance() : r.getMethod().getInstance();
if (r.getTestClass() != method.getTestClass() || instance == o) result.add(r);
- }
}
return result;
}
@@ -1750,7 +1696,9 @@ public class Invoker implements IInvoker {
ITestNGMethod testMethod,
ITestResult testResult,
int failureCount) {
- testResult.setThrowable(throwable);
+ if (throwable != null) {
+ testResult.setThrowable(throwable);
+ }
int successPercentage= testMethod.getSuccessPercentage();
int invocationCount= testMethod.getInvocationCount();
float numberOfTestsThatCanFail= ((100 - successPercentage) * invocationCount) / 100f;
@@ -1766,13 +1714,13 @@ public class Invoker implements IInvoker {
/**
* @param ite The exception that was just thrown
- * @param expectedExceptions The list of expected exceptions for this
+ * @param exceptionHolder Expected exceptions holder for this
* test method
* @return true if the exception that was just thrown is part of the
* expected exceptions
*/
private boolean isExpectedException(Throwable ite, ExpectedExceptionsHolder exceptionHolder) {
- if (exceptionHolder == null) {
+ if (exceptionHolder == null || exceptionHolder.expectedClasses == null) {
return false;
}
@@ -1834,21 +1782,11 @@ public class Invoker implements IInvoker {
}
/**
- * @return true if this method depends on certain groups.
- */
- private boolean dependsOnGroups(ITestNGMethod tm) {
- String[] groups = tm.getGroupsDependedUpon();
- boolean result = (null != groups) && (groups.length > 0);
- return result;
- }
-
- /**
- * @return true if this method depends on certain groups.
+ * @return true if this method depends on certain methods.
*/
private boolean dependsOnMethods(ITestNGMethod tm) {
String[] methods = tm.getMethodsDependedUpon();
- boolean result = (null != methods) && (methods.length > 0);
- return result;
+ return null != methods && methods.length > 0;
}
private void runConfigurationListeners(ITestResult tr, boolean before) {
@@ -1917,22 +1855,25 @@ public class Invoker implements IInvoker {
}
/**
- * This class holds a {@code ParameterHolder} and in case of an error, a non-null
+ * This class holds a {@code ParameterHolder} or in case of an error, a non-null
* {@code TestResult} containing the cause
*/
private static class ParameterBag {
final ParameterHolder parameterHolder;
- final List<ITestResult> errorResults = Lists.newArrayList();
+ final ITestResult errorResult;
- public ParameterBag(ParameterHolder params, TestResult tr) {
- parameterHolder = params;
- if (tr != null) {
- errorResults.add(tr);
- }
+ public ParameterBag(ParameterHolder parameterHolder) {
+ this.parameterHolder = parameterHolder;
+ this.errorResult = null;
+ }
+
+ public ParameterBag(ITestResult errorResult) {
+ this.parameterHolder = null;
+ this.errorResult = errorResult;
}
public boolean hasErrors() {
- return !errorResults.isEmpty();
+ return errorResult != null;
}
}
diff --git a/src/main/java/org/testng/internal/MethodGroupsHelper.java b/src/main/java/org/testng/internal/MethodGroupsHelper.java
index 11cb668..622a122 100644
--- a/src/main/java/org/testng/internal/MethodGroupsHelper.java
+++ b/src/main/java/org/testng/internal/MethodGroupsHelper.java
@@ -254,34 +254,57 @@ public class MethodGroupsHelper {
ITestNGMethod method,
ITestNGMethod[] methods, String groupRegexp)
{
- boolean foundGroup = false;
- List<ITestNGMethod> vResult = Lists.newArrayList();
- Pattern groupPattern = PATTERN_CACHE.get(groupRegexp);
- if (groupPattern == null) {
- groupPattern = Pattern.compile(groupRegexp);
- PATTERN_CACHE.put(groupRegexp, groupPattern);
+ ITestNGMethod[] found = findMethodsThatBelongToGroup(methods, groupRegexp);
+
+ if (found.length == 0) {
+ method.setMissingGroup(groupRegexp);
}
+
+ return found;
+ }
+
+ /**
+ * @param methods list of methods to search
+ * @param groupRegexp regex representing the group
+ *
+ * @return all the methods that belong to the group specified by the regular
+ * expression groupRegExp. methods[] is the list of all the methods we
+ * are choosing from.
+ */
+ protected static ITestNGMethod[] findMethodsThatBelongToGroup(ITestNGMethod[] methods, String groupRegexp)
+ {
+ List<ITestNGMethod> vResult = Lists.newArrayList();
+ final Pattern pattern = getPattern(groupRegexp);
for (ITestNGMethod tm : methods) {
String[] groups = tm.getGroups();
for (String group : groups) {
- Pair<String, String> cacheKey = Pair.create(groupRegexp, group);
- Boolean match = MATCH_CACHE.get(cacheKey);
- if (match == null) {
- match = groupPattern.matcher(group).matches();
- MATCH_CACHE.put(cacheKey, match);
- }
+ Boolean match = isMatch(pattern, group);
if (match) {
vResult.add(tm);
- foundGroup = true;
}
}
}
- if (!foundGroup) {
- method.setMissingGroup(groupRegexp);
+ return vResult.toArray(new ITestNGMethod[vResult.size()]);
+ }
+
+ private static Boolean isMatch(Pattern pattern, String group) {
+ Pair<String, String> cacheKey = Pair.create(pattern.pattern(), group);
+ Boolean match = MATCH_CACHE.get(cacheKey);
+ if (match == null) {
+ match = pattern.matcher(group).matches();
+ MATCH_CACHE.put(cacheKey, match);
}
+ return match;
+ }
- return vResult.toArray(new ITestNGMethod[vResult.size()]);
+ private static Pattern getPattern(String groupRegexp) {
+ Pattern groupPattern = PATTERN_CACHE.get(groupRegexp);
+ if (groupPattern == null) {
+ groupPattern = Pattern.compile(groupRegexp);
+ PATTERN_CACHE.put(groupRegexp, groupPattern);
+ }
+ return groupPattern;
}
diff --git a/src/main/java/org/testng/internal/MethodInvocationHelper.java b/src/main/java/org/testng/internal/MethodInvocationHelper.java
index 79b92e5..f5821f8 100644
--- a/src/main/java/org/testng/internal/MethodInvocationHelper.java
+++ b/src/main/java/org/testng/internal/MethodInvocationHelper.java
@@ -1,7 +1,9 @@
package org.testng.internal;
+import org.testng.IConfigurable;
import org.testng.IConfigureCallBack;
import org.testng.IHookCallBack;
+import org.testng.IHookable;
import org.testng.ITestContext;
import org.testng.ITestNGMethod;
import org.testng.ITestResult;
@@ -36,7 +38,6 @@ public class MethodInvocationHelper {
protected static Object invokeMethod(Method thisMethod, Object instance, Object[] parameters)
throws InvocationTargetException, IllegalAccessException {
- Object result = null;
Utils.checkInstanceOrStatic(instance, thisMethod);
// TESTNG-326, allow IObjectFactory to load from non-standard classloader
@@ -87,7 +88,7 @@ public class MethodInvocationHelper {
protected static Iterator<Object[]> invokeDataProvider(Object instance, Method dataProvider,
ITestNGMethod method, ITestContext testContext, Object fedInstance,
IAnnotationFinder annotationFinder) {
- Iterator<Object[]> result = null;
+ Iterator<Object[]> result;
final ConstructorOrMethod com = method.getConstructorOrMethod();
// If it returns an Object[][], convert it to an Iterable<Object[]>
@@ -149,7 +150,7 @@ public class MethodInvocationHelper {
method.setParameterInvocationCount(oResult.length);
result = MethodHelper.createArrayIterator(oResult);
} else if (Iterator.class.isAssignableFrom(returnType)) {
- // Already an Iterable<Object[]>, assign it directly
+ // Already an Iterator<Object[]>, assign it directly
result = (Iterator<Object[]>) invokeMethod(dataProvider, instance, parameters);
} else {
throw new TestNGException("Data Provider " + dataProvider + " must return"
@@ -188,9 +189,8 @@ public class MethodInvocationHelper {
* <tt>thisMethod</code> results in an exception
*/
protected static void invokeHookable(final Object testInstance, final Object[] parameters,
- Object hookableInstance, final Method thisMethod, TestResult testResult) throws Throwable {
- Method runMethod = hookableInstance.getClass().getMethod("run",
- new Class[] { IHookCallBack.class, ITestResult.class });
+ final IHookable hookable, final Method thisMethod,
+ final TestResult testResult) throws Throwable {
final Throwable[] error = new Throwable[1];
IHookCallBack callback = new IHookCallBack() {
@@ -209,7 +209,7 @@ public class MethodInvocationHelper {
return parameters;
}
};
- runMethod.invoke(hookableInstance, new Object[] { callback, testResult });
+ hookable.run(callback, testResult);
if (error[0] != null) {
throw error[0];
}
@@ -248,7 +248,7 @@ public class MethodInvocationHelper {
private static void invokeWithTimeoutWithNewExecutor(ITestNGMethod tm, Object instance,
Object[] parameterValues, ITestResult testResult)
throws InterruptedException, ThreadExecutionException {
- IExecutor exec = ThreadUtil.createExecutor(1, tm.getMethod().getName());
+ IExecutor exec = ThreadUtil.createExecutor(1, tm.getMethodName());
InvokeMethodRunnable imr = new InvokeMethodRunnable(tm, instance, parameterValues);
IFutureResult future = exec.submitRunnable(imr);
@@ -265,7 +265,7 @@ public class MethodInvocationHelper {
testResult.setThrowable(exception);
testResult.setStatus(ITestResult.FAILURE);
} else {
- Utils.log("Invoker " + Thread.currentThread().hashCode(), 3, "Method " + tm.getMethod()
+ Utils.log("Invoker " + Thread.currentThread().hashCode(), 3, "Method " + tm.getMethodName()
+ " completed within the time-out " + tm.getTimeOut());
// We don't need the result from the future but invoking get() on it
@@ -279,10 +279,8 @@ public class MethodInvocationHelper {
}
protected static void invokeConfigurable(final Object instance, final Object[] parameters,
- Object configurableInstance, final Method thisMethod, ITestResult testResult)
- throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, Throwable {
- Method runMethod = configurableInstance.getClass().getMethod("run",
- new Class[] { IConfigureCallBack.class, ITestResult.class });
+ final IConfigurable configurableInstance, final Method thisMethod,
+ final ITestResult testResult) throws Throwable {
final Throwable[] error = new Throwable[1];
IConfigureCallBack callback = new IConfigureCallBack() {
@@ -301,10 +299,10 @@ public class MethodInvocationHelper {
return parameters;
}
};
- runMethod.invoke(configurableInstance, new Object[] { callback, testResult });
+ configurableInstance.run(callback, testResult);
if (error[0] != null) {
throw error[0];
}
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/testng/internal/Parameters.java b/src/main/java/org/testng/internal/Parameters.java
index 3708011..4fa7c91 100755
--- a/src/main/java/org/testng/internal/Parameters.java
+++ b/src/main/java/org/testng/internal/Parameters.java
@@ -1,5 +1,15 @@
package org.testng.internal;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
import org.testng.ITestContext;
import org.testng.ITestNGMethod;
import org.testng.ITestResult;
@@ -19,16 +29,6 @@ import org.testng.util.Strings;
import org.testng.xml.XmlSuite;
import org.testng.xml.XmlTest;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
/**
* Methods that bind parameters declared in testng.xml to actual values
* used to invoke methods.
@@ -220,28 +220,28 @@ public class Parameters {
result = value;
}
else if(type == int.class || type == Integer.class) {
- result = Integer.valueOf(Integer.parseInt(value));
+ result = Integer.parseInt(value);
}
else if(type == boolean.class || type == Boolean.class) {
result = Boolean.valueOf(value);
}
else if(type == byte.class || type == Byte.class) {
- result = Byte.valueOf(Byte.parseByte(value));
+ result = Byte.parseByte(value);
}
else if(type == char.class || type == Character.class) {
- result = Character.valueOf(value.charAt(0));
+ result = value.charAt(0);
}
else if(type == double.class || type == Double.class) {
- result = Double.valueOf(Double.parseDouble(value));
+ result = Double.parseDouble(value);
}
else if(type == float.class || type == Float.class) {
- result = Float.valueOf(Float.parseFloat(value));
+ result = Float.parseFloat(value);
}
else if(type == long.class || type == Long.class) {
- result = Long.valueOf(Long.parseLong(value));
+ result = Long.parseLong(value);
}
else if(type == short.class || type == Short.class) {
- result = Short.valueOf(Short.parseShort(value));
+ result = Short.parseShort(value);
}
else if (type.isEnum()) {
result = Enum.valueOf(type, value);
@@ -282,7 +282,7 @@ public class Parameters {
*/
private static IDataProvidable findDataProviderInfo(Class clazz, ConstructorOrMethod m,
IAnnotationFinder finder) {
- IDataProvidable result = null;
+ IDataProvidable result;
if (m.getMethod() != null) {
//
@@ -325,8 +325,7 @@ public class Parameters {
}
for (Method m : ClassHelper.getAvailableMethods(cls)) {
- IDataProviderAnnotation dp = (IDataProviderAnnotation)
- finder.findAnnotation(m, IDataProviderAnnotation.class);
+ IDataProviderAnnotation dp = finder.findAnnotation(m, IDataProviderAnnotation.class);
if (null != dp && name.equals(getDataProviderName(dp, m))) {
if (shouldBeStatic && (m.getModifiers() & Modifier.STATIC) == 0) {
throw new TestNGException("DataProvider should be static: " + m);
@@ -352,11 +351,11 @@ public class Parameters {
{
List<Object> result = Lists.newArrayList();
- Object[] extraParameters = new Object[0];
+ Object[] extraParameters;
//
// Try to find an @Parameters annotation
//
- IParametersAnnotation annotation = (IParametersAnnotation) finder.findAnnotation(m, IParametersAnnotation.class);
+ IParametersAnnotation annotation = finder.findAnnotation(m, IParametersAnnotation.class);
Class<?>[] types = m.getParameterTypes();
if(null != annotation) {
String[] parameterNames = annotation.getValue();
@@ -383,9 +382,7 @@ public class Parameters {
//
// Add the extra parameters we found
//
- for (Object p : extraParameters) {
- result.add(p);
- }
+ Collections.addAll(result, extraParameters);
// If the method declared an Object[] parameter and we have parameter values, inject them
for (int i = 0; i < types.length; i++) {
@@ -413,7 +410,7 @@ public class Parameters {
Object fedInstance)
{
ParameterHolder result;
- Iterator<Object[]> parameters = null;
+ Iterator<Object[]> parameters;
/*
* Do we have a @DataProvider? If yes, then we have several
@@ -462,8 +459,7 @@ public class Parameters {
// Turn it into an Iterable
parameters = MethodHelper.createArrayIterator(allParameterValuesArray);
- result = new ParameterHolder(parameters, ParameterOrigin.ORIGIN_XML,
- dataProviderHolder);
+ result = new ParameterHolder(parameters, ParameterOrigin.ORIGIN_XML, null);
}
return result;
diff --git a/src/main/java/org/testng/internal/TestMethodWithDataProviderMethodWorker.java b/src/main/java/org/testng/internal/TestMethodWithDataProviderMethodWorker.java
index 8ba02f3..96be14a 100755
--- a/src/main/java/org/testng/internal/TestMethodWithDataProviderMethodWorker.java
+++ b/src/main/java/org/testng/internal/TestMethodWithDataProviderMethodWorker.java
@@ -15,7 +15,7 @@ public class TestMethodWithDataProviderMethodWorker implements Callable<List<ITe
private ITestNGMethod m_testMethod;
private Object[] m_parameterValues;
- private Object[] m_instances;
+ private Object m_instance;
private XmlSuite m_xmlSuite;
private Map<String, String> m_parameters;
private ITestClass m_testClass;
@@ -35,7 +35,7 @@ public class TestMethodWithDataProviderMethodWorker implements Callable<List<ITe
public TestMethodWithDataProviderMethodWorker(Invoker invoker, ITestNGMethod testMethod,
int parameterIndex,
- Object[] parameterValues, Object[] instances, XmlSuite suite,
+ Object[] parameterValues, Object instance, XmlSuite suite,
Map<String, String> parameters, ITestClass testClass,
ITestNGMethod[] beforeMethods, ITestNGMethod[] afterMethods,
ConfigurationGroupMethods groupMethods, ExpectedExceptionsHolder expectedExceptionHolder,
@@ -45,7 +45,7 @@ public class TestMethodWithDataProviderMethodWorker implements Callable<List<ITe
m_testMethod = testMethod;
m_parameterIndex = parameterIndex;
m_parameterValues = parameterValues;
- m_instances = instances;
+ m_instance = instance;
m_xmlSuite = suite;
m_parameters = parameters;
m_testClass = testClass;
@@ -69,33 +69,32 @@ public class TestMethodWithDataProviderMethodWorker implements Callable<List<ITe
List<ITestResult> tmpResults = Lists.newArrayList();
long start = System.currentTimeMillis();
+ final Invoker.FailureContext failure = new Invoker.FailureContext();
+ failure.count = m_failureCount;
try {
- tmpResults.addAll(m_invoker.invokeTestMethod(m_instances,
- m_testMethod,
- m_parameterValues,
- m_parameterIndex,
- m_xmlSuite,
- m_parameters,
- m_testClass,
- m_beforeMethods,
- m_afterMethods,
- m_groupMethods));
+ tmpResults.add(m_invoker.invokeTestMethod(m_instance,
+ m_testMethod,
+ m_parameterValues,
+ m_parameterIndex,
+ m_xmlSuite,
+ m_parameters,
+ m_testClass,
+ m_beforeMethods,
+ m_afterMethods,
+ m_groupMethods,
+ failure));
}
finally {
- List<Object> failedInstances = Lists.newArrayList();
-
- m_failureCount = m_invoker.handleInvocationResults(m_testMethod, tmpResults,
- failedInstances, m_failureCount, m_expectedExceptionHolder, true,
- false /* don't collect results */);
- if (failedInstances.isEmpty()) {
+ m_failureCount = failure.count;
+ if (failure.instances.isEmpty()) {
m_testResults.addAll(tmpResults);
} else {
- for (int i = 0; i < failedInstances.size(); i++) {
+ for (Object instance : failure.instances) {
List<ITestResult> retryResults = Lists.newArrayList();
m_failureCount =
- m_invoker.retryFailed(failedInstances.toArray(),
- i, m_testMethod, m_xmlSuite, m_testClass, m_beforeMethods,
+ m_invoker.retryFailed(
+ instance, m_testMethod, m_xmlSuite, m_testClass, m_beforeMethods,
m_afterMethods, m_groupMethods, retryResults,
m_failureCount, m_expectedExceptionHolder,
m_testContext, m_parameters, m_parameterIndex);
@@ -118,7 +117,7 @@ public class TestMethodWithDataProviderMethodWorker implements Callable<List<ITe
while (m_invocationCount-- > 0) {
ITestResult r =
new TestResult(m_testMethod.getTestClass(),
- m_instances[0],
+ m_instance,
m_testMethod,
null,
start,
diff --git a/src/main/java/org/testng/internal/TestMethodWorker.java b/src/main/java/org/testng/internal/TestMethodWorker.java
index d251264..cb93beb 100644
--- a/src/main/java/org/testng/internal/TestMethodWorker.java
+++ b/src/main/java/org/testng/internal/TestMethodWorker.java
@@ -36,7 +36,6 @@ public class TestMethodWorker implements IWorker<ITestNGMethod> {
private final IInvoker m_invoker;
private final Map<String, String> m_parameters;
private final XmlSuite m_suite;
- private final ITestNGMethod[] m_allTestMethods;
private List<ITestResult> m_testResults = Lists.newArrayList();
private final ConfigurationGroupMethods m_groupMethods;
private final ClassMethodMap m_classMethodMap;
@@ -46,7 +45,6 @@ public class TestMethodWorker implements IWorker<ITestNGMethod> {
IMethodInstance[] testMethods,
XmlSuite suite,
Map<String, String> parameters,
- ITestNGMethod[] allTestMethods,
ConfigurationGroupMethods groupMethods,
ClassMethodMap classMethodMap,
ITestContext testContext)
@@ -55,7 +53,6 @@ public class TestMethodWorker implements IWorker<ITestNGMethod> {
m_methodInstances = testMethods;
m_suite = suite;
m_parameters = parameters;
- m_allTestMethods = allTestMethods;
m_groupMethods = groupMethods;
m_classMethodMap = classMethodMap;
m_testContext = testContext;
@@ -108,7 +105,7 @@ public class TestMethodWorker implements IWorker<ITestNGMethod> {
// Invoke test method
try {
- invokeTestMethods(testMethod, testMthdInst.getInstances(), m_testContext);
+ invokeTestMethods(testMethod, testMthdInst.getInstance(), m_testContext);
}
finally {
invokeAfterClassMethods(testClass, testMthdInst);
@@ -116,7 +113,7 @@ public class TestMethodWorker implements IWorker<ITestNGMethod> {
}
}
- protected void invokeTestMethods(ITestNGMethod tm, Object[] instances,
+ protected void invokeTestMethods(ITestNGMethod tm, Object instance,
ITestContext testContext)
{
// Potential bug here: we look up the method index of tm among all
@@ -126,12 +123,10 @@ public class TestMethodWorker implements IWorker<ITestNGMethod> {
// more efficient)
List<ITestResult> testResults =
m_invoker.invokeTestMethods(tm,
- m_allTestMethods,
- indexOf(tm, m_allTestMethods),
m_suite,
m_parameters,
m_groupMethods,
- instances,
+ instance,
testContext);
if (testResults != null) {
@@ -288,16 +283,14 @@ class SingleTestMethodWorker extends TestMethodWorker {
MethodInstance testMethod,
XmlSuite suite,
Map<String, String> parameters,
- ITestNGMethod[] allTestMethods,
ITestContext testContext)
{
super(invoker,
new MethodInstance[] {testMethod},
suite,
parameters,
- allTestMethods,
EMPTY_GROUP_METHODS,
null,
testContext);
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/testng/internal/annotations/JDK15TagFactory.java b/src/main/java/org/testng/internal/annotations/JDK15TagFactory.java
index 2773460..5d4e6b3 100755
--- a/src/main/java/org/testng/internal/annotations/JDK15TagFactory.java
+++ b/src/main/java/org/testng/internal/annotations/JDK15TagFactory.java
@@ -2,7 +2,9 @@ package org.testng.internal.annotations;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
-import java.util.Map;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
import org.testng.IAnnotationTransformer;
import org.testng.TestNGException;
@@ -31,7 +33,7 @@ import org.testng.annotations.ITestAnnotation;
import org.testng.annotations.Listeners;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
-import org.testng.collections.Maps;
+import org.testng.collections.Lists;
import org.testng.internal.Utils;
/**
@@ -417,15 +419,15 @@ public class JDK15TagFactory {
}
private String[] join(String[] strings, String[] strings2) {
- Map<String, String> vResult = Maps.newHashMap();
- for (String s : strings) {
- vResult.put(s, s);
- }
+ List<String> result = Lists.newArrayList(strings);
+ Set<String> seen = new HashSet<String>(Lists.newArrayList(strings));
for (String s : strings2) {
- vResult.put(s, s);
+ if (! seen.contains(s)) {
+ result.add(s);
+ }
}
- return vResult.keySet().toArray(new String[vResult.size()]);
+ return result.toArray(new String[result.size()]);
}
/**
@@ -494,21 +496,20 @@ public class JDK15TagFactory {
return new String[0];
}
- Map<String, String> vResult = Maps.newHashMap();
+ List<String> result = Lists.newArrayList();
while (cls != null && cls != Object.class) {
Annotation annotation = cls.getAnnotation(annotationClass);
if (annotation != null) {
String[] g = (String[]) invokeMethod(annotation, methodName);
for (String s : g) {
- vResult.put(s, s);
+ result.add(s);
}
}
cls = cls.getSuperclass();
}
- String[] result = vResult.keySet().toArray(new String[vResult.size()]);
- return result;
+ return result.toArray(new String[result.size()]);
}
private Object invokeMethod(Annotation test, String methodName) {
diff --git a/src/main/java/org/testng/reporters/FileStringBuffer.java b/src/main/java/org/testng/reporters/FileStringBuffer.java
index 80e774e..af2e98b 100644
--- a/src/main/java/org/testng/reporters/FileStringBuffer.java
+++ b/src/main/java/org/testng/reporters/FileStringBuffer.java
@@ -43,6 +43,9 @@ public class FileStringBuffer implements IBuffer {
@Override
public FileStringBuffer append(CharSequence s) {
+ if (s == null) {
+ throw new IllegalArgumentException("CharSequence (Argument 0 of FileStringBuffer#append) should not be null");
+ }
// m_sb.append(s);
if (m_sb.length() > m_maxCharacters) {
flushToFile();
@@ -64,6 +67,9 @@ public class FileStringBuffer implements IBuffer {
@Override
public void toWriter(Writer fw) {
+ if (fw == null) {
+ throw new IllegalArgumentException("Writer (Argument 0 of FileStringBuffer#toWriter) should not be null");
+ }
try {
BufferedWriter bw = new BufferedWriter(fw);
if (m_file == null) {
diff --git a/src/main/java/org/testng/reporters/XMLStringBuffer.java b/src/main/java/org/testng/reporters/XMLStringBuffer.java
index 092c10e..84046b4 100755
--- a/src/main/java/org/testng/reporters/XMLStringBuffer.java
+++ b/src/main/java/org/testng/reporters/XMLStringBuffer.java
@@ -14,8 +14,8 @@ import java.util.regex.Pattern;
* @author <a href="mailto:cedric at beust.com">Cedric Beust</a> Jul 21, 2003
*/
public class XMLStringBuffer {
- /** End of line */
- private static final String EOL = System.getProperty("line.separator");
+ /** End of line, value of 'line.separator' system property or '\n' */
+ private static final String EOL = System.getProperty("line.separator", "\n");
/** Tab space indent for XML document */
private static final String DEFAULT_INDENT_INCREMENT = " ";
diff --git a/src/main/java/org/testng/xml/XmlSuite.java b/src/main/java/org/testng/xml/XmlSuite.java
index 61612eb..bdcc3e5 100755
--- a/src/main/java/org/testng/xml/XmlSuite.java
+++ b/src/main/java/org/testng/xml/XmlSuite.java
@@ -1,7 +1,12 @@
package org.testng.xml;
-import static org.testng.collections.CollectionUtils.hasElements;
-import static org.testng.internal.Utils.isStringNotEmpty;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
import org.testng.ITestObjectFactory;
import org.testng.TestNG;
@@ -12,13 +17,8 @@ import org.testng.xml.dom.OnElement;
import org.testng.xml.dom.OnElementList;
import org.testng.xml.dom.Tag;
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
+import static org.testng.collections.CollectionUtils.hasElements;
+import static org.testng.internal.Utils.isStringNotEmpty;
/**
* This class describes the tag <suite> in testng.xml.
@@ -439,6 +439,8 @@ public class XmlSuite implements Serializable, Cloneable {
if(isStringNotEmpty(parallel) && !DEFAULT_PARALLEL.equals(parallel)) {
p.setProperty("parallel", parallel);
}
+ XmlUtils.setProperty(p, "group-by-instances", String.valueOf(getGroupByInstances()),
+ DEFAULT_GROUP_BY_INSTANCES.toString());
XmlUtils.setProperty(p, "configfailurepolicy", getConfigFailurePolicy(),
DEFAULT_CONFIG_FAILURE_POLICY);
XmlUtils.setProperty(p, "thread-count", String.valueOf(getThreadCount()),
diff --git a/src/main/java/org/testng/xml/XmlTest.java b/src/main/java/org/testng/xml/XmlTest.java
index 06abec1..cbc8c12 100755
--- a/src/main/java/org/testng/xml/XmlTest.java
+++ b/src/main/java/org/testng/xml/XmlTest.java
@@ -1,12 +1,5 @@
package org.testng.xml;
-import org.testng.TestNG;
-import org.testng.TestNGException;
-import org.testng.collections.Lists;
-import org.testng.collections.Maps;
-import org.testng.reporters.XMLStringBuffer;
-import org.testng.xml.dom.ParentSetter;
-
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@@ -14,6 +7,13 @@ import java.util.Map;
import java.util.Properties;
import java.util.UUID;
+import org.testng.TestNG;
+import org.testng.TestNGException;
+import org.testng.collections.Lists;
+import org.testng.collections.Maps;
+import org.testng.reporters.XMLStringBuffer;
+import org.testng.xml.dom.ParentSetter;
+
/**
* This class describes the tag <test> in testng.xml.
*
@@ -477,6 +477,10 @@ public class XmlTest implements Serializable, Cloneable {
if (m_threadCount != -1) {
p.setProperty("thread-count", Integer.toString(m_threadCount));
}
+ if (m_groupByInstances != null) {
+ XmlUtils.setProperty(p, "group-by-instances", String.valueOf(getGroupByInstances()),
+ XmlSuite.DEFAULT_GROUP_BY_INSTANCES.toString());
+ }
xsb.push("test", p);
diff --git a/src/test/java/test/InvocationAndSuccessPercentageTest.java b/src/test/java/test/InvocationAndSuccessPercentageTest.java
index ec0254f..56f4434 100644
--- a/src/test/java/test/InvocationAndSuccessPercentageTest.java
+++ b/src/test/java/test/InvocationAndSuccessPercentageTest.java
@@ -67,9 +67,9 @@ public class InvocationAndSuccessPercentageTest extends BaseTest {
* 1 failed but within success percentage
* 1 failed
*/
- @Test(enabled = false)
+ @Test
public void successPercentageThatFails() {
- addClass("test.sample.InvocationCountTest");
+ addClass(test.sample.InvocationCountTest.class);
addIncludedGroup("successPercentageThatFailsOnly");
run();
String[] passed = {
diff --git a/src/test/java/test/dataprovider/DataProviderWithError.java b/src/test/java/test/dataprovider/DataProviderWithError.java
new file mode 100644
index 0000000..a7b8c7f
--- /dev/null
+++ b/src/test/java/test/dataprovider/DataProviderWithError.java
@@ -0,0 +1,25 @@
+package test.dataprovider;
+
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * @author Vladislav.Rassokhin
+ */
+public class DataProviderWithError {
+ @Test(dataProvider = "Data", invocationCount = 2)
+ public void testShouldSkip() throws Exception {
+ Assert.fail();
+ }
+
+ @Test(dataProvider = "Data", invocationCount = 2, successPercentage = 10)
+ public void testShouldSkipEvenIfSuccessPercentage() throws Exception {
+ Assert.fail();
+ }
+
+ @DataProvider(name = "Data")
+ public static Object[][] Data() {
+ throw new RuntimeException("Fail");
+ }
+}
diff --git a/src/test/java/test/dataprovider/FailingDataProviderTest.java b/src/test/java/test/dataprovider/FailingDataProviderTest.java
index fff2564..ee31493 100644
--- a/src/test/java/test/dataprovider/FailingDataProviderTest.java
+++ b/src/test/java/test/dataprovider/FailingDataProviderTest.java
@@ -3,27 +3,32 @@ package test.dataprovider;
import org.testng.Assert;
import org.testng.TestListenerAdapter;
import org.testng.TestNG;
-import org.testng.TestNGException;
import org.testng.annotations.Test;
import test.SimpleBaseTest;
public class FailingDataProviderTest extends SimpleBaseTest {
- private void shouldSkipOne(Class cls, String message) {
+ private void shouldSkip(Class cls, String message, int expected) {
TestNG testng = create(cls);
TestListenerAdapter tla = new TestListenerAdapter();
testng.addListener(tla);
testng.run();
- Assert.assertEquals(tla.getSkippedTests().size(), 1, message);
+ Assert.assertEquals(tla.getSkippedTests().size(), expected, message);
}
@Test(description = "TESTNG-142: Exceptions in DataProvider are not reported as failed test")
public void failingDataProvider() {
- shouldSkipOne(FailingDataProvider.class, "Test method should be marked as skipped");
+ shouldSkip(FailingDataProvider.class, "Test method should be marked as skipped", 1);
}
@Test(description = "TESTNG-447: Abort when two data providers have the same name")
public void duplicateDataProviders() {
- shouldSkipOne(DuplicateDataProviderSampleTest.class, "");
+ shouldSkip(DuplicateDataProviderSampleTest.class, "", 1);
+ }
+
+ @Test
+ public void failingDataProviderAndInvocationCount() throws Exception {
+ shouldSkip(DataProviderWithError.class,
+ "Test should be skipped even if invocation counter and success percentage set", 4);
}
}
diff --git a/src/test/java/test/testng106/TestNG106.java b/src/test/java/test/testng106/TestNG106.java
index 92c883f..171463a 100644
--- a/src/test/java/test/testng106/TestNG106.java
+++ b/src/test/java/test/testng106/TestNG106.java
@@ -1,12 +1,13 @@
package test.testng106;
+import java.util.Arrays;
+
import org.testng.Assert;
import org.testng.TestNG;
import org.testng.annotations.Test;
import org.testng.xml.XmlSuite;
-import test.SimpleBaseTest;
-import java.util.Arrays;
+import test.SimpleBaseTest;
public class TestNG106 extends SimpleBaseTest {
@Test
@@ -18,7 +19,6 @@ public class TestNG106 extends SimpleBaseTest {
createXmlTest(s, "myTest3", Test2.class.getName());
createXmlTest(s, "myTest-last", Test2.class.getName());
tng.setXmlSuites(Arrays.asList(s));
- tng.setVerbose(3);
tng.run();
Assert.assertEquals(FailingSuiteFixture.s_invocations, 0, "@BeforeSuite has failed. All tests should be skipped.");
}
diff --git a/src/test/resources/testng-single.xml b/src/test/resources/testng-single.xml
index 6898468..d144918 100644
--- a/src/test/resources/testng-single.xml
+++ b/src/test/resources/testng-single.xml
@@ -9,16 +9,11 @@
<parameter name="string" value="s"/>
<groups>
- <dependencies>
- <group name="c" depends-on="a b" />
- <group name="z" depends-on="c" />
- </dependencies>
</groups>
<classes>
- <class name="test.tmp.A">
- </class>
- </classes>
+ <class name="test.mannotation.MAnnotationSampleTest" />
+ </classes>
</test>
</suite>
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/testng.git
More information about the pkg-java-commits
mailing list