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
()