NUnit, is it possible to continue executing test after Assert fails?

前端 未结 9 2105
伪装坚强ぢ
伪装坚强ぢ 2020-12-29 19:42

In a test that contains some asserts, for example:

Assert.AreEqual(1,1);
Assert.AreEqual(2,1);
Assert.AreEqual(2,2);

is it possible to let

相关标签:
9条回答
  • 2020-12-29 20:12

    Asserts thrown an NUnit.Framework.AssertionException if they fail. You could catch that exception on the second assert, evaluate the third assert, then re-throw the exception.

    Not something I'd recommend, though, for the reasons pointed-out by Ed Woodcock and Carl Manaster.

    0 讨论(0)
  • 2020-12-29 20:17

    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);
        }
    }
    
    0 讨论(0)
  • 2020-12-29 20:24

    NUnit 3.6 adds Assert.Multiple method and MultipleAsserts attribute.

    See https://github.com/nunit/docs/wiki/Multiple-Asserts.

    0 讨论(0)
  • 2020-12-29 20:25

    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.

    0 讨论(0)
  • 2020-12-29 20:28

    You can cheat a little and not actually fail at a given point, but rather mark for failure, then fail at the very end, something like the following:

    var sbError = new StringBuilder();
    if (!SomeCondition()) {
      sbError.AppendLine("SomeCondition failed");
    }
    if (!SomeOtherCondition()) {
      sbError.AppendLine("SomeOtherCondition failed");
    }
    Assert.AreEqual(0, sbError.Length, sbError.ToString());
    

    I wouldn't recommend this, but if you need to do it once or twice, it shouldn't be that bad.

    0 讨论(0)
  • 2020-12-29 20:28

    You could restructure your test to wrap the assertions in try/catch block and keep track of them for later validation. I don't recommend this, however. You really should be using separate tests for each condition if you want them to be tested independently.

      bool[] assertionSuccesses = new bool[] { false, false, false };
    
      try
      {
           Assert.AreEqual( 1, 1 );
           assertionSuccesses[0] = true;
      }
      catch (AssertionException) {}
      ...
    
      if (assertionSuccesses.Any( s => !s ))
      {
           Assert.Fail("one of the assertions failed");
      }
    
    0 讨论(0)
提交回复
热议问题