<PackageReference Include="NUnit" Version="3.11.0" />

TestResult

The TestResult class represents the result of a test.
using NUnit.Compatibility; using NUnit.Framework.Interfaces; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading; namespace NUnit.Framework.Internal { public abstract class TestResult : LongLivedMarshalByRefObject, ITestResult, IXmlNodeBuilder { private struct ExceptionResult { public ResultState ResultState { get; } public string Message { get; } public string StackTrace { get; } public ExceptionResult(Exception ex, FailureSite site) { ex = ValidateAndUnwrap(ex); if (ex is ResultStateException) { ResultState = ((ResultStateException)ex).ResultState.WithSite(site); Message = ex.Message; StackTrace = StackFilter.DefaultFilter.Filter(ex.StackTrace); } else if (ex is ThreadAbortException) { ResultState = ResultState.Cancelled.WithSite(site); Message = "Test cancelled by user"; StackTrace = ex.StackTrace; } else { ResultState = ResultState.Error.WithSite(site); Message = ExceptionHelper.BuildMessage(ex, false); StackTrace = ExceptionHelper.BuildStackTrace(ex); } } } internal static readonly string CHILD_ERRORS_MESSAGE = "One or more child tests had errors"; internal static readonly string CHILD_WARNINGS_MESSAGE = "One or more child tests had warnings"; internal static readonly string CHILD_IGNORE_MESSAGE = "One or more child tests were ignored"; internal const double MIN_DURATION = 1E-06; private readonly StringBuilder _output = new StringBuilder(); private double _duration; protected int InternalAssertCount; private ResultState _resultState; private string _message; private string _stackTrace; private readonly List<AssertionResult> _assertionResults = new List<AssertionResult>(); private readonly List<TestAttachment> _testAttachments = new List<TestAttachment>(); protected ReaderWriterLockSlim RwLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); public ITest Test { get; } 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 ICollection<TestAttachment> TestAttachments => new ReadOnlyCollection<TestAttachment>(_testAttachments); 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 WarningCount { 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; } public string Output { get { lock (OutWriter) { return _output.ToString(); } } } public IList<AssertionResult> AssertionResults => _assertionResults; public int PendingFailures => AssertionResults.Count((AssertionResult ar) => ar.Status == AssertionStatus.Failed); public AssertionStatus WorstAssertionStatus => AssertionResults.Aggregate(delegate(AssertionResult ar1, AssertionResult ar2) { if (ar1.Status <= ar2.Status) return ar2; return ar1; }).Status; public TestResult(ITest test) { Test = test; ResultState = ResultState.Inconclusive; OutWriter = TextWriter.Synchronized(new StringWriter(_output)); } internal void AddTestAttachment(TestAttachment attachment) { _testAttachments.Add(attachment); } 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 = WarningCount; tNode8.AddAttribute("warnings", num.ToString()); TNode tNode9 = tNode; num = InconclusiveCount; tNode9.AddAttribute("inconclusive", num.ToString()); TNode tNode10 = tNode; num = SkipCount; tNode10.AddAttribute("skipped", num.ToString()); } TNode tNode11 = tNode; num = AssertCount; tNode11.AddAttribute("asserts", num.ToString()); status = ResultState.Status; if ((uint)status > 3) { if (status == TestStatus.Failed) AddFailureElement(tNode); } else if (Message != null && Message.Trim().Length > 0) { AddReasonElement(tNode); } if (Output.Length > 0) AddOutputElement(tNode); if (AssertionResults.Count > 0) AddAssertionsElement(tNode); if (_testAttachments.Count > 0) AddAttachmentsElement(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) { ExceptionResult exceptionResult = new ExceptionResult(ex, FailureSite.Test); SetResult(exceptionResult.ResultState, exceptionResult.Message, exceptionResult.StackTrace); if (AssertionResults.Count > 0 && exceptionResult.ResultState == ResultState.Error) { Message += CreateLegacyFailureMessage(); AssertionResults.Add(new AssertionResult(AssertionStatus.Error, exceptionResult.Message, exceptionResult.StackTrace)); } } public void RecordException(Exception ex, FailureSite site) { ExceptionResult exceptionResult = new ExceptionResult(ex, site); SetResult(exceptionResult.ResultState, exceptionResult.Message, exceptionResult.StackTrace); } public void RecordTearDownException(Exception ex) { ex = ValidateAndUnwrap(ex); ResultState resultState = (ResultState == ResultState.Cancelled) ? ResultState.Cancelled : ResultState.Error; if (Test.IsSuite) resultState = resultState.WithSite(FailureSite.TearDown); string text = "TearDown : " + ExceptionHelper.BuildMessage(ex, false); if (Message != null) text = Message + Environment.NewLine + text; string text2 = "--TearDown" + Environment.NewLine + ExceptionHelper.BuildStackTrace(ex); if (StackTrace != null) text2 = StackTrace + Environment.NewLine + text2; SetResult(resultState, text, text2); } private static Exception ValidateAndUnwrap(Exception ex) { Guard.ArgumentNotNull(ex, "ex"); if ((ex is NUnitException || ex is TargetInvocationException) && ex.InnerException != null) return ex.InnerException; return ex; } public void RecordTestCompletion() { switch (AssertionResults.Count) { case 0: SetResult(ResultState.Success); break; case 1: SetResult(AssertionStatusToResultState(AssertionResults[0].Status), AssertionResults[0].Message, AssertionResults[0].StackTrace); break; default: SetResult(AssertionStatusToResultState(WorstAssertionStatus), CreateLegacyFailureMessage()); break; } } public void RecordAssertion(AssertionResult assertion) { _assertionResults.Add(assertion); } public void RecordAssertion(AssertionStatus status, string message, string stackTrace) { RecordAssertion(new AssertionResult(status, message, stackTrace)); } public void RecordAssertion(AssertionStatus status, string message) { RecordAssertion(status, message, null); } private string CreateLegacyFailureMessage() { StringWriter stringWriter = new StringWriter(); if (AssertionResults.Count > 1) stringWriter.WriteLine("Multiple failures or warnings in test:"); int num = 0; foreach (AssertionResult assertionResult in AssertionResults) { stringWriter.WriteLine($"""{++num}""{assertionResult.Message}"); } return stringWriter.ToString(); } 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 && Message.Trim().Length > 0) tNode.AddElementWithCDATA("message", Message); if (StackTrace != null && StackTrace.Trim().Length > 0) tNode.AddElementWithCDATA("stack-trace", StackTrace); return tNode; } private TNode AddOutputElement(TNode targetNode) { return targetNode.AddElementWithCDATA("output", Output); } private TNode AddAssertionsElement(TNode targetNode) { TNode tNode = targetNode.AddElement("assertions"); foreach (AssertionResult assertionResult in AssertionResults) { TNode tNode2 = tNode.AddElement("assertion"); tNode2.AddAttribute("result", assertionResult.Status.ToString()); if (assertionResult.Message != null) tNode2.AddElementWithCDATA("message", assertionResult.Message); if (assertionResult.StackTrace != null) tNode2.AddElementWithCDATA("stack-trace", assertionResult.StackTrace); } return tNode; } private ResultState AssertionStatusToResultState(AssertionStatus status) { switch (status) { case AssertionStatus.Inconclusive: return ResultState.Inconclusive; default: return ResultState.Success; case AssertionStatus.Warning: return ResultState.Warning; case AssertionStatus.Failed: return ResultState.Failure; case AssertionStatus.Error: return ResultState.Error; } } private TNode AddAttachmentsElement(TNode targetNode) { TNode tNode = targetNode.AddElement("attachments"); foreach (TestAttachment testAttachment in _testAttachments) { TNode tNode2 = tNode.AddElement("attachment"); tNode2.AddElement("filePath", testAttachment.FilePath); if (testAttachment.Description != null) tNode2.AddElementWithCDATA("description", testAttachment.Description); } return tNode; } } }