.netteamcitypartcover

How do I include full PartCover results with TeamCity 5?


I'm trying to get PartCover reports to generate correctly in TeamCity 5.0. When I click the Code Coverage tab in the build details, the reports are empty.

I'm using the sln2008 build agent and my PartCoverage settings are as follows:

Include Patterns:

[*]*

Report XSLT:

C:\Program Files\PartCover .NET 2.3\xslt\Report By Assembly.xslt=>ByAssembly.html
C:\Program Files\PartCover .NET 2.3\xslt\Report By Class.xslt=>ByClass.html

Bonus points if you can describe how to include those reports (or just the important parts) with the email that TeamCity sends for successful/failed builds. I would like to continue using the sln2008 build agent, if possible, and not a different build agent.


Solution

  • I had the same problem with the PartCover reports. So I have been trying to make it work right and I just discovered that the problem was the two XSLT files that come with the PartCover distribution.

    I fixed these files and now everything is working fine for me:

    report by assembly

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

    report by class

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

    I hope you find this useful. Also, any feedback about this files is welcomed, so we can provide the commutiy with correct files.