【问题标题】:How can I make a unit test run in DEBUG mode only?如何使单元测试仅在 DEBUG 模式下运行?
【发布时间】:2009-10-30 11:22:24
【问题描述】:

我有一个单元测试来测试是否抛出异常,但是这个异常只在调试模式下抛出(通过 [Conditional("DEBUG")] 属性)。如果我在发布模式下运行此测试,它会失败。我尝试在测试中应用相同的属性,但没有考虑在内。

如何在发布模式下排除测试?在发布模式下运行单元测试是否有意义,还是应该坚持调试模式?

【问题讨论】:

标签: .net unit-testing debugging


【解决方案1】:

至于您的大部分问题,这在一定程度上取决于您使用的单元测试工具。但是,一般来说你想要的是preprocessor directives

//C#
#ifndef DEBUG
    //Unit test
#endif

也许适合你的情况

//C# - for NUnit
#if !DEBUG
    [Ignore("This test runs only in debug")] 
#endif 

但至于是否在发布版本中留下单元测试?我会给出一个响亮的NO。我建议将你所有的单元测试移到它自己的项目中,而不是在你的版本中包含它。

【讨论】:

  • 当然,我所有的单元测试都在另一个项目中,但我仍然可以在发布模式下运行它们...
  • 为什么你真的希望它们在发布和调试方面有所不同?
  • 我想确保我的代码在调试和发布模式下的行为相同。但在这种特殊情况下,我知道测试将在发布模式下失败,因为异常应该只在调试模式下抛出(按设计)
  • 好吧,我想出了一个可能的解决方案,前提是您使用 NUnit。
  • 我最终还是使用了您的解决方案。由于我使用的是 MSTest,因此属性为 [Ignore](无参数)。
【解决方案2】:

试试这个:

#if DEBUG

// here is your test

#endif

【讨论】:

  • 这可行,但我认为这是一个过于激进的解决方案。相反,我使用了 [Ignore] 属性(不过,它包含在 #if !DEBUG ... #endif 中,但我更喜欢它)。
【解决方案3】:

如果你使用 NUnit,你可以让你的单元测试方法有条件:

[System.Diagnostics.Conditional("DEBUG")]
public void UnitTestMethod()
{
   // Tests here
}

这样它只会在 DEBUG 构建中执行。我在 Visual Studio 单元测试方面没有太多经验,但我很确定这也应该在 VS 中工作。

编辑:其他人提到了条件编译指令。出于多种原因,我认为这不是一个好主意。要详细了解条件编译指令和条件属性之间的区别,请阅读Eric Lippert's excellent article here

【讨论】:

  • 我正在使用 MSTest,看起来测试引擎不支持条件属性...
  • 您可以将条件属性放在 DoUnitTestMethod 辅助方法上,您可以从 UnitTestMethod 调用该方法。这将成为一个始终在发布模式下通过的空测试。不过,使用 [ExpectedException] 之类的东西会变得更加棘手。最简单的是在整个测试用例中使用#if DEBUG。
【解决方案4】:

如果你使用的是 XUnit,你可以通过扩展 fact 属性来使用下面的方法as described by Jimmy Bogard

public class RunnableInDebugOnlyAttribute : FactAttribute
{
    public RunnableInDebugOnlyAttribute()
    {
        if (!Debugger.IsAttached)
        {
            Skip = "Only running in interactive mode.";
        }
    }
}

然后你可以按如下方式使用它:

[RunnableInDebugOnly]
public void Test_RunOnlyWhenDebugging()
{
    //your test code
}

【讨论】:

    【解决方案5】:

    NUnit 框架的类似解决方案(仅调试测试有效):

    public class DebugOnlyAttribute : NUnitAttribute, IApplyToTest
    {
    
        private const string _reason = "Debug only";
    
        public void ApplyToTest(Test test)
        {
            if (!Debugger.IsAttached)
            {
                test.RunState = RunState.Ignored;
                test.Properties.Set(PropertyNames.SkipReason, _reason);
            }
    
        }
    }
    
    [DebugOnly]
    [Test]
    public void TestMethod()
    { 
    //your test code
    }
    

    【讨论】:

      猜你喜欢
      • 2011-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多