【问题标题】:NUnit conflict with Debug.AssertNUnit 与 Debug.Assert 冲突
【发布时间】:2010-02-26 10:29:21
【问题描述】:

我正在使用 NUnit 为我的同事编写的库编写单元测试。他的库包含许多 Debug.Asserts 触发无效输入。当我编写单元测试并向他的库提供无效输入时,他的 Debug.Assert 会抛出一个消息框,抱怨输入错误。

我觉得他的库对无效输入抛出断言是一件好事,但同时我希望单元测试能够覆盖错误输入。但是当我这样做时,会出现消息框,我必须手动单击“确定”才能继续进行剩余的单元测试。

如果不清楚,我的问题是单元测试过程在 Debug.Assert 上停止。人们应该在任何签入之前运行他们的单元测试,并且它应该是自动的并且不应该抛出消息,除非测试失败..

在这种情况下,“最佳”方法是什么?

【问题讨论】:

    标签: c# nunit assert


    【解决方案1】:

    查看 Debug.Assert method 的 MSDN 文档。特别是在“备注”下,它解释了如何禁用 UI:

    <configuration>
      <system.diagnostics>
        <assert assertuienabled="false" logfilename="c:\\myFile.log" />
      </system.diagnostics>
    </configuration>
    

    因此,我建议应用程序配置文件默认具有此功能,并且您的同事只要觉得这样做有用就会打开 Assert to UI。

    【讨论】:

      【解决方案2】:

      正如 Henk 已经指出的,抑制 UI 是没有用的,因为您希望您的代码失败。当您不想更改代码时,可以编写一个引发异常的自定义跟踪侦听器,如下所示:

      public class ProductionTraceListener : DefaultTraceListener
      {
          public override void Fail(string message, string detailMessage)
          {
              string failMessage = message;
      
              if (detailMessage != null)
              {
                  failMessage += " " + detailMessage;
              }
      
              throw new AssertionFailedException(failMessage);
          }
      }
      
      [Serializable]
      public class AssertionFailedException : Exception
      {
          public AssertionFailedException() { }
          public AssertionFailedException(string message) : base(message) { }
          public AssertionFailedException(string message, Exception inner) 
              : base(message, inner) { }
          protected AssertionFailedException(SerializationInfo info,
              StreamingContext context) : base(info, context) { }
      }
      

      你可以按如下方式注册:

      <?xml version="1.0" encoding="utf-8" ?>
      <configuration>
        <system.diagnostics>
          <trace>
            <listeners>
              <clear />
              <add name="Default"
                type="[Namespace].ProductionTraceListener, [Assembly]" />
            </listeners>
          </trace>
        </system.diagnostics>
      </configuration>
      

      正如您对跟踪侦听器的名称 ProductionTraceListener 所期望的那样,我在我的生产环境(Web 应用程序)中使用了那个东西,而不是在我的单元测试中。虽然您可以在单元测试中使用此技巧,但我建议您更改代码。 IMO 你应该只对不应该运行的代码路径使用断言,如果他们这样做,测试应该失败。在您的情况下,您希望在断言失败时进行成功的测试,这是违反直觉的。

      我的建议是更改代码并使用普通的if (x) throw ArgumentException() 检查前提条件(或使用CuttingEdge.Conditions)并将这些断言仅用于不应运行的代码路径。还可以尝试使用Trace.Assert 而不是Debug.Assert,因为您还希望在生产环境中检查这些断言。完成后,您可以在生产环境中使用 ProductionTraceListener,在单元测试中使用 UnitTestTraceListener

      public class UnitTestTraceListener : DefaultTraceListener
      {
          public override void Fail(string message, string detailMessage)
          {
              string failMessage = message;
      
              if (detailMessage != null)
              {
                  failMessage += " " + detailMessage;
              }
      
              // Call to Assert method of used unit testing framework.
              Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Fail(
                  failMessage);
          }
      }
      

      祝你好运。

      【讨论】:

      • 这对于 Trace.Assert() 来说看起来不错,但 OP 提到了 Debug.Assert()。
      • 另外,您希望代码在作为自动化构建过程的一部分运行时在单元测试中失败。断言是为了让开发人员在运行代码时受益。
      • @Henk && @Rob:我不确定我是否关注你。在单元测试环境中配置ProductionTraceListener 将允许单元测试在方法没有抛出预期的AssertionFailedException 时失败。当单元测试在调试模式下运行时,这将完全按照他的意愿进行,不是吗?请赐教。
      • Steven,Debug.Assert() 不好,因为它使 Debug 构建的行为与 Release 构建不同。您要测试哪种行为?
      • Henk,这正是我建议使用Trace.Assert 的原因。让调试版本表现不同是一件坏事。我认为我们对此的看法相同。
      【解决方案3】:

      我认为有效的一个简单选项是使用标准 ConsoleTraceListener,这将允许 Debug.Assert 检查触发,但会将其输出定向到 NUnit 文本输出选项卡,而不会影响单元测试。

      您可以将其添加到您的测试设置中...

      [SetUp]
      public void SetUp()
      {
          // Replace pop-up assert trace listener with one that simply logs a message.
          Debug.Listeners.Clear();
          Debug.Listeners.Add(new ConsoleTraceListener());
      }
      

      只是不要忘记在测试失败时检查文本输出!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-29
        • 1970-01-01
        • 2010-11-30
        • 2012-01-04
        • 2017-12-09
        • 2013-10-21
        相关资源
        最近更新 更多