This project has moved. For the latest updates, please go here.

Add another XML input format

Aug 17, 2012 at 3:14 PM

Hi all,

I am using vs2010 for native C/C++ and, while it is possible to obtain coverage data, it lacks any kind of report, so it would be great to use this tool.

It is possible, however, to export coverage data in XML.

The question is : what are the steps needed to add another XML input format ?

 

thanks and best regards

Paolo Argenton

 

Coordinator
Aug 19, 2012 at 7:35 PM

Hi Paolo,

if I remember correctly, the XML report generated by VS210 does not contain the necessary information to use it within ReportGenerator.

Could you please post a sample XML report, then I can have a quick look if the required information is available.

Thanks

Daniel

Aug 27, 2012 at 9:23 AM

Hi Daniel,

 

thanks for the answer,

this is an extract of the xml generated (first lines)

 

<CoverageDSPriv>
<xs:schema id="CoverageDSPriv" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:msprop="urn:schemas-microsoft-com:xml-msprop">
<xs:element name="CoverageDSPriv" msdata:IsDataSet="true" msdata:UseCurrentLocale="true" msdata:EnforceConstraints="False" msprop:Version="8.00">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Module">
<xs:complexType>
<xs:sequence>
<xs:element name="ModuleName" type="xs:string" />
<xs:element name="ImageSize" type="xs:unsignedInt" />
<xs:element name="ImageLinkTime" type="xs:unsignedInt" />
<xs:element name="LinesCovered" type="xs:unsignedInt" minOccurs="0" />
<xs:element name="LinesPartiallyCovered" type="xs:unsignedInt" minOccurs="0" />
<xs:element name="LinesNotCovered" type="xs:unsignedInt" minOccurs="0" />
<xs:element name="BlocksCovered" type="xs:unsignedInt" minOccurs="0" />
<xs:element name="BlocksNotCovered" type="xs:unsignedInt" minOccurs="0" />
<xs:element name="NamespaceTable" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="BlocksCovered" type="xs:unsignedInt" minOccurs="0" />
<xs:element name="BlocksNotCovered" type="xs:unsignedInt" minOccurs="0" />
<xs:element name="LinesCovered" type="xs:unsignedInt" minOccurs="0" />
<xs:element name="LinesNotCovered" type="xs:unsignedInt" minOccurs="0" />
<xs:element name="LinesPartiallyCovered" type="xs:unsignedInt" minOccurs="0" />
<xs:element name="ModuleName" type="xs:string" minOccurs="0" />
<xs:element name="NamespaceKeyName" type="xs:string" />
<xs:element name="NamespaceName" type="xs:string" minOccurs="0" />
<xs:element name="Class" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="ClassKeyName" type="xs:string" />
<xs:element name="ClassName" type="xs:string" />
<xs:element name="LinesCovered" type="xs:unsignedInt" minOccurs="0" />
<xs:element name="LinesNotCovered" type="xs:unsignedInt" minOccurs="0" />
<xs:element name="LinesPartiallyCovered" type="xs:unsignedInt" minOccurs="0" />
<xs:element name="BlocksCovered" type="xs:unsignedInt" minOccurs="0" />
<xs:element name="BlocksNotCovered" type="xs:unsignedInt" minOccurs="0" />
<xs:element name="NamespaceKeyName" type="xs:string" minOccurs="0" />
<xs:element name="Method" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="MethodKeyName" type="xs:string" msdata:Ordinal="0" />
<xs:element name="MethodName" type="xs:string" msdata:Ordinal="1" />
<xs:element name="MethodFullName" type="xs:string" minOccurs="0" msdata:Ordinal="2" />
<xs:element name="LinesCovered" type="xs:unsignedInt" minOccurs="0" msdata:Ordinal="3" />
<xs:element name="LinesPartiallyCovered" type="xs:unsignedInt" minOccurs="0" msdata:Ordinal="4" />
<xs:element name="LinesNotCovered" type="xs:unsignedInt" minOccurs="0" msdata:Ordinal="5" />
<xs:element name="BlocksCovered" type="xs:unsignedInt" minOccurs="0" msdata:Ordinal="6" />
<xs:element name="BlocksNotCovered" type="xs:unsignedInt" minOccurs="0" msdata:Ordinal="7" />
<xs:element name="Lines" msdata:CaseSensitive="False" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="LnStart" type="xs:unsignedInt" msdata:Ordinal="0" />
<xs:element name="ColStart" type="xs:unsignedInt" msdata:Ordinal="1" />
<xs:element name="LnEnd" type="xs:unsignedInt" msdata:Ordinal="2" />
<xs:element name="ColEnd" type="xs:unsignedInt" msdata:Ordinal="3" />
<xs:element name="Coverage" type="xs:unsignedInt" msdata:Ordinal="4" />
<xs:element name="SourceFileID" type="xs:unsignedInt" msdata:Ordinal="5" />
<xs:element name="LineID" type="xs:unsignedInt" msdata:Ordinal="7" />
</xs:sequence>
<xs:attribute name="MethodKeyName" type="xs:string" use="prohibited" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="ClassKeyName" type="xs:string" use="prohibited" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SourceFileNames">
<xs:complexType>
<xs:sequence>
<xs:element name="SourceFileID" type="xs:unsignedInt" />
<xs:element name="SourceFileName" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
<xs:unique name="LineID" msdata:PrimaryKey="true">
<xs:selector xpath=".//Lines" />
<xs:field xpath="LineID" />
</xs:unique>
<xs:unique name="MethodKey" msdata:PrimaryKey="true">
<xs:selector xpath=".//Method" />
<xs:field xpath="MethodKeyName" />
</xs:unique>
<xs:unique name="ClassKey" msdata:PrimaryKey="true">
<xs:selector xpath=".//Class" />
<xs:field xpath="ClassKeyName" />
</xs:unique>
<xs:unique name="NamespaceKeyName" msdata:PrimaryKey="true">
<xs:selector xpath=".//NamespaceTable" />
<xs:field xpath="NamespaceKeyName" />
</xs:unique>
<xs:unique name="ModuleKey" msdata:PrimaryKey="true">
<xs:selector xpath=".//Module" />
<xs:field xpath="ModuleName" />
</xs:unique>
<xs:unique name="SourceFileIDKey" msdata:PrimaryKey="true">
<xs:selector xpath=".//SourceFileNames" />
<xs:field xpath="SourceFileID" />
</xs:unique>
<xs:keyref name="Module_Namespace" refer="ModuleKey" msdata:IsNested="true">
<xs:selector xpath=".//NamespaceTable" />
<xs:field xpath="ModuleName" />
</xs:keyref>
<xs:keyref name="Namespace_Class" refer="NamespaceKeyName" msdata:IsNested="true">
<xs:selector xpath=".//Class" />
<xs:field xpath="NamespaceKeyName" />
</xs:keyref>
<xs:keyref name="Class_Method" refer="ClassKey" msdata:IsNested="true">
<xs:selector xpath=".//Method" />
<xs:field xpath="@ClassKeyName" />
</xs:keyref>
<xs:keyref name="SourceFileNames_Lines" refer="SourceFileIDKey" msdata:ConstraintOnly="true">
<xs:selector xpath=".//Lines" />
<xs:field xpath="SourceFileID" />
</xs:keyref>
<xs:keyref name="Method_Lines" refer="MethodKey" msdata:IsNested="true">
<xs:selector xpath=".//Lines" />
<xs:field xpath="@MethodKeyName" />
</xs:keyref>
</xs:element>
</xs:schema>
<Module>
<ModuleName>cfsm_tcpip.dll</ModuleName>
<ImageSize>1654784</ImageSize>
<ImageLinkTime>0</ImageLinkTime>
<LinesCovered>1631</LinesCovered>
<LinesPartiallyCovered>28</LinesPartiallyCovered>
<LinesNotCovered>1810</LinesNotCovered>
<BlocksCovered>1353</BlocksCovered>
<BlocksNotCovered>1676</BlocksNotCovered>
<NamespaceTable>
<BlocksCovered>1353</BlocksCovered>
<BlocksNotCovered>1676</BlocksNotCovered>
<LinesCovered>1631</LinesCovered>
<LinesNotCovered>1810</LinesNotCovered>
<LinesPartiallyCovered>28</LinesPartiallyCovered>
<ModuleName>cfsm_tcpip.dll</ModuleName>
<NamespaceKeyName>cfsm_tcpip.dll</NamespaceKeyName>
<NamespaceName />
<Class>
<ClassKeyName>cfsm_tcpip.dll</ClassKeyName>
<ClassName />
<LinesCovered>1631</LinesCovered>
<LinesNotCovered>1810</LinesNotCovered>
<LinesPartiallyCovered>28</LinesPartiallyCovered>
<BlocksCovered>1353</BlocksCovered>
<BlocksNotCovered>1676</BlocksNotCovered>
<NamespaceKeyName>cfsm_tcpip.dll</NamespaceKeyName>
<Method>
<MethodKeyName>cfsm_tcpip.dll!1</MethodKeyName>
<MethodName>iTIMERS_pause_all_timers</MethodName>
<MethodFullName>_iTIMERS_pause_all_timers</MethodFullName>
<LinesCovered>11</LinesCovered>
<LinesPartiallyCovered>0</LinesPartiallyCovered>
<LinesNotCovered>0</LinesNotCovered>
<BlocksCovered>10</BlocksCovered>
<BlocksNotCovered>0</BlocksNotCovered>
<Lines>
<LnStart>267</LnStart>
<ColStart>0</ColStart>
<LnEnd>267</LnEnd>
<ColEnd>0</ColEnd>
<Coverage>0</Coverage>
<SourceFileID>1</SourceFileID>
<LineID>0</LineID>
</Lines>
<Lines>
<LnStart>268</LnStart>
<ColStart>0</ColStart>
<LnEnd>268</LnEnd>
<ColEnd>0</ColEnd>
<Coverage>0</Coverage>
<SourceFileID>1</SourceFileID>
<LineID>1</LineID>
</Lines>

Coordinator
Aug 28, 2012 at 11:55 AM

Hi Paolo,

I took a quick look at the report and I think it should be possible to support this format in ReportGenerator.

I hope I will find some time within the next 2 weeks.

Best regards

Daniel

Aug 28, 2012 at 2:01 PM

Hi Daniel,

that would be great, if you need a complete XML file let me know, I was not able to attach the file to the discussion.

 

p.s. I actually found a xslt  to convert this xml to a summary HTML report, but what is really interesting is the capability to visualize the source code lines, since, for some reasons, in native c/c++ vs2010 line coloring is disabled and so browsing coverage data in the ide is confusing.

Below is the css file I'm using (it is not mine, I found it in some visual studio blog but I do not remember where)

Regards

Paolo Argenton

 

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:param name="low_coverage" select="60"/>
  <xsl:param name="ok_coverage" select="30"/>
<xsl:template match="/">
    <html>
    <body>
      <h1>Detail coverage report</h1>
      <h2> Assembly coverage</h2>
      <table style="width:640;border:2px solid black;">
          <tr>
            <td style="font-weight:bold">Assembly</td>
            <td style="text-align:right;font-weight:bold">Blocks not covered</td>
            <td style="text-align:right;font-weight:bold">% blocks not covered</td>
          </tr>
        <xsl:for-each select="//Method">
          <tr>
            <td>
              <xsl:value-of select="MethodName"/>
            </td>
            <td style="text-align:right">
              <xsl:value-of select="BlocksNotCovered"/>
            </td>
            <td>
              <xsl:variable name="pct" select="(BlocksNotCovered div (BlocksNotCovered + BlocksCovered))*100"/>
              <xsl:attribute name="style">
                text-align:right;
                <xsl:choose>
                  <xsl:when test="number($pct &gt;= $low_coverage)">background-color:red;</xsl:when>
                  <xsl:when test="number($pct &gt;= $ok_coverage)">background-color:yellow;</xsl:when>
                  <xsl:otherwise>background-color:green;</xsl:otherwise>
                </xsl:choose>
              </xsl:attribute>
              <xsl:value-of select="$pct"/>
            </td>
          </tr>
        </xsl:for-each>
        </table>
    </body>
    </html>
</xsl:template>
</xsl:stylesheet>

Coordinator
Aug 30, 2012 at 7:15 PM

Hi Paolo,

I just added support for Visual Studio reports!

Could you please test this (beta) release: http://dl.dropbox.com/u/21096596/ReportGenerator_1.6.0.0_Beta.zip

Let me know if any errors occur during report generation and if the report looks as expected.

Thanks for your help.

Daniel

Aug 31, 2012 at 6:23 AM

wow Daniel thanks a lot !

 

Sure, I will test the beta and keep you informed

 

thanks again

Aug 31, 2012 at 6:27 AM

Hi Daniel,

sorry but I can't test it immediately as I hoped, I must download the beta from home, next week I will let you know how it behaves with actual coverage data from a C project

 

thanks again

Sep 3, 2012 at 7:24 AM

Hi Daniel,

very good news, I just tested it and it just worked ok.

I will keep you informed, in the meantime thanks again for this work, it really fills a need, since there is nothing available in standard visual studio 2010 for native c/c++.

Regards

Paolo