UnauthorizedAccessException на pdb при попытке отладки модульного теста

Если я добавлю одну точку останова для этого метода в последней строке и отладлю с помощью "Отладка выбранных тестов" в обозревателе тестов, я получу UnauthorizedAccessException на pdb тестовой сборки и теста прерывается.

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)

2 ответа

Решение

Это немного догадок, но a && b является выражением, а не утверждением, поэтому точка останова не получает удар. Если исполнитель теста сделал теневую копию вашей сборки и PDB, он может попытаться удалить ее после завершения теста - но отладчик все еще обращается к нему, что приводит к исключению.

Предполагая, что вы используете одну и ту же битность (используя 32-битный xunit runner для 32-битного проекта), я предполагаю, что причина этого заключается в том, что модульные тесты должны иметь сигнатуру: unit -> unit или в терминах C# void,

Если вы измените свой первый пример, чтобы вернуть модуль, я смог отладить a && b без проблем. Теперь о том, почему ваш второй пример работает, хотя он имеет тот же тип возврата, я понятия не имею. Может быть, ошибка связана с необходимостью назначить переменную, чтобы можно было что-то делать с ней в xunit?

[<Fact>]
let fact () =
    let rng = Random ()
    let a = rng.Next() % 2 = 0
    let b = rng.Next() % 2 = 0
    a && b // <- breakpoint here works
    ()
Другие вопросы по тегам