TestResult
The TestResult class represents the result of a test.
using NUnit.Framework.Interfaces;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;
namespace NUnit.Framework.Internal
{
public abstract class TestResult : ITestResult, IXmlNodeBuilder
{
public static readonly string CHILD_ERRORS_MESSAGE = "One or more child tests had errors";
public static readonly string CHILD_IGNORE_MESSAGE = "One or more child tests were ignored";
private List<ITestResult> _children;
private StringWriter _outWriter;
public ITest Test { get; set; }
public ResultState ResultState { get; set; }
public virtual string Name => Test.Name;
public virtual string FullName => Test.FullName;
public TimeSpan Duration { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string Message { get; set; }
public string EscapedMessage => EscapeInvalidXmlCharacters(Message);
public virtual string StackTrace { get; set; }
public int AssertCount { get; set; }
public abstract int FailCount { get; }
public abstract int PassCount { get; }
public abstract int SkipCount { get; }
public abstract int InconclusiveCount { get; }
public bool HasChildren {
get {
if (_children != null)
return _children.Count > 0;
return false;
}
}
public IList<ITestResult> Children {
get {
if (_children == null)
_children = new List<ITestResult>();
return _children;
}
}
public StringWriter OutWriter {
get {
if (_outWriter == null)
_outWriter = new StringWriter();
return _outWriter;
}
}
public string Output {
get {
if (_outWriter != null)
return _outWriter.ToString();
return string.Empty;
}
}
public TestResult(ITest test)
{
Test = test;
ResultState = ResultState.Inconclusive;
}
public XmlNode ToXml(bool recursive)
{
XmlNode xmlNode = XmlNode.CreateTopLevelElement("dummy");
AddToXml(xmlNode, recursive);
return xmlNode.FirstChild;
}
public virtual XmlNode AddToXml(XmlNode parentNode, bool recursive)
{
XmlNode xmlNode = Test.AddToXml(parentNode, false);
xmlNode.AddAttribute("result", ResultState.Status.ToString());
if (ResultState.Label != string.Empty)
xmlNode.AddAttribute("label", ResultState.Label);
if (ResultState.Site != 0)
xmlNode.AddAttribute("site", ResultState.Site.ToString());
xmlNode.AddAttribute("start-time", StartTime.ToString("u"));
xmlNode.AddAttribute("end-time", EndTime.ToString("u"));
xmlNode.AddAttribute("duration", Duration.TotalSeconds.ToString("0.000000", NumberFormatInfo.InvariantInfo));
if (Test is TestSuite) {
xmlNode.AddAttribute("total", (PassCount + FailCount + SkipCount + InconclusiveCount).ToString());
xmlNode.AddAttribute("passed", PassCount.ToString());
xmlNode.AddAttribute("failed", FailCount.ToString());
xmlNode.AddAttribute("inconclusive", InconclusiveCount.ToString());
xmlNode.AddAttribute("skipped", SkipCount.ToString());
}
xmlNode.AddAttribute("asserts", AssertCount.ToString());
switch (ResultState.Status) {
case TestStatus.Failed:
AddFailureElement(xmlNode);
break;
case TestStatus.Skipped:
AddReasonElement(xmlNode);
break;
case TestStatus.Inconclusive:
case TestStatus.Passed:
if (Message != null)
AddReasonElement(xmlNode);
break;
}
if (Output.Length > 0)
AddOutputElement(xmlNode);
if (recursive && HasChildren) {
foreach (TestResult child in Children) {
child.AddToXml(xmlNode, recursive);
}
return xmlNode;
}
return xmlNode;
}
public virtual void AddResult(ITestResult result)
{
Children.Add(result);
if (ResultState != ResultState.Cancelled) {
switch (result.ResultState.Status) {
case TestStatus.Passed:
if (ResultState.Status == TestStatus.Inconclusive)
SetResult(ResultState.Success);
break;
case TestStatus.Failed:
if (ResultState.Status != TestStatus.Failed)
SetResult(ResultState.ChildFailure, CHILD_ERRORS_MESSAGE);
break;
case TestStatus.Skipped:
if (result.ResultState.Label == "Ignored" && (ResultState.Status == TestStatus.Inconclusive || ResultState.Status == TestStatus.Passed))
SetResult(ResultState.Ignored, CHILD_IGNORE_MESSAGE);
break;
}
}
}
public void SetResult(ResultState resultState)
{
SetResult(resultState, null, null);
}
public void SetResult(ResultState resultState, string message)
{
SetResult(resultState, message, null);
}
public void SetResult(ResultState resultState, string message, string stackTrace)
{
ResultState = resultState;
Message = message;
StackTrace = stackTrace;
}
public void RecordException(Exception ex)
{
if (ex is NUnitException)
ex = ex.InnerException;
if (ex is ResultStateException)
SetResult(((ResultStateException)ex).ResultState, ex.Message, StackFilter.Filter(ex.StackTrace));
else if (ex is ThreadAbortException) {
SetResult(ResultState.Cancelled, "Test cancelled by user", ex.StackTrace);
} else {
SetResult(ResultState.Error, ExceptionHelper.BuildMessage(ex), ExceptionHelper.BuildStackTrace(ex));
}
}
public void RecordException(Exception ex, FailureSite site)
{
if (ex is NUnitException)
ex = ex.InnerException;
if (ex is ResultStateException)
SetResult(((ResultStateException)ex).ResultState.WithSite(site), ex.Message, StackFilter.Filter(ex.StackTrace));
else if (ex is ThreadAbortException) {
SetResult(ResultState.Cancelled.WithSite(site), "Test cancelled by user", ex.StackTrace);
} else {
SetResult(ResultState.Error.WithSite(site), ExceptionHelper.BuildMessage(ex), ExceptionHelper.BuildStackTrace(ex));
}
}
public void RecordTearDownException(Exception ex)
{
if (ex is NUnitException)
ex = ex.InnerException;
ResultState resultState = (ResultState == ResultState.Cancelled) ? ResultState.Cancelled : ResultState.Error;
if (Test.IsSuite)
resultState = resultState.WithSite(FailureSite.TearDown);
string text = "TearDown : " + ExceptionHelper.BuildMessage(ex);
if (Message != null)
text = Message + Env.NewLine + text;
string text2 = "--TearDown" + Env.NewLine + ExceptionHelper.BuildStackTrace(ex);
if (StackTrace != null)
text2 = StackTrace + Env.NewLine + text2;
SetResult(resultState, text, text2);
}
private XmlNode AddReasonElement(XmlNode targetNode)
{
XmlNode xmlNode = targetNode.AddElement("reason");
xmlNode.AddElement("message").TextContent = EscapedMessage;
return xmlNode;
}
private XmlNode AddFailureElement(XmlNode targetNode)
{
XmlNode xmlNode = targetNode.AddElement("failure");
if (Message != null)
xmlNode.AddElement("message").TextContent = EscapedMessage;
if (StackTrace != null)
xmlNode.AddElement("stack-trace").TextContent = StackTrace;
return xmlNode;
}
private XmlNode AddOutputElement(XmlNode targetNode)
{
XmlNode xmlNode = targetNode.AddElement("output");
xmlNode.TextContent = Output;
return xmlNode;
}
private static string EscapeInvalidXmlCharacters(string str)
{
Regex regex = new Regex("[^\t\n\r -�]|([�-�](?![�-�]))|((?<![�-�])[�-�])");
return regex.Replace(str, (Match match) => CharToUnicodeSequence(match.Value[0]));
}
private static string CharToUnicodeSequence(char symbol)
{
int num = symbol;
return string.Format("\\u{0}", num.ToString("x4"));
}
}
}