Using .runsettings to exclude assemblies from code coverage

懵懂的女人 提交于 2019-11-28 08:19:29
Hullah

The issue is the period. For some reason the RegEx is choking on that. You can get around it by escaping the period as follows:

<ModulePaths>
    <Include>
        <ModulePath>.*MyCompany\.Namespace\.Project\.dll$</ModulePath>
    </Include>
    <Exclude>
        <ModulePath>.*ThirdParty\.Namespace\.Project\.dll$</ModulePath>
    </Exclude>
</ModulePaths>

Also, the empty includes are valid and imply that all Modules are included. The comments of the Microsoft provided sample state that:

<!--
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.
-->

On a related note, I ran into this post because I was bit thinking clearly about the regular expression nature of the include and exclude paths. For my WPF application, I wanted to exclude coverage analysis on Caliburn.Micro. So I had written

<ModulePath>Caliburn.Micro.dll</ModulePath>

Clearly, the period is messing me up. This question does not suffer from that problem, but I bet I’m not the only one to overlook this simple fact. For any other readers, please also take note that * is not a wildcard – it is the regular expression “any number of” operator. You do not want *.Caliburn, but rather .*Caliburn Thus this simple statement solved my problem:

<ModulePath>.*Caliburn.*</ModulePath>

Because it is looking for a path, not just a module name, you need the .* in front of the module to ignore it – that is, you want to ignore it at any given file path.

As I couldn't find this answer anywhere else, and this just took me a while to figure out, ModulePath is the full path, and you may be matching your pattern somewhere else in the path.

For example, if you have a project Foo and a project Foo.Tests, and they are built to their own directories, you will end up with Foo.Tests\bin\Release\Foo.dll and Foo.Tests\bin\Release\Foo.Tests.dll. This is the dll that the test assembly will reference, so this is the path that is used. Foo\bin\Release\Foo.dll is not directly referenced by the test assembly.

If you try to exclude .*tests.* it will match both paths and produce no coverage.

To only exclude assemblies with "test" in their file name, ignoring their path, I used

<Exclude>
  <ModulePath>.*\\[^\\]*test[^\\]*\.dll</ModulePath>
</Exclude>

Unfortunately I couldn't get the other answers working for me, but I got this working, as per https://msdn.microsoft.com/en-us/library/jj159530.aspx:

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

I had all sorts of issues getting <ModulePaths> to work reliably (using ASP.NET Core 2.1).

In the end I found that using the <Sources> was simple and more reliable and worked exactly as I needed. You still leverage the advice on the use of regex.

I include my solution path, and exclude my \tests subfolders where all my test projects live. Example for CodeCoverage element in RunSettings xml file:

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

See more at: Customising Code Coverage on MS Docs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!