Extended reporters configuration
diff --git a/src/main/org/testng/TestNG.java b/src/main/org/testng/TestNG.java
index a1c534c..f9efe46 100644
--- a/src/main/org/testng/TestNG.java
+++ b/src/main/org/testng/TestNG.java
@@ -24,12 +24,7 @@
import javax.xml.parsers.ParserConfigurationException;
-import org.testng.internal.AnnotationTypeEnum;
-import org.testng.internal.ClassHelper;
-import org.testng.internal.HostFile;
-import org.testng.internal.IResultListener;
-import org.testng.internal.Invoker;
-import org.testng.internal.Utils;
+import org.testng.internal.*;
import org.testng.internal.annotations.DefaultAnnotationTransformer;
import org.testng.internal.annotations.IAnnotationFinder;
import org.testng.internal.annotations.IAnnotationTransformer;
@@ -683,7 +678,7 @@
if(m_useDefaultListeners) {
m_reporters.add(new SuiteHTMLReporter());
m_reporters.add(new FailedReporter());
- m_reporters.add(new XMLReporter());
+// m_reporters.add(new XMLReporter());
m_reporters.add(new EmailableReporter());
}
}
@@ -1112,6 +1107,23 @@
if(null != objectFactory) {
setObjectFactory(objectFactory);
}
+
+ List<ReporterConfig> reporterConfigs =
+ (List<ReporterConfig>) cmdLineArgs.get(TestNGCommandLineArgs.REPORTERS_LIST);
+ if (reporterConfigs != null) {
+ for (ReporterConfig reporterConfig : reporterConfigs) {
+ addReporter(reporterConfig);
+ }
+ }
+ }
+
+ private void addReporter(ReporterConfig reporterConfig) {
+ Object instance = reporterConfig.newReporterInstance();
+ if (instance != null) {
+ addListener(instance);
+ } else {
+ LOGGER.warn("Could not find reporte class : " + reporterConfig.getClassname());
+ }
}
private void setClientPort(int clientPort) {
diff --git a/src/main/org/testng/TestNGAntTask.java b/src/main/org/testng/TestNGAntTask.java
index 8845c51..fa8a755 100644
--- a/src/main/org/testng/TestNGAntTask.java
+++ b/src/main/org/testng/TestNGAntTask.java
@@ -135,6 +135,11 @@
private String m_suiteName="Ant suite";
private String m_testName="Ant test";
+ /**
+ * The list of report listeners added via <reporter> sub-element of the Ant task
+ */
+ private List<ReporterConfig> reporterConfigs = new ArrayList<ReporterConfig>();
+
public void setParallel(String parallel) {
m_parallelMode= parallel;
}
@@ -566,6 +571,13 @@
argv.add(m_testName);
}
+ if (!reporterConfigs.isEmpty()) {
+ for (ReporterConfig reporterConfig : reporterConfigs) {
+ argv.add(TestNGCommandLineArgs.REPORTER);
+ argv.add(reporterConfig.serialize());
+ }
+ }
+
if(m_xmlFilesets.size() > 0) {
for(String file : fileset(m_xmlFilesets)) {
argv.add(file);
@@ -995,4 +1007,8 @@
ppp(line);
}
}
+
+ public void addConfiguredReporter(ReporterConfig reporterConfig) {
+ reporterConfigs.add(reporterConfig);
+ }
}
diff --git a/src/main/org/testng/TestNGCommandLineArgs.java b/src/main/org/testng/TestNGCommandLineArgs.java
index b6d52d4..1a614bc 100644
--- a/src/main/org/testng/TestNGCommandLineArgs.java
+++ b/src/main/org/testng/TestNGCommandLineArgs.java
@@ -69,6 +69,14 @@
public static final String PARALLEL_MODE = "-parallel";
public static final String SUITE_NAME_OPT = "-suitename";
public static final String TEST_NAME_OPT = "-testname";
+ /**
+ * Used to pass a reporter configuration in the form <code>-reporter <reporter_name_or_class>:option=value[,option=value]</code>
+ */
+ public static final String REPORTER = "-reporter";
+ /**
+ * Used as map key for the complete list of report listeners provided with the above argument
+ */
+ public static final String REPORTERS_LIST = "-reporterslist";
/**
* When given a file name to form a class name, the file name is parsed and divided
@@ -331,6 +339,16 @@
i++;
}
}
+ else if (REPORTER.equalsIgnoreCase(argv[i])) {
+ if ((i + 1) < argv.length) {
+ ReporterConfig reporterConfig = ReporterConfig.deserialize(trim(argv[i + 1]));
+ if (arguments.get(REPORTERS_LIST) == null) {
+ arguments.put(REPORTERS_LIST, new ArrayList<ReporterConfig>());
+ }
+ ((List<ReporterConfig>)arguments.get(REPORTERS_LIST)).add(reporterConfig);
+ i++;
+ }
+ }
//
// Unknown option
//
diff --git a/src/main/org/testng/internal/Parameters.java b/src/main/org/testng/internal/Parameters.java
index 5d1f5b9..e44c071 100644
--- a/src/main/org/testng/internal/Parameters.java
+++ b/src/main/org/testng/internal/Parameters.java
@@ -138,8 +138,9 @@
}
}
}
-
- private static Object convertType(Class type, String value, String paramName) {
+
+ //TODO: Cosmin - making this public is not the best solution
+ public static Object convertType(Class type, String value, String paramName) {
Object result = null;
if(NULL_VALUE.equals(value.toLowerCase())) {
diff --git a/src/main/org/testng/reporters/XMLReporter.java b/src/main/org/testng/reporters/XMLReporter.java
index e2a2349..6335a48 100644
--- a/src/main/org/testng/reporters/XMLReporter.java
+++ b/src/main/org/testng/reporters/XMLReporter.java
@@ -5,9 +5,7 @@
import org.testng.xml.XmlSuite;
import java.io.File;
-import java.io.UnsupportedEncodingException;
import java.util.*;
-import java.net.URLEncoder;
/**
* The main entry for the XML generation operation
@@ -16,11 +14,13 @@
*/
public class XMLReporter implements IReporter {
- private XMLReporterConfig config;
+ private XMLReporterConfig config = new XMLReporterConfig();
private XMLStringBuffer rootBuffer;
public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectory) {
- config = new XMLReporterConfig(outputDirectory);
+ if (Utils.isStringEmpty(config.getOutputDirectory())) {
+ config.setOutputDirectory(outputDirectory);
+ }
rootBuffer = new XMLStringBuffer("");
rootBuffer.push(XMLReporterConfig.TAG_TESTNG_RESULTS);
@@ -29,7 +29,7 @@
writeSuite(xmlSuites.get(i), suites.get(i));
}
rootBuffer.pop();
- Utils.writeFile(config.getOutput(), "testng-results.xml", rootBuffer.toXML());
+ Utils.writeFile(config.getOutputDirectory(), "testng-results.xml", rootBuffer.toXML());
}
private void writeReporterOutput(XMLStringBuffer xmlBuffer) {
@@ -43,11 +43,6 @@
}
private void writeSuite(XmlSuite xmlSuite, ISuite suite) {
- try {
- Utils.writeFile(config.getOutput(), URLEncoder.encode(xmlSuite.getName(), "utf-8") + "-testng.xml", xmlSuite.toXml());
- } catch(UnsupportedEncodingException e) {
- throw new RuntimeException("no utf-8 in your JVM, awful awful things are happening", e);
- }
switch (config.getFileFragmentationLevel()) {
case XMLReporterConfig.FF_LEVEL_NONE:
writeSuiteToBuffer(rootBuffer, suite);
@@ -69,13 +64,8 @@
}
private File referenceSuite(XMLStringBuffer xmlBuffer, ISuite suite) {
- String relativePath;
- try {
- relativePath = URLEncoder.encode(suite.getName(), "utf-8") + File.separatorChar + "testng-results.xml";
- } catch(UnsupportedEncodingException e) {
- throw new RuntimeException("no utf-8 in your JVM, awful awful things are happening", e);
- }
- File suiteFile = new File(config.getOutput(), relativePath);
+ String relativePath = suite.getName() + File.separatorChar + "testng-results.xml";
+ File suiteFile = new File(config.getOutputDirectory(), relativePath);
Properties attrs = new Properties();
attrs.setProperty(XMLReporterConfig.ATTR_URL, relativePath);
xmlBuffer.addEmptyElement(XMLReporterConfig.TAG_SUITE, attrs);
@@ -129,4 +119,53 @@
}
return result;
}
+
+ //TODO: This is not the smartest way to implement the config
+ public int getFileFragmentationLevel() {
+ return config.getFileFragmentationLevel();
+ }
+
+ public void setFileFragmentationLevel(int fileFragmentationLevel) {
+ config.setFileFragmentationLevel(fileFragmentationLevel);
+ }
+
+ public int getStackTraceOutputMethod() {
+ return config.getStackTraceOutputMethod();
+ }
+
+ public void setStackTraceOutputMethod(int stackTraceOutputMethod) {
+ config.setStackTraceOutputMethod(stackTraceOutputMethod);
+ }
+
+ public String getOutputDirectory() {
+ return config.getOutputDirectory();
+ }
+
+ public void setOutputDirectory(String outputDirectory) {
+ config.setOutputDirectory(outputDirectory);
+ }
+
+ public boolean isGenerateGroupsAttribute() {
+ return config.isGenerateGroupsAttribute();
+ }
+
+ public void setGenerateGroupsAttribute(boolean generateGroupsAttribute) {
+ config.setGenerateGroupsAttribute(generateGroupsAttribute);
+ }
+
+ public boolean isSplitClassAndPackageNames() {
+ return config.isSplitClassAndPackageNames();
+ }
+
+ public void setSplitClassAndPackageNames(boolean splitClassAndPackageNames) {
+ config.setSplitClassAndPackageNames(splitClassAndPackageNames);
+ }
+
+ public String getTimestampFormat() {
+ return config.getTimestampFormat();
+ }
+
+ public void setTimestampFormat(String timestampFormat) {
+ config.setTimestampFormat(timestampFormat);
+ }
}
diff --git a/src/main/org/testng/reporters/XMLReporterConfig.java b/src/main/org/testng/reporters/XMLReporterConfig.java
index 72d1c6f..d87b052 100644
--- a/src/main/org/testng/reporters/XMLReporterConfig.java
+++ b/src/main/org/testng/reporters/XMLReporterConfig.java
@@ -1,13 +1,9 @@
package org.testng.reporters;
-import java.io.File;
-import java.io.Serializable;
-
/**
* @author Hani Suleiman Date: Mar 27, 2007 Time: 9:16:28 AM
*/
-public class XMLReporterConfig implements Serializable
-{
+public class XMLReporterConfig {
/**
* Indicates that no file fragmentation should be performed. This value indicates the XML generator to write all the
* results in one big file. Not recommended for large test suites.
@@ -86,7 +82,7 @@
* Indicates the way that the file fragmentation should be performed. Set this property to one of the FF_LEVEL_*
* values for the desired output structure
*/
- private int fileFragmentationLevel = FF_LEVEL_SUITE;
+ private int fileFragmentationLevel = FF_LEVEL_NONE;
/**
* Stack trace output method for the failed tests using one of the STACKTRACE_* constants.
@@ -118,19 +114,12 @@
*/
private String timestampFormat = FMT_DEFAULT;
- private String subDirectory = "xml";
- private static final long serialVersionUID = 5375520916207107244L;
-
- public XMLReporterConfig(String outputDirectory) {
- this.outputDirectory = outputDirectory;
+ public int getFileFragmentationLevel() {
+ return fileFragmentationLevel;
}
- public String getSubDirectory() {
- return subDirectory;
- }
-
- public void setSubDirectory(String subDirectory) {
- this.subDirectory = subDirectory;
+ public void setFileFragmentationLevel(int fileFragmentationLevel) {
+ this.fileFragmentationLevel = fileFragmentationLevel;
}
public int getStackTraceOutputMethod() {
@@ -141,24 +130,14 @@
this.stackTraceOutputMethod = stackTraceOutputMethod;
}
- public int getFileFragmentationLevel() {
- return fileFragmentationLevel;
- }
-
- public void setFileFragmentationLevel(int fileFragmentationLevel) {
- this.fileFragmentationLevel = fileFragmentationLevel;
- }
-
public String getOutputDirectory() {
return outputDirectory;
}
- public File getOutput() {
- if(subDirectory != null && subDirectory.length() > 0)
- return new File(outputDirectory, subDirectory);
- return new File(outputDirectory);
+ public void setOutputDirectory(String outputDirectory) {
+ this.outputDirectory = outputDirectory;
}
-
+
public boolean isGenerateGroupsAttribute() {
return generateGroupsAttribute;
}
@@ -167,14 +146,6 @@
this.generateGroupsAttribute = generateGroupsAttribute;
}
- public String getTimestampFormat() {
- return timestampFormat;
- }
-
- public void setTimestampFormat(String timestampFormat) {
- this.timestampFormat = timestampFormat;
- }
-
public boolean isSplitClassAndPackageNames() {
return splitClassAndPackageNames;
}
@@ -182,4 +153,12 @@
public void setSplitClassAndPackageNames(boolean splitClassAndPackageNames) {
this.splitClassAndPackageNames = splitClassAndPackageNames;
}
+
+ public String getTimestampFormat() {
+ return timestampFormat;
+ }
+
+ public void setTimestampFormat(String timestampFormat) {
+ this.timestampFormat = timestampFormat;
+ }
}
diff --git a/src/main/org/testng/reporters/XMLSuiteResultWriter.java b/src/main/org/testng/reporters/XMLSuiteResultWriter.java
index a94bb78..a22aec0 100644
--- a/src/main/org/testng/reporters/XMLSuiteResultWriter.java
+++ b/src/main/org/testng/reporters/XMLSuiteResultWriter.java
@@ -38,7 +38,7 @@
writeAllToBuffer(xmlBuffer, suiteResult);
} else {
String parentDir =
- config.getOutput().getAbsolutePath() + File.separatorChar + suiteResult.getTestContext().getSuite().getName();
+ config.getOutputDirectory() + File.separatorChar + suiteResult.getTestContext().getSuite().getName();
File file = referenceSuiteResult(xmlBuffer, parentDir, suiteResult);
XMLStringBuffer suiteXmlBuffer = new XMLStringBuffer("");
writeAllToBuffer(suiteXmlBuffer, suiteResult);
@@ -48,7 +48,7 @@
private void writeAllToBuffer(XMLStringBuffer xmlBuffer, ISuiteResult suiteResult) {
xmlBuffer.push(XMLReporterConfig.TAG_TEST, getSuiteResultAttributes(suiteResult));
- Set<ITestResult> testResults = new HashSet<ITestResult>();
+ Set<ITestResult> testResults = new HashSet();
addAllTestResults(testResults, suiteResult.getTestContext().getPassedTests());
addAllTestResults(testResults, suiteResult.getTestContext().getFailedTests());
addAllTestResults(testResults, suiteResult.getTestContext().getSkippedTests());