diff --git a/Directory.Build.props b/Directory.Build.props
index 940dda1..3943ac4 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -18,8 +18,8 @@
-
-
+
+
diff --git a/src/Heleonix.Testing.NUnit/Internal/TestHost.cs b/src/Heleonix.Testing.NUnit/Internal/TestHost.cs
index 8050084..0aeb5a4 100644
--- a/src/Heleonix.Testing.NUnit/Internal/TestHost.cs
+++ b/src/Heleonix.Testing.NUnit/Internal/TestHost.cs
@@ -8,7 +8,11 @@ namespace Heleonix.Testing.NUnit.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
using System.Text.RegularExpressions;
+using global::NUnit.Framework;
+using global::NUnit.Framework.Interfaces;
using global::NUnit.Framework.Internal;
///
@@ -89,8 +93,17 @@ public void Execute(SpecNode node)
TestExecutionContext.CurrentContext.OutWriter.WriteLine($"{new string(' ', node.NestingLevel * 4)}\u2713 {node.Description}");
}
}
- catch (Exception)
+ catch (Exception ex)
{
+ if (ex is not AssertionException)
+ {
+ var result = TestExecutionContext.CurrentContext.CurrentResult;
+
+ result.RecordAssertion(AssertionStatus.Failed, ex.Message, ex.StackTrace);
+
+ result.RecordTestCompletion();
+ }
+
if (node.IsAssertable)
{
TestExecutionContext.CurrentContext.OutWriter.WriteLine($"{new string(' ', node.NestingLevel * 4)}\u2717 {node.Description}");
@@ -110,7 +123,7 @@ private void ValidateAdding(SpecNode child)
{
if (!this.SpecStructureRules.ContainsKey(child.Type))
{
- throw new InvalidOperationException($"The spec '{child.Type}' is not valid for the current test pattern");
+ throw new InvalidOperationException($"The spec '{child.Type}' is not valid for the current test pattern.");
}
var rule = this.SpecStructureRules[child.Type];
@@ -119,7 +132,7 @@ private void ValidateAdding(SpecNode child)
&& !Regex.IsMatch(string.Join(",", this.specExecutionStack), rule.SpecExecutionStackRule))
{
throw new InvalidOperationException($"Invalid test structure: cannot place the '{child.Type}' " +
- $"into the '{string.Join("->", this.specExecutionStack.Reverse())}'");
+ $"into the '{string.Join("->", this.specExecutionStack.Reverse())}'.");
}
if (rule.PredecessorsRule != null)
@@ -129,7 +142,7 @@ private void ValidateAdding(SpecNode child)
if (!Regex.IsMatch(string.Join(",", parent.Children.Reverse()), rule.PredecessorsRule))
{
throw new InvalidOperationException($"Invalid test structure: cannot place the '{child.Type}' " +
- $"after the '{string.Join("->", parent.Children)}'");
+ $"after the '{string.Join("->", parent.Children)}'.");
}
}
}
diff --git a/test/Heleonix.Testing.NUnit.Tests/Internal/TestHostTests.cs b/test/Heleonix.Testing.NUnit.Tests/Internal/TestHostTests.cs
index ef89216..596e4e3 100644
--- a/test/Heleonix.Testing.NUnit.Tests/Internal/TestHostTests.cs
+++ b/test/Heleonix.Testing.NUnit.Tests/Internal/TestHostTests.cs
@@ -9,7 +9,9 @@ namespace Heleonix.Testing.NUnit.Tests.Internal;
using System.Collections.Generic;
using System.Reflection;
using global::NUnit.Framework;
+using global::NUnit.Framework.Interfaces;
using global::NUnit.Framework.Internal;
+using global::NUnit.Framework.Internal.Builders;
using Heleonix.Testing.NUnit.Internal;
using Moq;
using Moq.Protected;
@@ -268,7 +270,7 @@ public static void ValidateAdding6()
///
/// Tests writing of a failed test with marking into the Output.
///
- [Test(Description = "When an assertable node is throwing an exception Should write the test description as failed into the output")]
+ [Test(Description = "When an assertable node is throwing an exception Should write the test description as failed into the output and write failure result")]
public static void Execute1()
{
// Arrange
@@ -285,16 +287,33 @@ public static void Execute1()
var rootNode = new SpecNode(SpecNodeType.Root, null, () => { });
- var node = new SpecNode(SpecNodeType.Should, "description", () => { throw new InvalidOperationException(); }, true);
+ var node = new SpecNode(
+ SpecNodeType.Should,
+ "description",
+ () => { throw new InvalidOperationException("Custom exception message."); },
+ true);
rootNode.Add(node);
+ var prevResult = TestExecutionContext.CurrentContext.CurrentResult;
+
+ // Substitute the current test result to catch SpecNode execution.
+ TestExecutionContext.CurrentContext.CurrentResult =
+ TestExecutionContext.CurrentContext.CurrentTest.MakeTestResult();
+
// Act
methodInfo.Invoke(testHostMock.Object, new[] { node });
+ var failCount = TestExecutionContext.CurrentContext.CurrentResult.FailCount;
+ var message = TestExecutionContext.CurrentContext.CurrentResult.Message;
+ var stackTrace = TestExecutionContext.CurrentContext.CurrentResult.StackTrace;
+
+ TestExecutionContext.CurrentContext.CurrentResult = prevResult;
+
// Assert
- // Cannot read the NUnit Output, so rely on the 100% test coverage.
- Assert.True(true);
+ Assert.That(failCount, Is.EqualTo(1));
+ Assert.That(message, Contains.Substring("Custom exception message."));
+ Assert.That(stackTrace, Is.Not.Empty);
}
///