NUnit, is it possible to continue executing test after Assert fails?
NUnit 3.6 adds Assert.Multiple
method and MultipleAsserts
attribute.
See https://docs.nunit.org/articles/nunit/writing-tests/assertions/multiple-asserts.html
I prefer to be practical and put several related assertions in one method.
I have a helper class which enables the following syntax (I use):
AssertAll.Succeed(
() => Assert.AreEqual("bb", id.Context),
() => Assert.AreEqual("abc", id.FullName),
() => Assert.AreEqual("b", id.SessionID));
which gives me error messages like this:
Assert.AreEqual failed. Expected:<bb>. Actual:<b\c>.
Assert.AreEqual failed. Expected:<abc>. Actual:<[b\c]a{103}>.
at FXP_COM.Tests.EnumToStringConverterterTests.<>c__DisplayClass3.<ShouldConvert>b__0() in UnitTest1.cs: line 31
at FXP_COM.Tests.AssertAll.Succeed(Action[] assertions) in UnitTest1.cs: line 46 at FXP_COM.Tests.AssertAll.Succeed(Action[] assertions) in UnitTest1.cs: line 62
at FXP_COM.Tests.EnumToStringConverterterTests.ShouldConvert() in UnitTest1.cs: line 30
and the helper class is the following:
using System;
using NUnit.Framework;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
public static class AssertAll
{
public static void Succeed(params Action[] assertions)
{
var errors = new List<Exception>();
foreach (var assertion in assertions)
try
{
assertion();
}
catch (Exception ex)
{
errors.Add(ex);
}
if (errors.Any())
{
var ex = new AssertionException(
string.Join(Environment.NewLine, errors.Select(e => e.Message)),
errors.First());
// Use stack trace from the first exception to ensure first
// failed Assert is one click away
ReplaceStackTrace(ex, errors.First().StackTrace);
throw ex;
}
}
static void ReplaceStackTrace(Exception exception, string stackTrace)
{
var remoteStackTraceString = typeof(Exception)
.GetField("_remoteStackTraceString",
BindingFlags.Instance | BindingFlags.NonPublic);
remoteStackTraceString.SetValue(exception, stackTrace);
}
}
No you can't do it with NUnit alone. You have to do something like @Konstantin Spirin said. I created a small extension that you can use; it's called NUnit-GroupAssert. It can be found here: https://github.com/slvnperron/NUnit-GroupAssert
How to use it:
[Test]
public void Verify_GroupsExceptions()
{
var group = new AssertGroup();
group.Add(() => Assert.AreEqual(10, 20));
group.Add(() => Assert.AreEqual(1, 1));
group.Add(() => Assert.AreEqual(3, 4));
group.Add(() => Assert.IsTrue(1 > 3));
group.Verify();
}
// OR
public void Verify_GroupsExceptions()
{
// Verifies on disposal
using (var group = new AssertGroup())
{
group.Add(() => Assert.AreEqual(10, 20));
group.Add(() => Assert.AreEqual(1, 1));
group.Add(() => Assert.AreEqual(3, 4));
group.Add(() => Assert.IsTrue(1 > 3));
}
}
it will output:
Test failed because one or more assertions failed:
1) Expected: 10
But was: 20
From Verify_GroupsExceptions at line 182) Expected: 3
But was: 4
From Verify_GroupsExceptions at line 203) Expected: True
But was: False
From Verify_GroupsExceptions at line 21
No. Typically in this situation you would put all the code above the asserts into a setup method, then write each assert into its own test case.