从批处理脚本检查 NUnit 测试结果






4.14/5 (4投票s)
一个小程序,可以用来检查由 nunit-console 工具生成的测试结果。
问题概述
如果您使用 NUnit,可以使用 nunit-console 工具从构建脚本中运行测试。但是,这个测试运行器只是在控制台窗口中显示结果,并将报告保存到 XML 文件中。没有功能可以在 nunit-console 工具执行后检查测试结果,并根据这些结果执行某些操作。当然,有一些强大的构建工具可以做到这一点,例如 NAnt 或 FinalBuilder。但是,如果您仍然使用简单的 .bat 文件来构建您的产品,该怎么办?最重要的问题:如果某个单元测试失败,如何停止构建过程?
提出的解决方案
CheckTestResults 工具可以帮助解决这个问题。它可以分析 nunit-console 工具生成的 TestResult.xml 文件,显示所有找到的失败,为每个失败发出蜂鸣声,并且,如果在测试期间至少发生了一次失败,则最终停止执行并等待用户输入。
该工具是用 C# 编写的,需要 .NET 2.0(或更高版本)。这是源代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
namespace CheckTestResults {
class CheckTestResultsMain {
class ErrorItem {
public string Name;
public string Message;
public string StackTrace;
}
private static bool pauseOnError = true;
private static string resultFileName = "";
private static List<ErrorItem> errors;
static void Main(string[] args) {
Console.WriteLine("Check NUnit test results" +
" utility version 1.0.0");
Console.WriteLine("");
errors = new List<ErrorItem>();
if (args.Length > 0) {
// Load program arguments
for (int i = 0; i < args.Length; i++) {
if (args[i].StartsWith("-pause:")) {
string s = args[i].Substring("-pause:".Length);
pauseOnError = bool.Parse(s);
}
else
resultFileName = args[i];
}
}
else {
Console.WriteLine("Usage: CheckTestResults.exe" +
" <path to TestResult.xml file>");
return;
}
Console.WriteLine("Processing " +
resultFileName + "...");
Console.WriteLine("");
try {
//Analize test results file
FileStream fstream = new FileStream(resultFileName,
FileMode.Open, FileAccess.Read);
try {
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(fstream);
LoadTestResults(xmlDoc.DocumentElement);
}
finally {
fstream.Close();
}
}
catch (Exception ex) {
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Error occur: ");
Console.ForegroundColor = ConsoleColor.Magenta;
Console.WriteLine(ex.Message);
Console.Beep();
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine("");
Console.WriteLine("Press any key to continue...");
Console.ReadKey(true);
return;
}
if (errors.Count > 0) {
Console.ForegroundColor = ConsoleColor.Red;
//Print errors
Console.WriteLine("Tests failed");
Console.WriteLine("");
for (int I = 0; I < errors.Count; I++) {
Console.ForegroundColor = ConsoleColor.Magenta;
Console.WriteLine(" " + (I + 1).ToString() +
": " + errors[I].Name);
Console.ForegroundColor = ConsoleColor.Cyan;
Console.Write(errors[I].Message);
Console.ForegroundColor = ConsoleColor.DarkYellow;
Console.Write(errors[I].StackTrace);
Console.Beep();
Console.WriteLine("");
Console.WriteLine("");
}
//Stop and wait for user input
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine("");
Console.WriteLine("Press any key to continue...");
Console.ReadKey(true);
}
else {
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Testing succeeded!");
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine("");
}
}
private static void LoadTestResults(XmlElement rootNode) {
foreach (XmlNode node in rootNode.ChildNodes) {
if (node is XmlElement &&
node.LocalName == "test-suite")
LoadTestSuite((XmlElement)node);
}
}
private static void LoadTestSuite(XmlElement suiteNode) {
foreach (XmlNode node in suiteNode.ChildNodes) {
if (node is XmlElement &&
node.LocalName == "results") {
foreach (XmlNode subNode in node.ChildNodes) {
if (subNode is XmlElement ) {
if (subNode.LocalName == "test-suite") {
LoadTestSuite((XmlElement)subNode);
}
else if (subNode.LocalName == "test-case") {
LoadTestCase((XmlElement)subNode);
}
}
}
}
}
}
private static void LoadTestCase(XmlElement caseNode) {
foreach (XmlNode node in caseNode.ChildNodes) {
if (node is XmlElement &&
node.LocalName == "failure") {
LoadTestFailure((XmlElement)node);
}
}
}
private static void LoadTestFailure(XmlElement failureNode) {
ErrorItem error = new ErrorItem();
error.Name =
failureNode.ParentNode.Attributes["name"].Value;
foreach (XmlNode node in failureNode.ChildNodes) {
if (node.LocalName == "message") {
error.Message = node.FirstChild.Value;
}
else if (node.LocalName == "stack-trace") {
error.StackTrace = node.FirstChild.Value;
}
}
errors.Add(error);
}
}
}
使用代码
要使用 CheckTestResults,只需使用一个参数调用它:由 nunit-console 生成的 TestResult.xml 文件的路径。因此,您的构建脚本将如下所示:
nunit-console MyProject\Tests\bin\Debug\MyProjectTests.dll
CheckTestsResult.exe TestResult.xml