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;
using System.Threading;
namespace NUnit.Framework.Internal
{
public abstract class TestResult : ITestResult, IXmlNodeBuilder
{
internal static readonly string CHILD_ERRORS_MESSAGE = "One or more child tests had errors";
internal static readonly string CHILD_IGNORE_MESSAGE = "One or more child tests were ignored";
internal const double MIN_DURATION = 1E-06;
private StringBuilder _output = new StringBuilder();
private double _duration;
protected int InternalAssertCount;
private ResultState _resultState;
private string _message;
private string _stackTrace;
protected ReaderWriterLockSlim RwLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
public ITest Test { get; set; }
public ResultState ResultState {
get {
RwLock.EnterReadLock();
try {
return _resultState;
} finally {
RwLock.ExitReadLock();
}
}
private set {
_resultState = value;
}
}
public virtual string Name => Test.Name;
public virtual string FullName => Test.FullName;
public double Duration {
get {
return _duration;
}
set {
_duration = ((value >= 1E-06) ? value : 1E-06);
}
}
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string Message {
get {
RwLock.EnterReadLock();
try {
return _message;
} finally {
RwLock.ExitReadLock();
}
}
private set {
_message = value;
}
}
public virtual string StackTrace {
get {
RwLock.EnterReadLock();
try {
return _stackTrace;
} finally {
RwLock.ExitReadLock();
}
}
private set {
_stackTrace = value;
}
}
public int AssertCount {
get {
RwLock.EnterReadLock();
try {
return InternalAssertCount;
} finally {
RwLock.ExitReadLock();
}
}
internal set {
InternalAssertCount = value;
}
}
public abstract int FailCount { get; }
public abstract int PassCount { get; }
public abstract int SkipCount { get; }
public abstract int InconclusiveCount { get; }
public abstract bool HasChildren { get; }
public abstract IEnumerable<ITestResult> Children { get; }
public TextWriter OutWriter { get; set; }
public string Output => _output.ToString();
public TestResult(ITest test)
{
Test = test;
ResultState = ResultState.Inconclusive;
OutWriter = TextWriter.Synchronized(new StringWriter(_output));
}
public TNode ToXml(bool recursive)
{
return AddToXml(new TNode("dummy"), recursive);
}
public virtual TNode AddToXml(TNode parentNode, bool recursive)
{
TNode tNode = Test.AddToXml(parentNode, false);
TNode tNode2 = tNode;
TestStatus status = ResultState.Status;
tNode2.AddAttribute("result", status.ToString());
if (ResultState.Label != string.Empty)
tNode.AddAttribute("label", ResultState.Label);
if (ResultState.Site != 0)
tNode.AddAttribute("site", ResultState.Site.ToString());
TNode tNode3 = tNode;
DateTime dateTime = StartTime;
tNode3.AddAttribute("start-time", dateTime.ToString("u"));
TNode tNode4 = tNode;
dateTime = EndTime;
tNode4.AddAttribute("end-time", dateTime.ToString("u"));
tNode.AddAttribute("duration", Duration.ToString("0.000000", NumberFormatInfo.InvariantInfo));
int num;
if (Test is TestSuite) {
TNode tNode5 = tNode;
num = PassCount + FailCount + SkipCount + InconclusiveCount;
tNode5.AddAttribute("total", num.ToString());
TNode tNode6 = tNode;
num = PassCount;
tNode6.AddAttribute("passed", num.ToString());
TNode tNode7 = tNode;
num = FailCount;
tNode7.AddAttribute("failed", num.ToString());
TNode tNode8 = tNode;
num = InconclusiveCount;
tNode8.AddAttribute("inconclusive", num.ToString());
TNode tNode9 = tNode;
num = SkipCount;
tNode9.AddAttribute("skipped", num.ToString());
}
TNode tNode10 = tNode;
num = AssertCount;
tNode10.AddAttribute("asserts", num.ToString());
status = ResultState.Status;
switch (status) {
case TestStatus.Failed:
AddFailureElement(tNode);
break;
case TestStatus.Inconclusive:
case TestStatus.Skipped:
case TestStatus.Passed:
if (Message != null)
AddReasonElement(tNode);
break;
}
if (Output.Length > 0)
AddOutputElement(tNode);
if (recursive && HasChildren) {
foreach (TestResult child in Children) {
child.AddToXml(tNode, recursive);
}
return tNode;
}
return tNode;
}
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)
{
RwLock.EnterWriteLock();
try {
ResultState = resultState;
Message = message;
StackTrace = stackTrace;
} finally {
RwLock.ExitWriteLock();
}
}
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 TNode AddReasonElement(TNode targetNode)
{
return targetNode.AddElement("reason").AddElementWithCDATA("message", Message);
}
private TNode AddFailureElement(TNode targetNode)
{
TNode tNode = targetNode.AddElement("failure");
if (Message != null)
tNode.AddElementWithCDATA("message", Message);
if (StackTrace != null)
tNode.AddElementWithCDATA("stack-trace", StackTrace);
return tNode;
}
private TNode AddOutputElement(TNode targetNode)
{
return targetNode.AddElementWithCDATA("output", Output);
}
}
}