wake-up-neo.com

Verwenden von .runsettings, um Assemblys von der Codeabdeckung auszuschließen

Beim Ausführen von Code Coverage für meine Lösung, die mehrere Projekte enthält, habe ich festgestellt, dass Code Coverage auch meine Testassemblys enthält. 

Ich habe einen Artikel gefunden, der die folgende Vorlage für .runsettings vorschlägt:

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

Jetzt besteht das Problem darin, dass ich, wenn ich meine .runsettings-Datei im Einstellungsmenü TEST\Test überprüfe, Code Coverage-Analysen nur eine von vielen Assemblys in meiner Lösung durchführt. 

Auch wenn ich die Leitung entferne 

 <ModulePath>.*Tests\.dll$</ModulePath> <!-- I put it here -->

es wird nur eine Assembly analysiert. Ich möchte vermeiden, dass alle meine Assemblys der Include-Liste hinzugefügt werden. Ich muss lediglich alle Testassemblys ausschließen.

Warum werden in der .runsettings-Codeabdeckung nur eine der Assemblys in meiner VS-Lösung angezeigt?  

16
JustAMartin

Die Ausgabe ist die Periode . Aus irgendeinem Grund verschluckt der RegEx das. Sie können es umgehen, indem Sie den Zeitraum wie folgt umgehen:

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

Die leeren Includes sind ebenfalls gültig und implizieren, dass alle Module enthalten sind. In den Kommentaren des Microsoft-Beispiels heißt es:

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

In einem ähnlichen Zusammenhang bin ich auf diesen Beitrag gestoßen, weil ich ein bisschen über die regulären Ausdrücke der Include- und Exclude-Pfade nachgedacht habe. Für meine WPF-Anwendung wollte ich die Abdeckungsanalyse für Caliburn.Micro ausschließen. Also hatte ich geschrieben

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

Klar, die Zeit bringt mich durcheinander. Diese Frage leidet nicht unter diesem Problem, aber ich wette, ich bin nicht der einzige, der diese einfache Tatsache übersieht. Beachten Sie bei allen anderen Lesern auch, dass * kein Platzhalter ist - es ist der reguläre Ausdruck "Beliebig viele". Sie wollen nicht *.Caliburn, sondern .*Caliburn. Daher löste diese einfache Anweisung mein Problem:

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

Da nach einem Pfad und nicht nur nach einem Modulnamen gesucht wird, benötigen Sie das. * Vor dem Modul, um ihn zu ignorieren. Das heißt, Sie möchten ihn an einem beliebigen Dateipfad ignorieren.

13
sfuqua

Da ich diese Antwort nirgendwo anders finden konnte, brauchte ich nur eine Weile, um herauszufinden, dass ModulePath der vollständige Pfad ist, und Sie passen möglicherweise zu Ihrem Muster an anderer Stelle im Pfad.

Wenn Sie beispielsweise über ein Projekt Foo und ein Projekt Foo.Tests verfügen und diese in ihre eigenen Verzeichnisse erstellt werden, erhalten Sie Foo.Tests\bin\Release\Foo.dll und Foo.Tests\bin\Release\Foo.Tests.dll. Dies ist die DLL, auf die die Testassembly verweist. Dies ist der Pfad, der verwendet wird. Foo\bin\Release\Foo.dll wird von der Testassembly nicht direkt referenziert.

Wenn Sie versuchen, .*tests.* auszuschließen, stimmen beide Pfade überein und erzeugen keine Abdeckung.

Um nur Assemblys mit "test" im Dateinamen auszuschließen und ihren Pfad zu ignorieren, habe ich verwendet

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

Ich hatte alle möglichen Probleme damit, <ModulePaths> zuverlässig zu arbeiten (mit ASP.NET Core 2.1). 

Am Ende fand ich heraus, dass die Verwendung des <Sources> einfach und zuverlässiger war und genau so funktionierte, wie ich es brauchte. Sie nutzen immer noch die Ratschläge zur Verwendung von Regex.

Ich gebe meinen Lösungspfad ein und schließe meine\tests-Unterordner aus, in denen alle meine Testprojekte leben. Beispiel für das CodeCoverage-Element in der RunSettings-XML-Datei:

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

Weitere Informationen finden Sie unter: Anpassen der Codeabdeckung in MS Docs

0
Peter

Leider konnte ich die anderen Antworten nicht für mich arbeiten lassen, aber ich bekam diese Funktion gemäß https://msdn.Microsoft.com/en-us/library/jj159530.aspx :

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