Использование .runsettings для исключения сборок из покрытия кода

При запуске покрытия кода для моего решения, которое содержит несколько проектов, я заметил, что Code Coverage включает также мои тестовые сборки.

Я нашел статью, в которой предлагается следующий шаблон для .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>
 .*\\atlmfc\\.*
 .*\\vctools\\.*
 .*\\public\\sdk\\.*
 .*\\microsoft sdks\\.*
 .*\\vc\\include\\.*
 </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 -->

анализируется только одна сборка. Я хотел бы избежать добавления всех моих сборок в список Include, мне просто нужно исключить все тестовые сборки.

Почему настройки .runsettings обеспечивают покрытие кода, см. только одну из сборок в моем VS-решении?

3 ответа

Проблема - это период. По какой-то причине RegEx задыхается. Вы можете обойти это, ускорив период следующим образом:

<modulepaths>
 <include>
 <modulepath>.*MyCompany\.Namespace\.Project\.dll$</modulepath>
 </include>
 <exclude>
 <modulepath>.*ThirdParty\.Namespace\.Project\.dll$</modulepath>
 </exclude>
</modulepaths>

Кроме того, пустые включения действительны и подразумевают, что все модули включены. В комментариях Microsoft указано, что:


В соответствующей заметке я столкнулся с этим сообщением, потому что я немного думал о природе регулярного выражения путей include и exclude. Для моего приложения WPF я хотел исключить анализ покрытия на Caliburn.Micro. Поэтому я написал

<modulepath>Caliburn.Micro.dll</modulepath>

Понятно, что этот период меня перепутал. Этот вопрос не страдает от этой проблемы, но я уверен, что не единственный, кто упустил этот простой факт. Для любых других читателей, пожалуйста, также обратите внимание, что * не является подстановочным знаком - это регулярное выражение "любое число" оператора. Вы не хотите *.Caliburn, а скорее .*Caliburn. Таким образом, эта простая инструкция решила мою проблему:

<modulepath>.*Caliburn.*</modulepath>

Поскольку он ищет путь, а не только имя модуля, вам нужно. * перед модулем, чтобы его игнорировать, то есть вы хотите игнорировать его на любом заданном пути к файлу.


К сожалению, я не мог заставить другие ответы работать для меня, но я получил эту работу, согласно https://msdn.microsoft.com/en-us/library/jj159530.aspx:

<modulepath>.*\\MyProject\.Test\.dll$</modulepath>

licensed under cc by-sa 3.0 with attribution.