Использование.runsettings для исключения сборок из покрытия кода
При выполнении покрытия кода для моего решения, содержащего несколько проектов, я заметил, что покрытие кода также включает в себя мои тестовые сборки.
Я нашел статью, которая предлагает следующий шаблон для.runsettings:
<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
<DataCollectionRunSettings>
<DataCollectors>
<DataCollector friendlyName="Code Coverage" uri="datacollector://Microsoft/CodeCoverage/2.0" assemblyQualifiedName="Microsoft.VisualStudio.Coverage.DynamicCoverageDataCollector, Microsoft.VisualStudio.TraceCollector, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Configuration>
<CodeCoverage>
<ModulePaths>
<Include>
<!-- Do not specify any includes. This will attempt to include all binaries -->
</Include>
<Exclude>
<!-- Exclude modules that aren't to be processed, by their name / path -->
<ModulePath>.*Tests\.dll$</ModulePath> <!-- I put it here -->
</Exclude>
</ModulePaths>
<UseVerifiableInstrumentation>True</UseVerifiableInstrumentation>
<AllowLowIntegrityProcesses>True</AllowLowIntegrityProcesses>
<CollectFromChildProcesses>True</CollectFromChildProcesses>
<CollectAspDotNet>False</CollectAspDotNet>
<!--
Additional paths to search for symbol files. Symbols must be found for modules to be instrumented.
If symbols are alongside the binaries, they are automatically picked up. Otherwise specify the here.
Note that searching for symbols increases code coverage runtime. So keep this small and local.
<SymbolSearchPaths>
<Path>C:\Users\User\Documents\Visual Studio 11\Projects\ProjectX\bin\Debug</Path>
<Path>\\mybuildshare\builds\ProjectX</Path>
</SymbolSearchPaths>
-->
<Functions>
<Exclude>
<Function>^std::.*</Function>
<Function>^ATL::.*</Function>
<Function>.*::__GetTestMethodInfo.*</Function>
<Function>^Microsoft::VisualStudio::CppCodeCoverageFramework::.*</Function>
<Function>^Microsoft::VisualStudio::CppUnitTestFramework::.*</Function>
<Function>.*::YOU_CAN_ONLY_DESIGNATE_ONE_.*</Function>
</Exclude>
</Functions>
<Attributes>
<Exclude>
<Attribute>^System.Diagnostics.DebuggerHiddenAttribute$</Attribute>
<Attribute>^System.Diagnostics.DebuggerNonUserCodeAttribute$</Attribute>
<Attribute>^System.Runtime.CompilerServices.CompilerGeneratedAttribute$</Attribute>
<Attribute>^System.CodeDom.Compiler.GeneratedCodeAttribute$</Attribute>
<Attribute>^System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute$</Attribute>
</Exclude>
</Attributes>
<Sources>
<Exclude>
<Source>.*\\atlmfc\\.*</Source>
<Source>.*\\vctools\\.*</Source>
<Source>.*\\public\\sdk\\.*</Source>
<Source>.*\\microsoft sdks\\.*</Source>
<Source>.*\\vc\\include\\.*</Source>
</Exclude>
</Sources>
<CompanyNames>
<Exclude>
<CompanyName>.*microsoft.*</CompanyName>
</Exclude>
</CompanyNames>
<PublicKeyTokens>
<Exclude>
<PublicKeyToken>^B77A5C561934E089$</PublicKeyToken>
<PublicKeyToken>^B03F5F7F11D50A3A$</PublicKeyToken>
<PublicKeyToken>^31BF3856AD364E35$</PublicKeyToken>
<PublicKeyToken>^89845DCD8080CC91$</PublicKeyToken>
<PublicKeyToken>^71E9BCE111E9429C$</PublicKeyToken>
<PublicKeyToken>^8F50407C4E9E73B6$</PublicKeyToken>
<PublicKeyToken>^E361AF139669C375$</PublicKeyToken>
</Exclude>
</PublicKeyTokens>
</CodeCoverage>
</Configuration>
</DataCollector>
</DataCollectors>
</DataCollectionRunSettings>
</RunSettings>
Теперь проблема в том, что как только я проверяю свой файл.runsettings в меню настроек TEST\Test, я вижу, что Code Coverage анализирует только одну из многих сборок в моем решении.
Даже если я уберу строку
<ModulePath>.*Tests\.dll$</ModulePath> <!-- I put it here -->
анализируется только одна сборка. Я хотел бы избежать добавления всех моих сборок в список "Включить", мне просто нужно исключить все тестовые сборки.
Почему.runsettings заставляет покрытие кода видеть только одну из сборок в моем решении VS?
5 ответов
Вопрос заключается в периоде. По какой-то причине RegEx задыхается от этого. Вы можете обойти это, избегая периода следующим образом:
<ModulePaths>
<Include>
<ModulePath>.*MyCompany\.Namespace\.Project\.dll$</ModulePath>
</Include>
<Exclude>
<ModulePath>.*ThirdParty\.Namespace\.Project\.dll$</ModulePath>
</Exclude>
</ModulePaths>
Кроме того, пустые включения действительны и подразумевают, что все модули включены. В комментариях Microsoft приведен пример состояния, в котором:
<!--
About include/exclude lists:
Empty "Include" clauses imply all; empty "Exclude" clauses imply none.
Each element in the list is a regular expression (ECMAScript syntax).
See http://msdn.microsoft.com/library/2k3te2cs.aspx.
An item must first match at least one entry in the include list to be included.
Included items must then not match any entries in the exclude list to remain included.
-->
В связи с этим я столкнулся с этим постом, потому что немного размышлял о природе регулярных выражений путей включения и исключения. Для моего приложения WPF я хотел исключить анализ покрытия в Caliburn.Micro. Итак, я написал
<ModulePath>Caliburn.Micro.dll</ModulePath>
Ясно, что этот период меня портит. Этот вопрос не страдает от этой проблемы, но держу пари, я не единственный, кто упускает из виду этот простой факт. Для любых других читателей, пожалуйста, обратите внимание, что * не является подстановочным знаком - это оператор регулярного выражения "любое число". Ты не хочешь *.Caliburn
, скорее .*Caliburn
Таким образом, это простое утверждение решило мою проблему:
<ModulePath>.*Caliburn.*</ModulePath>
Поскольку он ищет путь, а не просто имя модуля, вам нужно.* Перед модулем, чтобы игнорировать его, то есть вы хотите игнорировать его при любом заданном пути к файлу.
Поскольку я не мог найти этот ответ где-либо еще, и мне потребовалось некоторое время, чтобы понять, ModulePath
это полный путь, и вы можете сопоставить свой шаблон где-то еще в пути.
Например, если у вас есть проект Foo
и проект Foo.Tests
и они построены в свои собственные каталоги, вы в конечном итоге Foo.Tests\bin\Release\Foo.dll
а также Foo.Tests\bin\Release\Foo.Tests.dll
, Это dll, на который будет ссылаться тестовая сборка, так что это путь, который используется. Foo\bin\Release\Foo.dll
не имеет прямой ссылки на тестовую сборку.
Если вы попытаетесь исключить .*tests.*
это будет соответствовать обоим путям и не будет давать покрытия.
Чтобы исключить только сборки с "test" в имени файла, игнорируя их путь, я использовал
<Exclude>
<ModulePath>.*\\[^\\]*test[^\\]*\.dll</ModulePath>
</Exclude>
У меня были всевозможные проблемы с получением <ModulePaths>
работать надежно (используя ASP.NET Core 2.1).
В конце концов я обнаружил, что с помощью <Sources>
был простой и надежный и работал именно так, как мне нужно. Вы по-прежнему используете советы по использованию регулярных выражений.
Я включаю свой путь решения и исключаю подпапки \tests, в которых находятся все мои тестовые проекты. Пример для элемента CodeCoverage в xml-файле RunSettings:
<CodeCoverage>
<Sources>
<Include>
<Source>.*\\My\.Solution\.Name\.Space\\.*</Source> <!-- ie: include *\My.Solution.Name.Space\* -->
</Include>
<Exclude>
<Source>.*\\My\.Solution\.Name\.Space\\Tests\\.*</Source> <!-- ie: exclude *\My.Solution.Name.Space\Tests\* -->
</Exclude>
</Sources>
<!-- removed for brevity -->
<CodeCoverage>
Смотрите больше на: Настройка покрытия кода в MS Docs
К сожалению, я не мог получить другие ответы, работающие на меня, но я получил это работает, согласно https://msdn.microsoft.com/en-us/library/jj159530.aspx:
<ModulePath>.*\\MyProject\.Test\.dll$</ModulePath>