Подтвердить что ты не робот

Получение PartCover для работы

Я хочу попробовать PartCover для покрытия кода. Я запускаю Visual Studio 2008 Professional с MSTest. Professional Edition не включает инструменты Team Testing, такие как Code Coverage.

Итак, я пытаюсь использовать PartCover, но я не могу заставить его работать. В PartCover.Browser я выбрал исполняемый файл MSTest, я указал рабочие аргументы на мои test.dll, и я попытался указать свой рабочий каталог в папку TestResults, но я получаю сообщение об ошибке:

"Отчет пуст. Проверьте настройки и снова запустите цель."

Я не знаю, что делать дальше.

Edit

Оказывается, у меня было две проблемы. Во-первых, я не ставил свои правила правильно. Во-вторых, у меня были пробелы в моих рабочих аргументах. Пробелы выдавали ошибку, но нигде не отображались.

4b9b3361

Ответ 1

Да, у меня тоже была эта проблема. Ознакомьтесь с форматом поля "Правила".

В браузере добавьте что-то вроде:

+[MyNamespace.MyAssemblyName]*

Если указанное имя сборки является именем сборки, содержащей типы, для которых вы хотите охватить. Начните с:

+[*]*

и partcover с радостью предоставят вам показатели охвата для проекта unit test, любых библиотек, на которые вы ссылаетесь, и вкл. и далее.

Из командной строки вы указываете один и тот же шаблон в аргументе -include:  --include=[MyNamespace.MyAssembly]*

Вы также можете исключить содержащиеся пространства имен или типы или ограничить типы из пространства имен, в которые вы получаете данные о охвате, в отчете. Формат правил представляет собой подмножество синтаксиса регулярных выражений в соответствии с руководством (состоящим из asterix в качестве подстановочного знака и символов, которые составляют имена сборки и класса, поэтому довольно ограничены, но достаточно, чтобы получить нужные вам данные). Ознакомьтесь с разделом правил в руководстве. Если у вас нет руководства, загрузите его из sourceforge.

Ответ 2

Мне пришлось пройти несколько шагов, чтобы, наконец, заставить PartCover работать при вызове из NAnt script. Я собрал все, что мне нужно было сделать для удобства других; обратите внимание, что на некоторые из них уже были ответы другие, но я потратил много времени на то, чтобы собрать все это вместе.

Во-первых, как будет сказано в другом месте здесь, если ваша ОС 64-разрядная, вам нужно запустить [последний Windows SDK]\bin\CorFlags.exe [PartCover install dir]\PartCover.exe/32BIT +/Force

Это одноразовый шаг после установки PartCover. Он изменит исполняемый файл и предупредит вас о необходимости повторной подписки на сборку, но я этого не сделал, и он (в конце концов) работал нормально. Обратите внимание, что, хотя похоже, что CorFlags не выполнил то, что вы просили, и предупредил вас о подписании, он изменил файл .exe, он просто не указывает на это явно.

Далее, если ваша ОС 64-разрядная, и вы используете NUnit (или другое тестовое exe) с PartCover, вам нужно будет вызвать версию, явно скомпилированную для x86. В случае NUnit это будет nunit-console-x86.exe. Вызов nunit-console.exe будет просто вешать бесконечно для меня после выполнения работы и не возвращаться к приглашению.

Далее, как и в другом месте, PartCover 2.3, dev build, терпел неудачу даже после запуска CorFlags. Тем не менее, 2.2 работал.

Затем, когда вызывается PartCover.exe, синтаксис аргументов - arg-name... и NOT - = arg-name (т.е. имя аргумента пробела в тире, а не тире dash равно имя arg); документы PartCover, похоже, идут в обоих направлениях, но знак равенства просто не работает для меня.

После вышесказанного, PartCover, наконец, работал из командной строки. Я использовал файл настроек (вы можете использовать приложение интерфейса браузера PartCover для сохранения файла настроек, который затем можно использовать из командной строки), так что только указанные мной аргументы были полным файлом файла настроек, а файл выходного отчета name полный путь.

Это все еще не срабатывало при вызове из NAnt script, поэтому я, наконец, понял, что значения arg должны быть указаны... и использовать теги, закодированные в HTML, для кавычек. Таким образом,...

Отрывок NAnt:

<property name="PartCoverExePath" value="c:\Program Files (x86)\PartCover .NET 2\PartCover.exe" />
<property name="PartCoverWorkPath" value="c:\Projects\MyProject\trunk\CI\" />
<property name="PartCoverSettingsFileName" value="PartCover.Settings.xml" />
<property name="PartCoverReportFileName" value="PartCover.Report.xml" />

<target name="MyTarget">
<exec program="${PartCoverExePath}">
<arg value="--settings &quot;${PartCoverWorkPath}${PartCoverSettingsFileName}&quot;" />
<arg value="--output &quot;${PartCoverWorkPath}${PartCoverReportFileName}&quot;" />
</exec>
</target>

И файл настроек PartCover:

<PartCoverSettings>
<Target>C:\CI\Binaries\NUnit2.5.2\bin\net-2.0\nunit-console-x86.exe</Target>
<TargetWorkDir>c:\Projects\MyProject\trunk\MyProject.Test\bin\Debug</TargetWorkDir>
<TargetArgs>MyProject.Test.dll</TargetArgs>
<Rule>+[*]*</Rule>
<Rule>-[log4net*]*</Rule>
<Rule>-[nunit*]*</Rule>
<Rule>-[MyProject.Test*]*</Rule>
</PartCoverSettings>

Уф! Надеюсь, это спасет кого-то еще головные боли, которые у меня были.

Ответ 3

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

Я исправил эти файлы, и теперь все работает отлично для меня:

отчет по сборке

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxml="urn:schemas-microsoft-com:xslt">
  <xsl:output method="html" indent="yes"/>
    <xsl:template match="/">

    <xsl:variable name="cov0style" select="'background:#E79090;text-align:right;'"/>
    <xsl:variable name="cov20style" select="'background:#D79797;text-align:right;'"/>
    <xsl:variable name="cov40style" select="'background:#D7A0A0;text-align:right;'"/>
    <xsl:variable name="cov60style" select="'background:#C7A7A7;text-align:right;'"/>
    <xsl:variable name="cov80style" select="'background:#C0B0B0;text-align:right;'"/>
    <xsl:variable name="cov100style" select="'background:#D7D7D7;text-align:right;'"/>

<table style="border-collapse: collapse;">
  <tr style="font-weight:bold; background:whitesmoke;">
    <td colspan="2">Coverage by assembly</td>
  </tr>

  <xsl:variable name="asms" select="/PartCoverReport/Assembly"/>
  <xsl:for-each select="$asms">
    <xsl:variable name="current-asm-node" select="."/>
    <tr>

      <xsl:element name="td">
        <xsl:attribute name="style">background:ghostwhite; padding: 5px  30px 5px  5px;</xsl:attribute>
        <xsl:value-of select="$current-asm-node/@name"/>
      </xsl:element>

      <xsl:variable name="codeSize" select="sum(/PartCoverReport/Type[@asmref=$current-asm-node/@id]/Method/pt/@len)+0"/>
      <xsl:variable name="coveredCodeSize" select="sum(/PartCoverReport/Type[@asmref=$current-asm-node/@id]/Method/pt[@visit>0]/@len)+0"/>

      <xsl:element name="td">
        <xsl:if test="$codeSize=0">
          <xsl:attribute name="style">
            <xsl:value-of select="$cov0style"/>
          </xsl:attribute>
          0%
        </xsl:if>
        <xsl:if test="$codeSize &gt; 0">
          <xsl:variable name="coverage" select="ceiling(100 * $coveredCodeSize div $codeSize)"/>
          <xsl:if test="$coverage &gt;=  0 and $coverage &lt; 20">
            <xsl:attribute name="style">
              <xsl:value-of select="$cov20style"/>
            </xsl:attribute>
          </xsl:if>
          <xsl:if test="$coverage &gt;= 20 and $coverage &lt; 40">
            <xsl:attribute name="style">
              <xsl:value-of select="$cov40style"/>
            </xsl:attribute>
          </xsl:if>
          <xsl:if test="$coverage &gt;= 40 and $coverage &lt; 60">
            <xsl:attribute name="style">
              <xsl:value-of select="$cov60style"/>
            </xsl:attribute>
          </xsl:if>
          <xsl:if test="$coverage &gt;= 60 and $coverage &lt; 80">
            <xsl:attribute name="style">
              <xsl:value-of select="$cov80style"/>
            </xsl:attribute>
          </xsl:if>
          <xsl:if test="$coverage &gt;= 80">
            <xsl:attribute name="style">
              <xsl:value-of select="$cov100style"/>
            </xsl:attribute>
          </xsl:if>
          <xsl:value-of select="$coverage"/>%
        </xsl:if>
      </xsl:element>
    </tr>
  </xsl:for-each>
</table>

  

отчет по классу

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxml="urn:schemas-microsoft-com:xslt">
<xsl:output method="html" indent="no"/>

<xsl:template match="/">

<xsl:variable name="cov0style" select="'background:#FF4040;text-align:right;'"/>
<xsl:variable name="cov20style" select="'background:#F06060;text-align:right;'"/>
<xsl:variable name="cov40style" select="'background:#E78080;text-align:right;'"/>
<xsl:variable name="cov60style" select="'background:#E0A0A0;text-align:right;'"/>
<xsl:variable name="cov80style" select="'background:#D7B0B0;text-align:right;'"/>
<xsl:variable name="cov100style" select="'background:#E0E0E0;text-align:right;'"/>

<table style="border-collapse: collapse;">
    <tr style="font-weight:bold; background:whitesmoke;"><td colspan="2">Coverage by class</td></tr>

    <xsl:for-each select="/PartCoverReport/Type">
        <tr>

            <xsl:element name="td">
                <xsl:attribute name="style">background:ghostwhite; padding: 5px  30px 5px  5px;</xsl:attribute>
                <xsl:value-of select="@name"/>
            </xsl:element>

            <xsl:variable name="codeSize" select="sum(./Method/pt/@len)+0"/>
            <xsl:variable name="coveredCodeSize" select="sum(./Method/pt[@visit>0]/@len)+0"/>

            <xsl:element name="td">
                <xsl:if test="$codeSize=0">
                    <xsl:attribute name="style"><xsl:value-of select="$cov0style"/></xsl:attribute>
                    0%
                </xsl:if>

                <xsl:if test="$codeSize &gt; 0">
                    <xsl:variable name="coverage" select="ceiling(100 * $coveredCodeSize div $codeSize)"/>

                    <xsl:if test="$coverage &gt;=  0 and $coverage &lt; 20"><xsl:attribute name="style"><xsl:value-of select="$cov20style"/></xsl:attribute></xsl:if>
                    <xsl:if test="$coverage &gt;= 20 and $coverage &lt; 40"><xsl:attribute name="style"><xsl:value-of select="$cov40style"/></xsl:attribute></xsl:if>
                    <xsl:if test="$coverage &gt;= 40 and $coverage &lt; 60"><xsl:attribute name="style"><xsl:value-of select="$cov60style"/></xsl:attribute></xsl:if>
                    <xsl:if test="$coverage &gt;= 60 and $coverage &lt; 80"><xsl:attribute name="style"><xsl:value-of select="$cov80style"/></xsl:attribute></xsl:if>
                    <xsl:if test="$coverage &gt;= 80"><xsl:attribute name="style"><xsl:value-of select="$cov100style"/></xsl:attribute></xsl:if>
                    <xsl:value-of select="$coverage"/>%
                </xsl:if>

            </xsl:element>
        </tr>
    </xsl:for-each>
</table>    
</xsl:template>
</xsl:stylesheet>

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

Ответ 4

@pelazm - Спасибо за отличное руководство.

Две дополнительные вещи, которые можно добавить к вашему решению:

(a) Если вы не хотите использовать внешний PartCover.settings.xml

<!-- Runs unit tests through PartCover to calculate unit test covereage-->
<!-- Use %2a instead of * and %3f instead of ? to prevent expansion -->
<!-- %40 = @  %25 = % %24 = $ -->
<Target Name="RunTests">
  <ItemGroup>
     <pc4_settings Include="--target &quot;$(NUnitEXE)&quot;"/>
     <pc4_settings Include="--target-work-dir &quot;$(RootDirectory)\src&quot;"/>
     <pc4_settings Include="--include [%2a]%2a"/>
     <pc4_settings Include="--exclude [nunit%2a]%2a"/>
     <pc4_settings Include="--exclude [log4net%2a]%2a"/>
     <pc4_settings Include="--exclude [MetadataProcessor.Tests%2a]%2a"/>
   </ItemGroup>

   <CreateItem Include="$(RootDirectory)\src\**\bin\$(Configuration)\*.Tests.dll">
     <Output TaskParameter="Include" ItemName="TestAssemblies" />
   </CreateItem>

   <Exec Command="&quot;$(PartCover4Directory)\PartCover.exe&quot; --register    @(pc4_settings,' ') --target-args &quot;%(TestAssemblies.Identity) $(NUnitArgs) /xml:%(TestAssemblies.Identity).NUnitResults.xml&quot; --output $(BuildDirectory)\PartCover-results.xml"
  ContinueOnError="true"
  WorkingDirectory="$(BuildDirectory)">
     <Output TaskParameter="ExitCode" ItemName="ExitCodes"/>
   </Exec>

   <XslTransformation XslInputPath="$(RootDirectory)\tools\partcover4\xslt\PartCoverFullReport.xslt"
                  XmlInputPaths="$(BuildDirectory)\PartCover-results.xml"
                  OutputPaths="$(BuildDirectory)\PartCover-results-PartCoverFullReport.html" />

   <Error Text="Test error occurred" Condition="'%(ExitCodes.Identity)'>0"/>
 </Target>

(b) HTML-отчет Gáspár Nagy довольно хорош - http://gasparnagy.blogspot.com/2010/09/detailed-report-for-partcover-in.html

Ответ 5

У меня были аналогичные проблемы с тем, что мой код не отображался в отчете при использовании PartCover версии 2.3.0.18745. Использование версии 2.2.0.34631 решило проблему.