visual unit test studio missing coverage community code axocover analyze .net visual-studio unit-testing code-coverage vs-unit-testing-framework

.net - missing - unit test visual studio c#



Uso de.runsettings para excluir ensamblados de la cobertura del código (5)

Como no pude encontrar esta respuesta en ningún otro lugar, y esto me llevó un tiempo descifrarlo, ModulePath es la ruta completa, y es posible que coincida con su patrón en otra parte de la ruta.

Por ejemplo, si tiene un proyecto Foo y un proyecto Foo.Tests , y están integrados en sus propios directorios, terminará con Foo.Tests/bin/Release/Foo.dll y Foo.Tests/bin/Release/Foo.Tests.dll . Esta es la dll a la que hará referencia el ensamblaje de prueba, por lo que esta es la ruta que se utiliza. Foo/bin/Release/Foo.dll ensamblaje de prueba no hace referencia directa a Foo/bin/Release/Foo.dll .

Si intenta excluir .*tests.* Coincidirá con ambas rutas y no producirá cobertura.

Para excluir solo los ensamblajes con "prueba" en su nombre de archivo, ignorando su ruta, utilicé

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

Al ejecutar la cobertura de código para mi solución que contiene varios proyectos, noté que la cobertura de código también incluye mis ensamblajes de prueba.

Encontré un artículo que sugiere la siguiente plantilla para .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>

Ahora el problema es que tan pronto como reviso mi archivo .runsettings en el menú de configuración de PRUEBA / Prueba, veo que Cobertura de código analiza solo uno de los muchos ensamblajes en mi solución.

Incluso si elimino la línea

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

Sólo se analiza un conjunto. Me gustaría evitar agregar todos mis ensamblajes a la lista de Incluir, solo necesito excluir todos los ensamblajes de prueba.

¿Por qué .runsettings hace que la cobertura del código vea solo uno de los ensamblajes en mi solución VS?



En una nota relacionada, me encontré con esta publicación porque estaba pensando poco acerca de la naturaleza de la expresión regular de los caminos de inclusión y exclusión. Para mi aplicación WPF, quería excluir el análisis de cobertura en Caliburn.Micro. Asi que habia escrito

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

Claramente, el período me está arruinando. Esta pregunta no sufre ese problema, pero apuesto a que no soy la única que pasa por alto este simple hecho. Para cualquier otro lector, también tenga en cuenta que * no es un comodín, es la expresión regular "cualquier número de" operador. No desea *.Caliburn , sino más bien .*Caliburn De esta manera, esta simple afirmación resolvió mi problema:

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

Debido a que está buscando una ruta, no solo un nombre de módulo, necesita el. * Delante del módulo para ignorarlo, es decir, desea ignorarlo en cualquier ruta de archivo determinada.


Tuve todo tipo de problemas para que las <ModulePaths> funcionaran de manera confiable (usando ASP.NET Core 2.1).

Al final, descubrí que usar <Sources> era simple, más confiable y que funcionaba exactamente como lo necesitaba. Aún aprovechas los consejos sobre el uso de expresiones regulares.

Incluyo la ruta de mi solución y excluyo mis subcarpetas de prueba donde viven todos mis proyectos de prueba. Ejemplo para el elemento CodeCoverage en el archivo 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>

Ver más en: Personalizar la cobertura de código en MS Docs


El tema es el período . Por alguna razón el RegEx se está ahogando en eso. Puede evitarlo escapando el período de la siguiente manera:

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

Además, las inclusiones vacías son válidas e implican que todos los módulos están incluidos. Los comentarios de Microsoft proporcionaron un estado de muestra que:

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