【问题标题】:Inconsistent test results when using dotCover使用 dotCover 时测试结果不一致
【发布时间】:2012-02-19 11:43:01
【问题描述】:

我有一些带有单元测试的代码,这些代码在调试版本中通过,但在发布版本中失败,这是正确的。但是,当使用 JetBrains dotCover 运行时,相同的测试在 Debug 和 Release 模式下都会通过。

为了提供一些背景知识,这里是有问题的测试代码,只是为了让您了解它在发布版本中失败的原因 - 这基本上是因为代码优化导致堆栈信息减少。

using System.Diagnostics;
using NUnit.Framework;

namespace DotCoverTest
{
    [TestFixture]
    public class TestLogger
    {
        [Test]
        public void GetCurrentClassLoggerReturnsLoggerWithOwningTypeName()
        {
            Assert.AreEqual(Logger.GetCurrentClassLogger(), GetType().Name);
        }
    }

    public class Logger
    {
        public static string GetCurrentClassLogger()
        {
            return new StackFrame(1, false).GetMethod().DeclaringType.Name;
        }
    }
}

编辑: 有什么想法可以设置我的构建,以便在使用或不使用覆盖工具的情况下获得相同的测试结果?

注意:最初发布此问题时认为这是 TeamCity 的问题,但事实并非如此。

【问题讨论】:

  • 您确定 TeamCity 中的 Release 版本实际上使用的是 Release dll 而不是 Debug 的?
  • 查看运行单元测试的构建脚本会很有用
  • 感谢小伙子们的回复——我在原帖中添加了更多关于该问题的信息

标签: .net unit-testing nunit continuous-integration teamcity


【解决方案1】:

我相信这里的主要问题是Tail call optimization,编译器会折叠堆栈帧以提高性能。这仅在发布模式下发生。

dotCover(与其他 .net 分析器一样)禁用 CLR 的一些优化,防止结果受损 - 如果方法执行不执行,则很难计算它们的执行次数……

我无法告诉您 NCover 是否无法克服优化问题,或者以其他方式解决此问题,但我对 dotCover 非常确定。

【讨论】:

  • 我更改了 GetCurrentClassLogger() 以使有问题的行不在末尾,并且仍然无法按预期工作。不过,看起来你是对的。你知道绕过它的方法吗?
  • 在方法中更改行顺序无济于事,因为整个框架 (GetCurrentClassLogger) 正在使用其父框架。我不明白你为什么要解决这个问题......要么禁用尾调用优化(~不要~),要么不使用依赖帧数的代码。如果您必须依赖堆栈,请让测试意识到这一点(当然,如果没有您的真实代码,很难准确)。
  • 我只是以这段代码为例来说明问题,无论如何我现在不得不删除它。据推测,除了 StackFrame 之外,优化后可能还有其他可能具有相同效果的东西?如果我能找到一种方法让 Visual Studio 和 dotCover 共享相同的构建设置,那就太好了,这样我就可以确保类似的代码在未来不会被忽视。感谢您的帮助
  • 我不关注。 dotCover 不会“构建”。它是一个 .net 分析器,可在运行时更改 JIT 编译器的行为。请准确解释您想要“绕过”的是什么 - 如果您编写的代码依赖于 .Net 优化,请不要对它在发布时中断感到惊讶,根据我的回答,不要对 dotCover 感到惊讶绕过优化...相应地编写您的测试(即您可以单独运行 dotCover)。
猜你喜欢
  • 2016-10-09
  • 1970-01-01
  • 1970-01-01
  • 2021-06-12
  • 2016-06-03
  • 1970-01-01
  • 2020-04-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多