代码之家  ›  专栏  ›  技术社区  ›  finnw

让PartCover工作

  •  23
  • finnw  · 技术社区  · 16 年前

    我想尝试使用PartCover进行代码覆盖。我正在用MSTest运行Visual Studio 2008 Professional。专业版不包括团队测试工具,如代码覆盖率。

    所以,我正在尝试PartCover,但我无法让它工作。在PartCover中。浏览器我选择了MSTest可执行文件,我将工作参数指向了tests.dll,并尝试将工作目录指向TestResults文件夹,但我收到了一个错误:

    “报告为空。请检查设置,然后再次运行目标。”

    我不知道下一步该尝试什么。

    编辑

    原来我有两个问题。首先,我没有把我的规则放对。其次,我的工作论点中有空格。空格出现了错误,但没有出现在任何地方。

    5 回复  |  直到 16 年前
        1
  •  21
  •   Hamish Smith    16 年前

    是的,我也有这个问题。 查看“规则”字段的格式。

    在浏览器中添加以下内容:

    +[MyNamespace.MyAssemblyName]*

    其中,您指定的程序集名称是包含您想要覆盖的类型的程序集的名称。从以下内容开始:

    +[*]*

    partcover将很乐意为您提供单元测试项目、您参考的任何库等的覆盖率指标。

    在命令行中,您可以在--include参数中指定相同的模式: --include=[MyNamespace.MyAssembly]*

    您还可以排除包含的命名空间或类型,或限制在报告中获取覆盖率数据的命名空间中的类型。根据手册,规则的格式是正则表达式语法的一个子集(由星号作为通配符和组成程序集和类名的字符组成,非常有限,但足以获得所需的数据)。查看手册中的规则部分。如果你没有手册, download it from sourceforge .

        2
  •  17
  •   pelazem    15 年前

    当从NAnt脚本调用PartCover时,我必须经历一系列步骤才能使其工作。我收集了我在这里所做的一切,以方便别人;请注意,其中一些问题已经得到了其他人的回答,但我花了大量时间把它们放在一起。

    首先,正如本文其他部分所回答的那样,如果你的操作系统是64位的,你需要运行[最新的Windows SDK]\bin\CorFlags.exe[PartCover安装目录]\PartCover.exe/32BIT+/Force

    这是安装PartCover后的一次性步骤。它将更改可执行文件,并警告您需要重新签名程序集,但我没有这样做,它(最终)运行良好。请注意,尽管看起来CorFlags没有按照您的要求和警告进行签名,但它确实更改了.exe,只是没有明确指出这一点。

    接下来,如果您的操作系统是64位的,并且您将NUnit(或另一个测试exe)与PartCover一起使用,您将需要调用为x86显式编译的版本。在NUnit的情况下,这将是NUnit-console-x86.exe。调用nunit-console.exe只会在完成工作后无限期挂起,而不会返回提示。

    接下来,正如本文其他地方所回答的那样,开发版本PartCover 2.3即使在运行CorFlags后也会悄无声息地失败。然而,2.2仍然有效。

    接下来,当调用PartCover.exe时,参数的语法为 --arg名称。..和NOT--=arg名称(即破折号空格arg名称,非破折号破折号等于arg名称);PartCover文档似乎是双向的,但等号对我不起作用。

    在上述操作之后,PartCover终于可以从命令行开始工作了。我使用了一个设置文件(您可以使用PartCover浏览器UI应用程序保存设置文件,然后可以从命令行使用),因此我指定的唯一参数是设置文件完整路径和输出报告文件名完整路径。

    当从NAnt脚本调用时,这仍然不起作用,所以我终于意识到必须引用arg值。..并使用HTML编码的标记作为引号。因此。..

    无摘录:

    <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
  •  3
  •   Community CDub    8 年前

    我对PartCover报告也有同样的问题。所以我一直在努力让它正常工作,我刚刚发现问题出在PartCover发行版附带的两个XSLT文件上。

    我修复了这些文件,现在一切对我来说都很好:

    按组件报告

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

    我希望你觉得这有用。此外,欢迎对这些文件提出任何反馈,这样我们就可以为通勤者提供正确的文件。 See this related question

        4
  •  1
  •   community wiki David Laing    14 年前

    @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) Gspr-Nagy的HTML报告相当不错- http://gasparnagy.blogspot.com/2010/09/detailed-report-for-partcover-in.html

        5
  •  0
  •   Dan Nuffer    16 年前

    在使用PartCover 2.3.0.18745版本时,我的代码也出现了类似的问题,没有显示在报告中。使用版本2.2.0.34631解决了这个问题。