我在工作中也有类似的目标,所以我创建了一个通用的命令行 Fitnesse 测试运行器,它以 Web 请求的形式执行测试或套件,解析生成的 XML 并使用下面的样式表对其进行转换,最后编写结果到 %TestOutputDirectory% 中名为“results.xml”的文件中,由 Visual Studio 中的通用测试指定。
结果文件由 Visual Studio 加载并解析为 summary results file,报告在 Fitnesse 测试或套件中通过或失败的子测试数量。输出文件格式的详细信息记录在 here 中,但是当在默认的 Fitnesse wiki 中针对 Fitnesse 的两分钟示例运行时,一个简单的示例看起来像这样:
<?xml version="1.0" encoding="utf-8"?>
<SummaryResult>
<TestName>TwoMinuteExample</TestName>
<TestResult>Failed</TestResult>
<ErrorMessage>6 right, 1 wrong, 0 ignores and 0 exceptions.</ErrorMessage>
<InnerTests>
<InnerTest>
<TestName>TwoMinuteExample</TestName>
<TestResult>Failed</TestResult>
<ErrorMessage>6 right, 1 wrong, 0 ignores and 0 exceptions.</ErrorMessage>
</InnerTest>
</InnerTests>
</SummaryResult>
因此,现在可以在测试项目中为您希望从 Visual Studio 执行或作为构建的一部分执行的每个 Fitnesse 测试/套件创建 Visual Studio“通用测试”。通用测试必须指定通用测试运行程序可执行文件的路径、Fitnesse 服务器、端口和 wiki 中的测试/套件名称。它需要选中“摘要结果文件”复选框并输入“Results.xml”以获取详细信息以显示在测试运行或构建的输出中。
我可以与您共享此代码,或者您可以使用通用命令行测试运行程序并将输出传送到一个小应用程序中,该应用程序使用下面的样式表转换结果。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="GlobalRightCount" select="sum(//result/counts/right)"/>
<xsl:variable name="GlobalIgnoresCount" select="sum(//result/counts/ignores)"/>
<xsl:variable name="GlobalWrongCount" select="sum(//result/counts/wrong)"/>
<xsl:variable name="GlobalExceptionsCount" select="sum(//result/counts/exceptions)"/>
<xsl:variable name="GlobalFailureCount" select="$GlobalWrongCount + $GlobalExceptionsCount"/>
<xsl:template match="testResults">
<SummaryResult>
<TestName>
<xsl:value-of select="rootPath"/>
</TestName>
<xsl:choose>
<xsl:when test="$GlobalFailureCount = 0">
<TestResult>Passed</TestResult>
<xsl:call-template name="GlobalErrorMessage"/>
</xsl:when>
<xsl:otherwise>
<TestResult>Failed</TestResult>
<xsl:call-template name="GlobalErrorMessage"/>
</xsl:otherwise>
</xsl:choose>
<InnerTests>
<xsl:for-each select="result">
<InnerTest>
<TestName>
<xsl:value-of select="relativePageName"/>
</TestName>
<xsl:choose>
<xsl:when test="sum(counts/wrong) + sum(counts/exceptions) = 0">
<TestResult>Passed</TestResult>
<xsl:call-template name="ResultErrorMessage"/>
</xsl:when>
<xsl:otherwise>
<TestResult>Failed</TestResult>
<xsl:call-template name="ResultErrorMessage"/>
</xsl:otherwise>
</xsl:choose>
</InnerTest>
</xsl:for-each>
</InnerTests>
</SummaryResult>
</xsl:template>
<xsl:template name="GlobalErrorMessage">
<ErrorMessage><xsl:value-of select ="$GlobalRightCount"/> right, <xsl:value-of select ="$GlobalWrongCount"/> wrong, <xsl:value-of select ="$GlobalIgnoresCount"/> ignores and <xsl:value-of select ="$GlobalExceptionsCount"/> exceptions.</ErrorMessage>
</xsl:template>
<xsl:template name="ResultErrorMessage">
<ErrorMessage><xsl:value-of select ="sum(counts/right)"/> right, <xsl:value-of select ="sum(counts/wrong)"/> wrong, <xsl:value-of select ="sum(counts/ignores)"/> ignores and <xsl:value-of select ="sum(counts/exceptions)"/> exceptions.</ErrorMessage>
</xsl:template>
</xsl:stylesheet>
更新:添加通用测试运行程序代码
这绝对只是概念验证,不一定是最终解决方案。您可以将此技术与 Martin Woodward 的答案结合起来,以获得测试列表本身是动态的完整图片。或者,您可以更改测试运行程序以运行它在整个(子)wiki 中找到的所有测试。这里可能还有其他几个选项。
以下代码远未优化,但显示了一般过程。您可以将其粘贴到新的控制台应用程序项目中。请注意,它需要命令行参数,您可以在项目属性中为这些参数提供默认值:
命令行示例:localhost 80 FitNesse.UserGuide.TwoMinuteExample
class Program
{
static int Main(string[] args)
{
//Default to error unless proven otherwise
int returnValue = 1;
try
{
List<string> commandLineArgs = args.ToList<string>();
string host = args[0];
int port = int.Parse(args[1]);
string path = args[2];
string testCommand = "suite";
XmlDocument fitnesseResults = GetFitnesseResult(host, port, path, testCommand);
XmlDocument visualStudioResults = TransformFitnesseToVisualStudioResults(fitnesseResults);
visualStudioResults.Save("Results.xml");
var testResultNode = visualStudioResults.DocumentElement.SelectSingleNode("TestResult");
var value = testResultNode.InnerText;
if (value == "Success")
{
returnValue = 0;
}
}
catch (System.Exception ex)
{
Console.WriteLine(ex.ToString());
}
return returnValue;
}
private static XmlDocument GetFitnesseResult(string host, int port, string path, string testCommand)
{
UriBuilder uriBuilder = new UriBuilder("http", host, port, path, "?" + testCommand + "&format=xml");
WebRequest request = HttpWebRequest.Create(uriBuilder.Uri);
request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
WebResponse response = request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader responseReader = new StreamReader(responseStream);
string responseString = responseReader.ReadToEnd();
XmlDocument rawResults = new XmlDocument();
rawResults.LoadXml(responseString);
return (rawResults);
}
private static XmlDocument TransformFitnesseToVisualStudioResults(XmlDocument fitnesseResults)
{
XslCompiledTransform transformer = new XslCompiledTransform(false);
string codeBase = Assembly.GetEntryAssembly().CodeBase;
string directory = Path.GetDirectoryName(codeBase);
string xsltPath = Path.Combine(directory, "FitnesseToSummaryResult.xslt");
transformer.Load(xsltPath);
MemoryStream resultsStream = new MemoryStream();
transformer.Transform(fitnesseResults, null, resultsStream);
resultsStream.Position = 0;
XmlDocument results = new XmlDocument();
results.Load(resultsStream);
return (results);
}
}