blob: b49925c1e56e5d21389ebffb6851ca4d81e17d8d [file] [log] [blame]
package org.testng;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import org.testng.internal.ClassHelper;
import org.testng.internal.ConfigurationGroupMethods;
import org.testng.internal.Constants;
import org.testng.internal.IConfigurationListener;
import org.testng.internal.IInvoker;
import org.testng.internal.IMethodWorker;
import org.testng.internal.ITestResultNotifier;
import org.testng.internal.InvokedMethod;
import org.testng.internal.Invoker;
import org.testng.internal.MethodHelper;
import org.testng.internal.MethodInstance;
import org.testng.internal.ResultMap;
import org.testng.internal.RunInfo;
import org.testng.internal.TestMethodWorker;
import org.testng.internal.TestNGClassFinder;
import org.testng.internal.TestNGMethod;
import org.testng.internal.TestNGMethodFinder;
import org.testng.internal.Utils;
import org.testng.internal.XmlMethodSelector;
import org.testng.internal.annotations.IAnnotationFinder;
import org.testng.internal.thread.ThreadUtil;
import org.testng.junit.IJUnitTestRunner;
import org.testng.xml.XmlClass;
import org.testng.xml.XmlPackage;
import org.testng.xml.XmlSuite;
import org.testng.xml.XmlTest;
/**
* This class takes care of running one Test.
*
* @author Cedric Beust, Apr 26, 2004
* @author <a href = "mailto:the_mindstorm&#64;evolva.ro">Alexandru Popescu</a>
*/
public class TestRunner implements ITestContext, ITestResultNotifier {
/* generated */
private static final long serialVersionUID = 4247820024988306670L;
private ISuite m_suite;
protected XmlTest m_xmlTest;
private String m_testName;
private boolean m_debug = false;
transient private List<XmlClass> m_testClassesFromXml= null;
transient private List<XmlPackage> m_packageNamesFromXml= null;
transient private IInvoker m_invoker= null;
transient private IAnnotationFinder m_annotationFinder= null;
/** ITestListeners support. */
transient private List<ITestListener> m_testListeners = new ArrayList<ITestListener>();
transient private List<IConfigurationListener> m_configurationListeners= new ArrayList<IConfigurationListener>();
private IConfigurationListener m_confListener= new ConfigurationListener();
/**
* All the test methods we found, associated with their respective classes.
* Note that these test methods might belong to different classes.
* We pick which ones to run at runtime.
*/
private ITestNGMethod[] m_allTestMethods = new ITestNGMethod[0];
// Information about this test run
private Date m_startDate = null;
private Date m_endDate = null;
/** A map to keep track of Class <-> IClass. */
transient private Map<Class, ITestClass> m_classMap= new HashMap<Class, ITestClass>();
/** Where the reports will be created. */
private String m_outputDirectory= Constants.getDefaultValueFor(Constants.PROP_OUTPUT_DIR);
// The XML method selector (groups/methods included/excluded in XML)
private XmlMethodSelector m_xmlMethodSelector = new XmlMethodSelector();
private static int m_verbose = 1;
//
// These next fields contain all the configuration methods found on this class.
// At initialization time, they just contain all the various @Configuration methods
// found in all the classes we are going to run. When comes the time to run them,
// only a subset of them are run: those that are enabled and belong on the same class as
// (or a parent of) the test class.
//
private ITestNGMethod[] m_beforeClassMethods = {};
private ITestNGMethod[] m_afterClassMethods = {};
/** */
private ITestNGMethod[] m_beforeSuiteMethods = {};
private ITestNGMethod[] m_afterSuiteMethods = {};
private ITestNGMethod[] m_beforeXmlTestMethods = {};
private ITestNGMethod[] m_afterXmlTestMethods = {};
private List<ITestNGMethod> m_excludedMethods = new ArrayList<ITestNGMethod>();
private ConfigurationGroupMethods m_groupMethods = null;
// Meta groups
private Map<String, List<String>> m_metaGroups = new HashMap<String, List<String>>();
// All the tests that were run along with their result
private IResultMap m_passedTests = new ResultMap();
private IResultMap m_failedTests = new ResultMap();
private IResultMap m_failedButWithinSuccessPercentageTests = new ResultMap();
private IResultMap m_skippedTests = new ResultMap();
private RunInfo m_runInfo= new RunInfo();
// The host where this test was run, or null if run locally
private String m_host;
private Map<String, Object> m_attributes = new HashMap<String, Object>();
public TestRunner(ISuite suite,
XmlTest test,
String outputDirectory,
IAnnotationFinder finder)
{
init(suite, test, outputDirectory, finder);
}
public TestRunner(ISuite suite, XmlTest test, IAnnotationFinder finder)
{
init(suite, test, suite.getOutputDirectory(), finder);
}
public TestRunner(ISuite suite, XmlTest test) {
init(suite, test, suite.getOutputDirectory(),
suite.getAnnotationFinder(test.getAnnotations()));
}
private void init(ISuite suite,
XmlTest test,
String outputDirectory,
IAnnotationFinder annotationFinder)
{
m_xmlTest= test;
m_suite = suite;
m_testName = test.getName();
m_host = suite.getHost();
m_testClassesFromXml= test.getXmlClasses();
m_packageNamesFromXml= test.getXmlPackages();
if(null != m_packageNamesFromXml) {
for(XmlPackage xp: m_packageNamesFromXml) {
m_testClassesFromXml.addAll(xp.getXmlClasses());
}
}
m_annotationFinder= annotationFinder;
m_invoker= new Invoker(this, this, m_suite.getSuiteState(), m_annotationFinder);
setVerbose(test.getVerbose());
if (suite.getParallel() != null) {
log(3, "Running the tests in '" + test.getName() + "' with parallel mode:" + suite.getParallel());
}
setOutputDirectory(outputDirectory);
// Finish our initialization
init();
}
public IInvoker getInvoker() {
return m_invoker;
}
public ITestNGMethod[] getBeforeSuiteMethods() {
return m_beforeSuiteMethods;
}
public ITestNGMethod[] getAfterSuiteMethods() {
return m_afterSuiteMethods;
}
public ITestNGMethod[] getBeforeTestConfigurationMethods() {
return m_beforeXmlTestMethods;
}
public ITestNGMethod[] getAfterTestConfigurationMethods() {
return m_afterXmlTestMethods;
}
public Object getAttribute(String name) {
return m_attributes.get(name);
}
public void setAttribute(String name, Object value) {
m_attributes.put(name, value);
}
private void init() {
initMetaGroups(m_xmlTest);
initRunInfo(m_xmlTest);
// Init methods and class map
// JUnit behavior is different and doesn't need this initialization step
if(!m_xmlTest.isJUnit()) {
initMethods();
}
addConfigurationListener(m_confListener);
}
/**
* Initialize meta groups
*/
private void initMetaGroups(XmlTest xmlTest) {
Map<String, List<String>> metaGroups = xmlTest.getMetaGroups();
for (String name : metaGroups.keySet()) {
addMetaGroup(name, metaGroups.get(name));
}
}
private void initRunInfo(final XmlTest xmlTest) {
// Groups
m_xmlMethodSelector.setIncludedGroups(createGroups(m_xmlTest.getIncludedGroups()));
m_xmlMethodSelector.setExcludedGroups(createGroups(m_xmlTest.getExcludedGroups()));
m_xmlMethodSelector.setExpression(m_xmlTest.getExpression());
// Methods
m_xmlMethodSelector.setXmlClasses(m_xmlTest.getXmlClasses());
m_runInfo.addMethodSelector(m_xmlMethodSelector, 10);
// Add user-specified method selectors (only class selectors, we can ignore
// script selectors here)
if (null != xmlTest.getMethodSelectors()) {
for (org.testng.xml.XmlMethodSelector selector : xmlTest.getMethodSelectors()) {
if (selector.getClassName() != null) {
IMethodSelector s = ClassHelper.createSelector(selector);
m_runInfo.addMethodSelector(s, selector.getPriority());
}
}
}
}
private void initMethods() {
//
// Calculate all the methods we need to invoke
//
List<ITestNGMethod> beforeClassMethods = new ArrayList<ITestNGMethod>();
List<ITestNGMethod> testMethods = new ArrayList<ITestNGMethod>();
List<ITestNGMethod> afterClassMethods = new ArrayList<ITestNGMethod>();
List<ITestNGMethod> beforeSuiteMethods = new ArrayList<ITestNGMethod>();
List<ITestNGMethod> afterSuiteMethods = new ArrayList<ITestNGMethod>();
List<ITestNGMethod> beforeXmlTestMethods = new ArrayList<ITestNGMethod>();
List<ITestNGMethod> afterXmlTestMethods = new ArrayList<ITestNGMethod>();
ITestClassFinder testClassFinder= new TestNGClassFinder(Utils.xmlClassesToClasses(m_testClassesFromXml),
null,
m_xmlTest,
m_annotationFinder,
this);
ITestMethodFinder testMethodFinder
= new TestNGMethodFinder(m_runInfo, m_annotationFinder);
m_runInfo.setTestMethods(testMethods);
//
// Initialize TestClasses
//
IClass[] classes = testClassFinder.findTestClasses();
for (IClass ic : classes) {
// Create TestClass
ITestClass tc = new TestClass(ic,
m_testName,
testMethodFinder,
m_annotationFinder,
m_runInfo);
m_classMap.put(ic.getRealClass(), tc);
}
//
// Calculate groups methods
//
Map<String, List<ITestNGMethod>> beforeGroupMethods= MethodHelper.findGroupsMethods(m_classMap.values(), true);
Map<String, List<ITestNGMethod>> afterGroupMethods= MethodHelper.findGroupsMethods(m_classMap.values(), false);
//
// Walk through all the TestClasses, store their method
// and initialize them with the correct ITestClass
//
for (ITestClass tc : m_classMap.values()) {
fixMethodsWithClass(tc.getBeforeClassMethods(), tc, beforeClassMethods);
fixMethodsWithClass(tc.getBeforeTestMethods(), tc, null); // HINT: does not link back to beforeTestMethods
fixMethodsWithClass(tc.getTestMethods(), tc, testMethods);
fixMethodsWithClass(tc.getAfterTestMethods(), tc, null);
fixMethodsWithClass(tc.getAfterClassMethods(), tc, afterClassMethods);
fixMethodsWithClass(tc.getBeforeSuiteMethods(), tc, beforeSuiteMethods);
fixMethodsWithClass(tc.getAfterSuiteMethods(), tc, afterSuiteMethods);
fixMethodsWithClass(tc.getBeforeTestConfigurationMethods(), tc, beforeXmlTestMethods);
fixMethodsWithClass(tc.getAfterTestConfigurationMethods(), tc, afterXmlTestMethods);
fixMethodsWithClass(tc.getBeforeGroupsMethods(), tc,
MethodHelper.uniqueMethodList(beforeGroupMethods.values()));
fixMethodsWithClass(tc.getAfterGroupsMethods(), tc,
MethodHelper.uniqueMethodList(afterGroupMethods.values()));
}
//
// Sort the methods
//
m_beforeSuiteMethods = MethodHelper.collectAndOrderMethods(beforeSuiteMethods,
false,
m_runInfo,
m_annotationFinder,
true /* unique */,
m_excludedMethods);
m_beforeXmlTestMethods = MethodHelper.collectAndOrderMethods(beforeXmlTestMethods,
false,
m_runInfo,
m_annotationFinder,
true, // CQ added by me
m_excludedMethods);
m_beforeClassMethods = MethodHelper.collectAndOrderMethods(beforeClassMethods,
false,
m_runInfo,
m_annotationFinder,
m_excludedMethods);
m_allTestMethods = MethodHelper.collectAndOrderMethods(testMethods,
true,
m_runInfo,
m_annotationFinder,
m_excludedMethods);
m_afterClassMethods = MethodHelper.collectAndOrderMethods(afterClassMethods,
false,
m_runInfo,
m_annotationFinder,
m_excludedMethods);
m_afterXmlTestMethods = MethodHelper.collectAndOrderMethods(afterXmlTestMethods,
false,
m_runInfo,
m_annotationFinder,
true, // CQ added by me
m_excludedMethods);
m_afterSuiteMethods = MethodHelper.collectAndOrderMethods(afterSuiteMethods,
false,
m_runInfo,
m_annotationFinder,
true /* unique */,
m_excludedMethods);
// shared group methods
m_groupMethods = new ConfigurationGroupMethods(m_allTestMethods, beforeGroupMethods, afterGroupMethods);
}
private static void ppp(String s) {
if (true) {
System.out.println("[TestRunner] " + s);
}
}
private void fixMethodsWithClass(ITestNGMethod[] methods,
ITestClass testCls,
List<ITestNGMethod> methodList) {
for (ITestNGMethod itm : methods) {
itm.setTestClass(testCls);
if (methodList != null) {
methodList.add(itm);
}
}
}
public Collection<ITestClass> getIClass() {
return m_classMap.values();
}
/**
* FIXME: not used
*/
private IClass findIClass(IClass[] classes, Class cls) {
for (IClass c : classes) {
if (c.getRealClass().equals(cls)) {
return c;
}
}
return null;
}
public void setTestName(String name) {
m_testName = name;
}
public void setOutputDirectory(String od) {
if (od == null) { m_outputDirectory = null; return; } //for maven2
File file = new File(od);
file.mkdirs();
m_outputDirectory= file.getAbsolutePath();
}
private void addMetaGroup(String name, List<String> groupNames) {
m_metaGroups.put(name, groupNames);
}
/**
* Calculate the transitive closure of all the MetaGroups
*
* @param groups
* @param unfinishedGroups
* @param result The transitive closure containing all the groups found
*/
private void collectGroups(String[] groups,
List<String> unfinishedGroups,
Map<String, String> result) {
for (String gn : groups) {
List<String> subGroups = m_metaGroups.get(gn);
if (null != subGroups) {
for (String sg : subGroups) {
if (null == result.get(sg)) {
result.put(sg, sg);
unfinishedGroups.add(sg);
}
}
}
}
}
private Map<String, String> createGroups(List<String> groups) {
return createGroups((String[]) groups.toArray(new String[groups.size()]));
}
private Map<String, String> createGroups(String[] groups) {
Map<String, String> result= new HashMap<String, String>();
// Groups that were passed on the command line
for (String group : groups) {
result.put(group, group);
}
// See if we have any MetaGroups and
// expand them if they match one of the groups
// we have just been passed
List<String> unfinishedGroups = new ArrayList<String>();
if (m_metaGroups.size() > 0) {
collectGroups(groups, unfinishedGroups, result);
// Do we need to loop over unfinished groups?
while (unfinishedGroups.size() > 0) {
String[] uGroups = (String[]) unfinishedGroups.toArray(new String[unfinishedGroups.size()]);
unfinishedGroups = new ArrayList<String>();
collectGroups(uGroups, unfinishedGroups, result);
}
}
// Utils.dumpMap(result);
return result;
}
/**
* The main entry method for TestRunner.
*
* This is where all the hard work is done:
* - Invoke configuration methods
* - Invoke test methods
* - Catch exceptions
* - Collect results
* - Invoke listeners
* - etc...
*/
public void run() {
beforeRun();
try {
XmlTest test= getTest();
if(test.isJUnit()) {
privateRunJUnit(test);
}
else {
privateRun(test);
}
}
finally {
afterRun();
}
}
/** Before run preparements. */
private void beforeRun() {
//
// Log the start date
//
m_startDate = new Date(System.currentTimeMillis());
// Log start
logStart();
// Invoke listeners
fireEvent(true /*start*/);
// invoke @BeforeTest
ITestNGMethod[] testConfigurationMethods= getBeforeTestConfigurationMethods();
if(null != testConfigurationMethods && testConfigurationMethods.length > 0) {
m_invoker.invokeConfigurations(null,
testConfigurationMethods,
m_xmlTest.getSuite(),
m_xmlTest.getParameters(),
null /* instance */);
}
}
private void privateRunJUnit(XmlTest xmlTest) {
final Class[] classes= Utils.xmlClassesToClasses(m_testClassesFromXml);
final List<ITestNGMethod> runMethods= new ArrayList<ITestNGMethod>();
List<IMethodWorker> workers= new ArrayList<IMethodWorker>();
// FIXME: directly referincing JUnitTestRunner which uses JUnit classes
// may result in an class resolution exception under different JVMs
// The resolution process is not specified in the JVM spec with a specific implementation,
// so it can be eager => failure
workers.add(new IMethodWorker() {
/**
* @see org.testng.internal.IMethodWorker#getMaxTimeOut()
*/
public long getMaxTimeOut() {
return 0;
}
public List<ITestResult> getTestResults() {
return null;
}
/**
* @see java.lang.Runnable#run()
*/
public void run() {
for(Class tc: classes) {
IJUnitTestRunner tr= ClassHelper.createTestRunner(TestRunner.this);
try {
tr.run(tc);
}
catch(Exception ex) {
ex.printStackTrace();
}
finally {
runMethods.addAll(tr.getTestMethods());
}
}
}
});
runWorkers(workers, "" /* JUnit does not support parallel */);
m_allTestMethods= runMethods.toArray(new ITestNGMethod[runMethods.size()]);
}
public void privateRun(XmlTest xmlTest) {
Map<String, String> params = xmlTest.getParameters();
//
// Calculate the lists of tests that can be run in sequence and in parallel
//
List<List<ITestNGMethod>> sequentialList= new ArrayList<List<ITestNGMethod>>();
List<ITestNGMethod> parallelList= new ArrayList<ITestNGMethod>();
computeTestLists(sequentialList, parallelList);
log(3, "Found " + (sequentialList.size() + parallelList.size()) + " applicable methods");
//
// Create the workers
//
List<TestMethodWorker> workers = new ArrayList<TestMethodWorker>();
ClassMethodMap cmm = new ClassMethodMap(m_allTestMethods);
// All the sequential tests are place in one worker, guaranteeing they
// will be invoked sequentially
if (sequentialList.size() > 0) {
for (List<ITestNGMethod> sl : sequentialList) {
workers.add(new TestMethodWorker(m_invoker,
methodsToMethodInstances(sl),
m_xmlTest.getSuite(),
params,
m_allTestMethods,
m_groupMethods,
cmm,
this));
}
}
// All the parallel tests are placed in a separate worker, so they can be
// invoked in parallel
if (parallelList.size() > 0) {
for (ITestNGMethod tm : parallelList) {
List<MethodInstance> methodInstances = methodsToMultipleMethodInstances(Arrays.asList(new ITestNGMethod[] {tm}));
for (MethodInstance mi : methodInstances) {
workers.add(new TestMethodWorker(m_invoker,
new MethodInstance[] { mi },
m_xmlTest.getSuite(),
params,
m_allTestMethods,
m_groupMethods,
cmm,
this));
}
}
}
try {
runWorkers(workers, xmlTest.getParallel());
}
finally {
cmm.clear();
}
}
private List<MethodInstance> methodsToMultipleMethodInstances(List<ITestNGMethod> sl) {
List<MethodInstance> vResult = new ArrayList<MethodInstance>();
for (ITestNGMethod m : sl) {
Object[] instances = m.getTestClass().getInstances(true);
for (Object instance : instances) {
vResult.add(new MethodInstance(m, new Object[] { instance }));
}
}
return vResult;
}
private MethodInstance[] methodsToMethodInstances(List<ITestNGMethod> sl) {
MethodInstance[] result = new MethodInstance[sl.size()];
for (int i = 0; i < result.length; i++) {
result[i] = new MethodInstance(sl.get(i), sl.get(i).getTestClass().getInstances(true));
}
return result;
}
//
// Invoke the workers
//
private void runWorkers(List<? extends IMethodWorker> workers, String parallelMode) {
if (XmlSuite.PARALLEL_METHODS.equals(parallelMode)
|| "true".equalsIgnoreCase(parallelMode) )
{
//
// Parallel run
//
// Default timeout for individual methods: 10 seconds
long maxTimeOut = m_xmlTest.getTimeOut(10 * 1000);
for (IMethodWorker tmw : workers) {
long mt= tmw.getMaxTimeOut();
if (mt > maxTimeOut) {
maxTimeOut= mt;
}
}
ThreadUtil.execute(workers, m_xmlTest.getThreadCount(), maxTimeOut, false);
}
else {
//
// Sequential run
//
for (IMethodWorker tmw : workers) {
tmw.run();
}
}
}
private void afterRun() {
// invoke @AfterTest
ITestNGMethod[] testConfigurationMethods= getAfterTestConfigurationMethods();
if(null != testConfigurationMethods && testConfigurationMethods.length > 0) {
m_invoker.invokeConfigurations(null,
testConfigurationMethods,
m_xmlTest.getSuite(),
m_xmlTest.getParameters(),
null /* instance */);
}
//
// Log the end date
//
m_endDate = new Date(System.currentTimeMillis());
if (getVerbose() >= 3) {
dumpInvokedMethods();
}
// Invoke listeners
fireEvent(false /*stop*/);
// Statistics
// logResults();
}
/**
* @param regexps
* @param group
* @return true if the map contains at least one regexp that matches the
* given group
*/
private boolean containsString(Map<String, String> regexps, String group) {
for (String regexp : regexps.values()) {
boolean match = Pattern.matches(regexp, group);
if (match) {
return true;
}
}
return false;
}
/**
* Creates the
* @param sl the sequential list of methods
* @param parallelList the list of methods that can be run in parallel
*/
private void computeTestLists(List<List<ITestNGMethod>> sl,
List<ITestNGMethod> parallelList)
{
Map<String, String> groupsDependedUpon= new HashMap<String, String>();
Map<String, String> methodsDependedUpon= new HashMap<String, String>();
Map<String, List<ITestNGMethod>> sequentialAttributeList = new HashMap<String, List<ITestNGMethod>>();
List<ITestNGMethod> sequentialList = new ArrayList<ITestNGMethod>();
for (int i= m_allTestMethods.length - 1; i >= 0; i--) {
ITestNGMethod tm= m_allTestMethods[i];
//
// If the class this method belongs to has @Test(sequential = true), we
// put this method in the sequential list right away
//
Class cls = tm.getMethod().getDeclaringClass();
org.testng.internal.annotations.ITest test =
(org.testng.internal.annotations.ITest) m_annotationFinder.
findAnnotation(cls, org.testng.internal.annotations.ITest.class);
if (test != null) {
if (test.getSequential()) {
String className = cls.getName();
List<ITestNGMethod> list = sequentialAttributeList.get(className);
if (list == null) {
list = new ArrayList<ITestNGMethod>();
sequentialAttributeList.put(className, list);
}
list.add(0, tm);
continue;
}
}
//
// Otherwise, determine if it depends on other methods/groups or if
// it is depended upon
//
String[] currentGroups = tm.getGroups();
String[] currentGroupsDependedUpon= tm.getGroupsDependedUpon();
String[] currentMethodsDependedUpon= tm.getMethodsDependedUpon();
String thisMethodName = tm.getMethod().getDeclaringClass().getName() + "." +
tm.getMethod().getName();
if (currentGroupsDependedUpon.length > 0) {
for (String gdu : currentGroupsDependedUpon) {
groupsDependedUpon.put(gdu, gdu);
}
sequentialList.add(0, tm);
}
else if (currentMethodsDependedUpon.length > 0) {
for (String cmu : currentMethodsDependedUpon) {
methodsDependedUpon.put(cmu, cmu);
}
sequentialList.add(0, tm);
}
// Is there a method that depends on the current method?
else if (containsString(methodsDependedUpon, thisMethodName)) {
sequentialList.add(0, tm);
}
else if (currentGroups.length > 0) {
boolean isSequential= false;
for (String group : currentGroups) {
if (containsString(groupsDependedUpon, group)) {
sequentialList.add(0, tm);
isSequential = true;
break;
}
}
if (!isSequential) {
parallelList.add(0, tm);
}
}
else {
parallelList.add(0, tm);
}
}
//
// Put all the sequential methods in the output argument
//
if(sequentialList.size() > 0) {
sl.add(sequentialList);
}
for (List<ITestNGMethod> l : sequentialAttributeList.values()) {
sl.add(l);
}
//
// Finally, sort the parallel methods by classes
//
Collections.sort(parallelList, TestNGMethod.SORT_BY_CLASS);
if (getVerbose() >= 2) {
log(3, "WILL BE RUN IN RANDOM ORDER:");
for (ITestNGMethod tm : parallelList) {
log(3, " " + tm);
}
log(3, "WILL BE RUN SEQUENTIALLY:");
for (List<ITestNGMethod> l : sl) {
for (ITestNGMethod tm : l) {
log(3, " " + tm);
}
log(3, "====");
}
log(3, "===");
}
}
/**
* Logs the beginning of the {@link #beforeRun()} .
*/
private void logStart() {
log(3,
"Running test " + m_testName + " on " + m_classMap.size() + " " + " classes, "
+ " included groups:[" + mapToString(m_xmlMethodSelector.getIncludedGroups())
+ "] excluded groups:[" + mapToString(m_xmlMethodSelector.getExcludedGroups()) + "]");
if (getVerbose() >= 3) {
for (ITestClass tc : m_classMap.values()) {
((TestClass) tc).dump();
}
}
}
/**
* Trigger the start/finish event.
*
* @param isStart <tt>true</tt> if the event is for start, <tt>false</tt> if the
* event is for finish
*/
private void fireEvent(boolean isStart) {
for (ITestListener itl : m_testListeners) {
if (isStart) {
itl.onStart(this);
}
else {
itl.onFinish(this);
}
}
}
/////
// ITestContext
//
public String getName() {
return m_testName;
}
/**
* @return Returns the startDate.
*/
public Date getStartDate() {
return m_startDate;
}
/**
* @return Returns the endDate.
*/
public Date getEndDate() {
return m_endDate;
}
public IResultMap getPassedTests() {
return m_passedTests;
}
public IResultMap getSkippedTests() {
return m_skippedTests;
}
public IResultMap getFailedTests() {
return m_failedTests;
}
public IResultMap getFailedButWithinSuccessPercentageTests() {
return m_failedButWithinSuccessPercentageTests;
}
public String[] getIncludedGroups() {
Map<String, String> ig= m_xmlMethodSelector.getIncludedGroups();
String[] result= (String[]) ig.values().toArray((new String[ig.size()]));
return result;
}
public String[] getExcludedGroups() {
Map<String, String> eg= m_xmlMethodSelector.getExcludedGroups();
String[] result= (String[]) eg.values().toArray((new String[eg.size()]));
return result;
}
public String getOutputDirectory() {
return m_outputDirectory;
}
/**
* @return Returns the suite.
*/
public ISuite getSuite() {
return m_suite;
}
public ITestNGMethod[] getAllTestMethods() {
return m_allTestMethods;
}
public String getHost() {
return m_host;
}
public Collection<ITestNGMethod> getExcludedMethods() {
Map<ITestNGMethod, ITestNGMethod> vResult =
new HashMap<ITestNGMethod, ITestNGMethod>();
for (ITestNGMethod m : m_excludedMethods) {
vResult.put(m, m);
}
return vResult.keySet();
}
/**
* @see org.testng.ITestContext#getFailedConfigurations()
*/
public IResultMap getFailedConfigurations() {
return m_failedConfigurations;
}
/**
* @see org.testng.ITestContext#getPassedConfigurations()
*/
public IResultMap getPassedConfigurations() {
return m_passedConfigurations;
}
/**
* @see org.testng.ITestContext#getSkippedConfigurations()
*/
public IResultMap getSkippedConfigurations() {
return m_skippedConfigurations;
}
//
// ITestContext
/////
/////
// ITestResultNotifier
//
public void addPassedTest(ITestNGMethod tm, ITestResult tr) {
m_passedTests.addResult(tr, tm);
}
public Set<ITestResult> getPassedTests(ITestNGMethod tm) {
return m_passedTests.getResults(tm);
}
public void addSkippedTest(ITestNGMethod tm, ITestResult tr) {
m_skippedTests.addResult(tr, tm);
}
public void addInvokedMethod(InvokedMethod im) {
synchronized(m_invokedMethods) {
m_invokedMethods.add(im);
}
}
public void addFailedTest(ITestNGMethod testMethod, ITestResult result) {
logFailedTest(testMethod, result, false /* withinSuccessPercentage */);
}
public void addFailedButWithinSuccessPercentageTest(ITestNGMethod testMethod,
ITestResult result) {
logFailedTest(testMethod, result, true /* withinSuccessPercentage */);
}
public XmlTest getTest() {
return m_xmlTest;
}
public List<ITestListener> getTestListeners() {
return m_testListeners;
}
public List<IConfigurationListener> getConfigurationListeners() {
return m_configurationListeners;
}
//
// ITestResultNotifier
/////
private void logFailedTest(ITestNGMethod method,
ITestResult tr,
boolean withinSuccessPercentage) {
if (withinSuccessPercentage) {
m_failedButWithinSuccessPercentageTests.addResult(tr, method);
}
else {
m_failedTests.addResult(tr, method);
}
}
private String mapToString(Map m) {
StringBuffer result= new StringBuffer();
for (Object o : m.values()) {
result.append(o.toString()).append(" ");
}
return result.toString();
}
private void log(int level, String s) {
Utils.log("TestRunner", level, s);
}
public static int getVerbose() {
return m_verbose;
}
public void setVerbose(int n) {
m_verbose = n;
}
private void log(String s) {
Utils.log("TestRunner", 2, s);
}
/////
// Listeners
//
public void addListener(Object listener) {
if(listener instanceof ITestListener) {
addTestListener((ITestListener) listener);
}
if(listener instanceof IConfigurationListener) {
addConfigurationListener((IConfigurationListener) listener);
}
}
public void addTestListener(ITestListener il) {
m_testListeners.add(il);
}
public void addConfigurationListener(IConfigurationListener icl) {
m_configurationListeners.add(icl);
}
//
// Listeners
/////
private List<InvokedMethod> m_invokedMethods = new ArrayList<InvokedMethod>();
private void dumpInvokedMethods() {
System.out.println("\n*********** INVOKED METHODS\n");
for (InvokedMethod im : m_invokedMethods) {
if (im.isTestMethod()) {
System.out.print("\t\t");
}
else if (im.isConfigurationMethod()) {
System.out.print("\t");
}
else {
continue;
}
System.out.println("" + im);
}
System.out.println("\n***********\n");
}
/**
* @return
*/
public List<ITestNGMethod> getInvokedMethods() {
List<ITestNGMethod> result= new ArrayList<ITestNGMethod>();
for (InvokedMethod im : m_invokedMethods) {
ITestNGMethod tm= im.getTestMethod();
tm.setDate(im.getDate());
result.add(tm);
}
return result;
}
private IResultMap m_passedConfigurations= new ResultMap();
private IResultMap m_skippedConfigurations= new ResultMap();
private IResultMap m_failedConfigurations= new ResultMap();
private class ConfigurationListener implements IConfigurationListener {
public void onConfigurationFailure(ITestResult itr) {
m_failedConfigurations.addResult(itr, itr.getMethod());
}
public void onConfigurationSkip(ITestResult itr) {
m_skippedConfigurations.addResult(itr, itr.getMethod());
}
public void onConfigurationSuccess(ITestResult itr) {
m_passedConfigurations.addResult(itr, itr.getMethod());
}
}
} // TestRunner