接着上一篇继续走查整个xml文件生成的过程
1.在FailedReporter.java中的方法generateFailureSuite最后是生成xml文件,这里的三个入参分别是输出路径,文件名,及SuiteXml
if(null != failedSuite.getTests() && failedSuite.getTests().size() > 0) {
Utils.writeUtf8File(outputDir, TESTNG_FAILED_XML, failedSuite.toXml();
}
那么,方法writeUtf8File的具体实现又是什么呢?简单来说就是在目录下outputDir下生成一个内容是sb且文件名是fileName的文件
/**
* Writes the content of the sb string to the file named filename in outDir encoding the output as UTF-8.
* If outDir does not exist, it is created.
*
* @param outputDir the output directory (may not exist). If is null then current directory is used.
* @param fileName the filename
* @param sb the file content
*/
public static void writeUtf8File(@Nullable String outputDir, String fileName, String sb)
{
final String outDirPath= outputDir != null ? outputDir : "";
final File outDir= new File(outDirPath);
writeFile(outDir, fileName, escapeUnicode(sb), "UTF-8", false /* don't append */);
}
还是回到上一步,文件内容是怎么生成的呢?利用方法 failedSuite.toXml(),走读一下该方法的具体实现:
/**
* @return A String representation of this XML suite.
*/
public String toXml() {
XMLStringBuffer xsb = new XMLStringBuffer();
//TESTNG_DTD
xsb.setDocType("suite SYSTEM \"" + Parser.TESTNG_DTD_URL + '\"');
Properties p = new Properties();
//suiteName
p.setProperty("name", getName());
//suiteVerbose
if (getVerbose() != null) {
XmlUtils.setProperty(p, "verbose", getVerbose().toString(), DEFAULT_VERBOSE.toString());
}
//parallel
final ParallelMode parallel= getParallel();
if(parallel != null && !DEFAULT_PARALLEL.equals(parallel)) {
p.setProperty("parallel", parallel.toString());
}
//thread-count
XmlUtils.setProperty(p, "thread-count", String.valueOf(getThreadCount()),
DEFAULT_THREAD_COUNT.toString());
//data-provider-thread-count
XmlUtils.setProperty(p, "data-provider-thread-count", String.valueOf(getDataProviderThreadCount()),
DEFAULT_DATA_PROVIDER_THREAD_COUNT.toString());
//skipfailedinvocationcounts
XmlUtils.setProperty(p, "skipfailedinvocationcounts", m_skipFailedInvocationCounts.toString(),
DEFAULT_SKIP_FAILED_INVOCATION_COUNTS.toString());
//push properties
xsb.push("suite", p);
//配置参数,如dataProvider等
XmlUtils.dumpParameters(xsb, m_parameters);
//监听器
if (hasElements(m_listeners)) {
xsb.push("listeners");
for (String listenerName: m_listeners) {
Properties listenerProps = new Properties();
listenerProps.setProperty("class-name", listenerName);
xsb.addEmptyElement("listener", listenerProps);
}
xsb.pop("listeners");
}
//package标签
if (hasElements(getXmlPackages())) {
xsb.push("packages");
for (XmlPackage pack : getXmlPackages()) {
xsb.getStringBuffer().append(pack.toXml(" "));
}
xsb.pop("packages");
}
//groups(包括include及exclude)
List<String> included = getIncludedGroups();
List<String> excluded = getExcludedGroups();
if (hasElements(included) || hasElements(excluded)) {
xsb.push("groups");
xsb.push("run");
for (String g : included) {
xsb.addEmptyElement("include", "name", g);
}
for (String g : excluded) {
xsb.addEmptyElement("exclude", "name", g);
}
xsb.pop("run");
xsb.pop("groups");
}
//生成group标签的Xml
if (m_xmlGroups != null) {
xsb.getStringBuffer().append(m_xmlGroups.toXml(" "));
}
//生成testscXml
for (XmlTest test : getTests()) {
xsb.getStringBuffer().append(test.toXml(" "));
}
xsb.pop("suite");
return xsb.toXML();
}
在生成suiteXml的时候会调用成功group及tests标签的xml方法,
而在test.toxml方法中又有生成<package>标签及classes标签xml的方法,
继续在生成classesXml的方法中又有生成IncludeXml的方法。
他们之间的生成关系图如下: