【问题标题】:VS2010 Code Coverage Not AccurateVS2010 代码覆盖率不准确
【发布时间】:2012-04-26 13:58:18
【问题描述】:

我正在使用 Visual Studio 2010 Ultimate SP1。我的项目中有大约 225 个单元测试,它们都通过了。然而,其中一项测试报告其命中的方法的代码覆盖率为 0%。调试时,我可以单步执行并看到它触及了方法的每一行。然而在代码覆盖率报告中,它显示该方法根本没有被覆盖。所有其他测试和方法在代码覆盖率方面都可以正常工作。

我尝试了以下方法但没有成功:

  • 将正在测试的方法移到另一个类中。
  • 做的方法
  • 静态与非静态。
  • 将测试转移到另一个班级。
  • 删除了我所有的 .testsetting 文件并从头开始重新创建它们
  • 编写了不同的测试来使用相同的方法,结果相同
  • 重启VS
  • 重新启动

如果重要的话,该方法在 Global.asax 文件中。但是,我把它移到另一个班级,并没有什么不同。

有什么想法吗?

这是正在测试的方法。

 public void LogError(ILoggingService loggingService, IController controller)
    {
        if (loggingService == null)
            throw new ArgumentNullException("loggingService");

        if (controller == null)
            throw new ArgumentNullException("controller");

        Exception ex = Server.GetLastError();

        loggingService.LogException(ex.Message, ex.StackTrace, ApplicationName.VoucherLog, UserInfo.UserName);


        HttpException httpException = ex as HttpException;

        if (httpException == null)
        {
            var routeData = new RouteData();
            routeData.Values["controller"] = "Error";
            routeData.Values["action"] = "HttpError";

            Server.ClearError();

            var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
            controller.Execute(rc);
        }
    }

前 4 行,抛出异常的地方,被其他测试命中并显示在代码覆盖率统计中。该方法的其余部分受到以下测试的影响(通过调试验证并看到每一行实际上都已执行),但不会显示在代码覆盖率统计信息中。这是测试:

    [TestMethod]
    [HostType("Moles")]
    public void LogError()
    {
        DMVCommon.ApplicationName expectedApplication = DMVCommon.ApplicationName.VoucherLog;
        string expectedUser = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
        NotImplementedException expectedException = null;

        System.Web.Moles.MHttpServerUtility.AllInstances.GetLastError = (System.Web.HttpServerUtility server) =>
        {
            return expectedException;
        };

        System.Web.Moles.MHttpApplication.AllInstances.ContextGet = (System.Web.HttpApplication application) =>
        {
            return MvcMockHelpers.FakeHttpCurrentContext();
        };


        try
        {
            throw new NotImplementedException();
        }
        catch (NotImplementedException exc)
        {
            expectedException = exc;
            using (MvcApplication app = new MvcApplication())
            {
                bool called = false;

                Mock<ILoggingService> mockLoggingService = new Mock<ILoggingService>();
                mockLoggingService.Setup(a => a.LogException(expectedException.Message, expectedException.StackTrace, expectedApplication, expectedUser)).Callback(() => called = true);

                Mock<IController> mockController = new Mock<IController>();

                app.LogError(mockLoggingService.Object, mockController.Object);

                mockController.Verify(a => a.Execute(It.IsAny<System.Web.Routing.RequestContext>()), Times.Exactly(1));
                Assert.IsTrue(called);
            }
        }
    }

【问题讨论】:

  • 您是否在 RELEASE 中运行覆盖?你能告诉我们方法本身吗?
  • 我在调试中运行。但是,在您询问后,我在 RELEASE 中再次尝试,结果并没有什么不同。我用代码更新了问题,包括测试和正在测试的方法。顺便说一下,我们正在使用 Moq 和 Moles。

标签: visual-studio-2010 unit-testing mstest


【解决方案1】:

这可能是因为您使用了Moles - 当运行程序加载程序集时,Moles 接管并分析程序集而不是覆盖率分析器。

已经有 known integration issues 使用覆盖工具和 Moles - 为了让两个 .Net 分析器(Moles 和覆盖)协同工作,它们必须相互实现特定的支持。

尝试在没有 Moles 的情况下跑步,看看会发生什么......

另请参阅this 作为类似示例。

【讨论】:

  • 是的,就是这样!当我注释掉被痣和测试中的痣时,一切都按预期工作。所以我想我现在最好的做法是在方法中添加 [ExcludeFromCodeCoverage] 属性,以及解释它实际上被覆盖的注释,为什么?我唯一担心的是,未来可能会改变覆盖率的代码更改不一定会被注意到。
猜你喜欢
  • 2011-06-24
  • 1970-01-01
  • 2012-10-03
  • 2012-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多