VS2012断点无法命中

40

我有一个类,看起来像这样:

public class MyService
{
    private MyService(){}
    public static string GetStuff()
    {
        var stuffDid = new MyService();
        return stuffDid.DoStuff();
    }
    private string DoStuff()
    {
        //do stuff
    }
    //other private helpers

}

显然,我省略了很多内容,但那是基本框架。

现在,我有一个单元测试:

[Test]
public void MyTest()
{

    var results = MyService.GetStuff();
}

我在单元测试中设置了断点,可以看到results有数据。但是,即使我在MyService的各个地方设置断点,除非我把它们放在大括号上,否则什么也不会触发。因为results有数据,所以我在MyService中的return语句应该会被触发,对吗?

我有遗漏什么吗?我完全忘记了某些最基本的规则吗?为什么MyService中的任何内容都不会被触发?如果我手动用F11进入它,它只会跳来跳去,并且甚至不会像我预期的那样逐行执行。当我手动步进时,我倾向于在本应首先命中它的某些代码之后才能命中它。而且,任何switch语句似乎都默认为第一个选项,尽管被切换的值显然应该进入不同的case

我甚至尝试将MyService构造函数设置为public并删除所有static方法,但仍然没有作用。

我的测试和“Core”代码在同一个解决方案中,但位于不同的项目中(分别为TestCore)。其他测试没有问题地击中了Core中的断点,只有这个特定测试(唯一测试MyService的测试)存在问题。

我已经删除了PDB文件并清除了解决方案。仍然没有作用。


你的测试中有一个圆形的东西(不确定它是否只适用于NUnit)吗?如果有,点击它,然后点击调试...然后应该就可以了。 - Lews Therin
代码是否在同一解决方案中?Visual Studio的调试器有一个“仅限我的代码”选项。不确定它是如何工作的具体细节。 - ta.speot.is
导入是否正确?你的单元测试能否看到项目代码,还是只能看到编译后的dll文件? - user1877337
是的,所有代码都在同一个解决方案中。我的测试位于单独的项目中(称为“Tests”),但其他测试似乎没有问题,可以在核心(其中不会被命中的代码)中触发断点。 - RJP
你应该检查测试运行器运行的代码是否是最新版本的代码。尝试从“普通”的exe文件中调用测试,看看是否有任何差异。 - Hylaean
显示剩余3条评论
24个回答

62

一些想法。

  1. 确保它是调试版本而不是发布版本
  2. 如果已经打开优化,可以在项目属性中关闭
  3. 尝试在代码中插入 Debugger.Break() ,而不是在VS中使用断点
  4. 确保启用了断点(调试->窗口->断点工具栏),并且断点符号应该是实心的
  5. 执行您的应用程序。加载调试->窗口->模块窗口。检查您的程序集是否已加载符号。如果没有,它可能会显示相关的状态消息。

你最近有调整计算机上的日期吗?这可能会导致构建过程出现问题。如果是这样,请手动删除所有 obj/bin 文件夹并重新编译。


我刚遇到另一个问题:解决方案中的程序集之间存在.NET Framework版本不匹配。测试程序集是.NET 4.5,被测试程序集是.NET 3.5,无法在任何一个程序集中设置断点。通过将测试程序集转换回3.5来解决该问题。 - yoyo
我不理解第五步。我可以打开Debug > Window > Modules,但是从那里我该怎么做呢?我如何检查我的程序集以查看是否已加载符号? - levininja
2
删除 /obj 对我有用,之前我把系统日期搞乱了 - 谢谢! - Danny Beckett
1
我遇到了相反的问题,我的断点只在实际代码上命中,而不是在方法体的开放或关闭花括号上。在项目属性>构建>常规下删除“优化代码”中的“勾选”,这就是解决问题的方法。谢谢@Alan。 - N Katz

11

可能是因为您只调试了一个项目,而不是同时调试TestCore两个项目。

您可以将VS设置为同时调试多个项目,方法是右键单击解决方案 > 属性 > 公共属性 > 启动项目

在这里,您可以设置“多个启动项目”enter image description here

只需设置CoreTest两个项目即可启动。这可能会解决您的问题。


9

原来这与代码覆盖率有关。

关闭它可以解决这个问题。

你可以通过以下链接找到如何禁用代码覆盖率。

禁用代码覆盖率


28
这实际上不是一个答案。您应该描述如何关闭代码覆盖率。 - jamesrom

5

我有一个非常具体的场景,导致了“断点未被命中”的问题。

由于其他答案都没有提到这一点,所以我想加入我的答案,希望能帮助到遇到同样问题的人。

在我的情况下,解决方案很傻,因为我使用了很多LINQ,所以我应该早点发现。当运行一个返回IEnumerable的方法时,其中包含的返回语句实际上是yield return语句,那么当您调用它时,该方法将不会被执行。

只有当您从该IEnumerable对象调用另一个方法,例如ToList()或Count()时,该方法才会被执行并达到断点。


我总是忘记这个,然后去谷歌搜索,找到像这样的答案,然后提醒自己不要再忘记了... - cschooley

3

请确保使用调试符号编译您的程序集。

此选项必须填写为“full”:

右键单击包含未被命中断点的代码文件的项目。选择“属性”。

打开项目属性后,选择“生成”选项卡。注意选项卡底部“高级...”按钮。(在"输出"组中)

单击此按钮,并将“调试信息”属性设置为“full”。这可能是断点未被命中的原因。Visual Studio使用保存在pdb文件中的符号来找到断点的确切位置。如果这些文件没有创建,则不会命中任何断点。也许您禁用了这些文件的创建,以整理项目文件结构。这是我发现需要这些文件的情况。


1
你是否正在使用出现在Windows服务列表中的服务?如果是,那么你可能需要通过点击“调试”->“附加到进程”来进行调试,而不是简单地进行调试。 - Marco Klein
1
这是我的问题。谢谢! - Chris - Haddox Technologies

3
我最近也遇到了同样的问题,一直在苦思冥想。
答案其实很简单:我的测试项目和主库项目似乎出现了不同步的情况。我构建的是测试版本和库文件的debug版,但是测试项目从bin/Release文件夹中复制了库文件。我只需要重新创建项目引用,一切问题都得到了解决。
顺带一提,更奇怪的是:调试器进入了库函数,但却在其中一个中间行跳过了一行代码。

1

你需要将DoStuff方法改为静态的。

private static string DoStuff()
{
    //do stuff
}

抱歉,我对代码进行了修改,所以我不确定将DoStuff设置为静态是否必要。 - RJP
现在你已经更新了代码以实例化一个类变量来调用方法,所以不会出现这种情况。另外请注意,你的构造函数是私有的,除非你只计划从静态方法中调用它,否则应该将其设置为公共的。 - Sorceri
构造函数是私有的,所以访问该类的唯一方式是通过静态公共方法(不幸的是,我需要遵循这种模式)。 - RJP

1

你的代码指示了一个“服务”,它可能作为一个独立的进程运行。如果是这种情况,你可以加载你的程序集,断点会显示为实心红圆圈,但是另一个运行在独立进程中的程序集实际上正在处理请求。

  • 检查任务管理器,寻找可能托管你的服务的进程。在调试时将它们杀死以确认调用失败。
  • 尝试使用Debugger.Break();
  • 创建一个调试日志文件,在加载时输出进程和程序集名称的条目。确保你的日志每次都是不同的文件,以避免异步访问问题。

1
我曾经在25个项目的同一个解决方案中遇到过这种情况。其他项目都能识别断点,但是其中一个不行。我将该项目从解决方案中删除(删除而不是卸载),这导致所有对它的引用都失效,然后重新将其添加到解决方案中,这样就可以了!
如果这样还不行,你可能需要从头开始重新创建问题项目,并将新项目添加到解决方案中。
除了纯粹的运气之外,我认为这样做的最好解释是,多年来我们将项目从一个版本的VS迁移到另一个版本,可能其中一个迁移导致了这个问题。

1
  1. 清理解决方案并重新构建,同时启动项目。

  2. 您可以快速查看BUILD > Configuration Manager,以确保配置属性已设置。如果是开发模式,则可能需要调整项目属性 -> 点击高级设置 -> 在[输出选项卡]中将调试信息更改为“完整”。

  3. 即使不是开发模式,您也可以按照第二步操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接