尝试调试单元测试的 pdb 上的 UnauthorizedAccessException

UnauthorizedAccessException on pdb trying to debug a unit test

如果我在这个方法的最后一行放置一个断点,并在测试资源管理器中通过 "Debug selected tests" 进行调试,我会在测试程序集的 pdb 上得到一个 UnauthorizedAccessException 并且测试中止。

module Tests

open System
open Xunit

[<Fact>]
let fact () =
    let rng = Random ()
    let a = rng.Next() % 2 = 0
    let b = rng.Next() % 2 = 0
    a && b // <- breakpoint here

如果我在其他地方放置断点,我可以很好地调试。如果方法中的其他地方有断点,我可以在该行上放置一个断点并进行调试;最后一个断点只是显示为空(没有生成的代码匹配它)。请注意,最后一行的 && 似乎很重要,如果我删除它,问题就会消失。例如这个版本没有出现问题:

[<Fact>]
let fact () =
    let rng = Random ()
    let a = rng.Next() % 2 = 0
    let b = rng.Next() % 2 = 0
    let result = a && b
    result // can put a breakpoint anywhere and debug fine

我无法在包含我从事的许多其他项目的特定解决方案之外进行复制,即使使用所有完全相同的引用和 App.config。我已经花了相当多的时间试图确定这个问题,并且正在寻找此时的提示。反正他们在这里:

App.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="xunit.methodDisplay" value="method"/>
  </appSettings>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="xunit.core" publicKeyToken="8d05b1bb7a6fdb6c" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.1.0.3179" newVersion="2.1.0.3179" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.4.0.0" newVersion="4.4.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

packages.config:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="FSharp.Core" version="4.0.0.1" targetFramework="net46" />
  <package id="xunit" version="2.1.0" targetFramework="net46" />
  <package id="xunit.abstractions" version="2.0.0" targetFramework="net46" />
  <package id="xunit.assert" version="2.1.0" targetFramework="net46" />
  <package id="xunit.core" version="2.1.0" targetFramework="net46" />
  <package id="xunit.extensibility.core" version="2.1.0" targetFramework="net46" />
  <package id="xunit.extensibility.execution" version="2.1.0" targetFramework="net46" />
  <package id="xunit.runner.visualstudio" version="2.1.0" targetFramework="net46" />
</packages>

Visual Studio Enterprise 2015 更新 3(版本 14.0.25424.00)

假设您使用相同的位数(对 32 位项目使用 32 位 xunit 运行程序),我猜这是中断的原因是因为单元测试应该具有签名:unit -> unit 或 C# 术语void.

如果您将第一个示例更改为 return 单元,我可以毫无问题地调试 a && b。现在,为什么您的第二个示例即使具有相同的 return 类型也能正常工作,我不知道。也许这个错误与需要分配一个变量才能在 xunit 中使用它有关?

[<Fact>]
let fact () =
    let rng = Random ()
    let a = rng.Next() % 2 = 0
    let b = rng.Next() % 2 = 0
    a && b // <- breakpoint here works
    ()

有点猜测,但 a && b 是一个表达式而不是语句,因此不会命中断点。 如果测试运行器已经制作了程序集和 PDB 的卷影副本,那么它可能会在测试完成后尝试将其删除 - 但调试器仍在访问它,从而导致异常。