Vb.net Sonar Runner在处理Visual Studio';生成的.coverage XML文件时出错;MSS测试

Vb.net Sonar Runner在处理Visual Studio';生成的.coverage XML文件时出错;MSS测试,vb.net,visual-studio-2013,sonarqube,Vb.net,Visual Studio 2013,Sonarqube,我正在尝试处理从命令行使用MSTest后得到的.coverage xml文件(在转换.coverage文件之后),但Sonar Runner在尝试解析该文件时一直失败。 错误包括解析错误,例如意外的“?”以及无法在文件中找到标记 我尝试了几种获取.coveragexml文件的方法:从命令行使用“vsinstr-coverage…”和“start-vsperfmon-coverage…”命令(然后运行MSTest),更改 .testrunconfig文件,并指示要获取覆盖率的DLL,并尝试使用“C

我正在尝试处理从命令行使用MSTest后得到的.coverage xml文件(在转换.coverage文件之后),但Sonar Runner在尝试解析该文件时一直失败。 错误包括解析错误,例如意外的“?”以及无法在文件中找到标记

我尝试了几种获取.coveragexml文件的方法:从命令行使用“vsinstr-coverage…”和“start-vsperfmon-coverage…”命令(然后运行MSTest),更改 .testrunconfig文件,并指示要获取覆盖率的DLL,并尝试使用“CodeCoverage.exe collect…”。前两个让我成功地获得了代码覆盖率数据, 但我在获取“CodeCoverage.exe collect…”以收集结果时遇到问题。尽管我可以从前两个收集代码覆盖率结果,但是.coveragexml文件 尽管SonarQube在其VB.NET插件网页上表示支持MSTest和VSTest XML代码覆盖率文件,但生成的格式似乎并不符合SonarQube接受的正确格式。 我尝试过使用VSTest,可以让Sonarqube接受我的.coveragexml文件,没有任何错误。问题是我实习的公司使用MSTest来运行所有的测试 所以我需要使用MSTest获取.coveragexml数据

我注意到的另一件事是,当我尝试在VisualStudio中将.coverage文件导出为.coverage XML时(对于MSTest或VSTest),它会生成一个.coverage XML格式 不接受(它只是由于我上面提到的错误而出错)。当我使用“CodeCoverage.exe analyze…”命令从VSTest转换.coverage文件时,它会生成一个 .coverage XML格式,Sonarqube接受该格式,因为我没有收到任何错误,并且可以在仪表板上看到我的代码覆盖率结果。现在,当我尝试使用“CodeCoverage.exe analyze…”命令转换 MSTest中的.coverage文件,没有发生任何事情。不会生成.coveragexml文件,不会给出错误或任何类型的反馈。我还尝试编写一个C#方法来转换.coverage 使用Microsoft.VisualStudio.Coverage.Analysis将文件转换为.Coverage XML文件。但它生成的.coveragexml文件的格式与我从VisualStudio导出时的格式相同

其他可能有助于了解的事项:

  • 我正在运行VB.NET代码的分析
  • 我使用的是Sonarqube的2.2版VB.NET插件
  • 我使用的是Sonarqube的4.3.2版和Sonarqube Runner的2.4版
  • 我正在使用Visual Studio 2013 Premium
(可能会出现错误) 从Visual Studio导出.coverage XML文件后,其格式如下所示:

<CoverageDSPriv>
<xs:schema ...>
  ...
</xs:schema>
<Module>
  <ModuleName>...</ModuleName>
  <ImageSize>...</ImageSize>
  ...
  <NameSpaceTable>
    <BlocksCovered>...</BlocksCovered>
    ...

...
...
...
...
...
...
(库贝接受) 使用“CodeCoverage.exe analyze…”后.coverage XML文件的格式(仅适用于VSTest的.coverage文件)


...

看起来这个数据有两种完全不同的模式,SonarQube只接受其中一种,是这样吗?是否有其他方法将.coverage数据转换为SonarQube接受的数据?

我认为您已经完美地描述了这种情况:确实有两种完全不同的代码覆盖率报告,它们都使用了*.coverage XML扩展名


C#和VB.NET插件目前只支持其中一种格式,并且存在一个票证来添加对另一种格式的支持:

我创建这个XSLT是为了以良好的格式转换coveragexml文件

<xsl:output method="xml" indent="yes"/>

<xsl:template match="CoverageDSPriv">
    <results>
        <modules>
            <xsl:for-each select="Module">
                <xsl:element name="module">
                    <xsl:attribute name="name">
                        <xsl:value-of select="ModuleName"/>
                    </xsl:attribute>
                    <xsl:attribute name="path">
                        <xsl:value-of select="ModuleName"/>
                    </xsl:attribute>
                    <xsl:attribute name="block_coverage">
                        <xsl:value-of select="BlocksCovered div (BlocksCovered + BlocksNotCovered) * 100"/>
                    </xsl:attribute>
                    <xsl:attribute name="line_coverage">
                        <xsl:value-of select="LinesCovered div (LinesCovered + LinesPartiallyCovered + LinesNotCovered) * 100"/>
                    </xsl:attribute>
                    <xsl:attribute name="blocks_covered">
                        <xsl:value-of select="BlocksCovered"/>
                    </xsl:attribute>
                    <xsl:attribute name="blocks_not_covered">
                        <xsl:value-of select="BlocksNotCovered"/>
                    </xsl:attribute>
                    <xsl:attribute name="lines_covered">
                        <xsl:value-of select="LinesCovered"/>
                    </xsl:attribute>
                    <xsl:attribute name="lines_partially_covered">
                        <xsl:value-of select="LinesPartiallyCovered"/>
                    </xsl:attribute>
                    <xsl:attribute name="lines_not_covered">
                        <xsl:value-of select="LinesNotCovered"/>
                    </xsl:attribute>
                    <xsl:for-each select="NamespaceTable">
                        <xsl:for-each select="Class">
                            <functions>
                                <xsl:for-each select="Method">
                                    <xsl:element name="function">
                                        <xsl:attribute name="name">
                                            <xsl:value-of select="substring-before(MethodName, '()')"/>
                                        </xsl:attribute>
                                        <xsl:attribute name="type_name">
                                            <xsl:value-of select="../ClassName"/>
                                        </xsl:attribute>
                                        <xsl:attribute name="block_coverage">
                                            <xsl:value-of select="BlocksCovered div (BlocksCovered + BlocksNotCovered) * 100"/>
                                        </xsl:attribute>
                                        <xsl:attribute name="line_coverage">
                                            <xsl:value-of select="LinesCovered div (LinesCovered + LinesPartiallyCovered + LinesNotCovered) * 100"/>
                                        </xsl:attribute>
                                        <xsl:attribute name="blocks_covered">
                                            <xsl:value-of select="BlocksCovered"/>
                                        </xsl:attribute>
                                        <xsl:attribute name="blocks_not_covered">
                                            <xsl:value-of select="BlocksNotCovered"/>
                                        </xsl:attribute>
                                        <xsl:attribute name="lines_covered">
                                            <xsl:value-of select="LinesCovered"/>
                                        </xsl:attribute>
                                        <xsl:attribute name="lines_partially_covered">
                                            <xsl:value-of select="LinesPartiallyCovered"/>
                                        </xsl:attribute>
                                        <xsl:attribute name="lines_not_covered">
                                            <xsl:value-of select="LinesNotCovered"/>
                                        </xsl:attribute>
                                        <ranges>
                                            <xsl:for-each select="Lines">
                                                <xsl:element name="range">
                                                    <xsl:attribute name="source_id">
                                                        <xsl:value-of select="SourceFileID"/>
                                                    </xsl:attribute>
                                                    <xsl:attribute name="covered">
                                                        <xsl:choose>
                                                            <xsl:when test="Coverage=0">yes</xsl:when>
                                                            <xsl:when test="Coverage=1">partial</xsl:when>
                                                            <xsl:when test="Coverage=2">no</xsl:when>
                                                        </xsl:choose>
                                                    </xsl:attribute>
                                                    <xsl:attribute name="start_line">
                                                        <xsl:value-of select="LnStart"/>
                                                    </xsl:attribute>
                                                    <xsl:attribute name="start_column">
                                                        <xsl:value-of select="ColStart"/>
                                                    </xsl:attribute>
                                                    <xsl:attribute name="end_line">
                                                        <xsl:value-of select="LnEnd"/>
                                                    </xsl:attribute>
                                                    <xsl:attribute name="end_column">
                                                        <xsl:value-of select="ColEnd"/>
                                                    </xsl:attribute>
                                                </xsl:element>
                                            </xsl:for-each>
                                        </ranges>
                                    </xsl:element>
                                </xsl:for-each>
                            </functions>
                            <source_files>
                                <xsl:for-each select="../../../SourceFileNames">
                                    <xsl:element name="source_file">
                                        <xsl:attribute name="id">
                                            <xsl:value-of select="SourceFileID"/>
                                        </xsl:attribute>
                                        <xsl:attribute name="path">
                                            <xsl:value-of select="SourceFileName"/>
                                        </xsl:attribute>
                                    </xsl:element>
                                </xsl:for-each>
                            </source_files>
                        </xsl:for-each>
                    </xsl:for-each>
                </xsl:element>
            </xsl:for-each>
        </modules>
    </results>
</xsl:template>

<xsl:output method="xml" indent="yes"/>

<xsl:template match="CoverageDSPriv">
    <results>
        <modules>
            <xsl:for-each select="Module">
                <xsl:element name="module">
                    <xsl:attribute name="name">
                        <xsl:value-of select="ModuleName"/>
                    </xsl:attribute>
                    <xsl:attribute name="path">
                        <xsl:value-of select="ModuleName"/>
                    </xsl:attribute>
                    <xsl:attribute name="block_coverage">
                        <xsl:value-of select="BlocksCovered div (BlocksCovered + BlocksNotCovered) * 100"/>
                    </xsl:attribute>
                    <xsl:attribute name="line_coverage">
                        <xsl:value-of select="LinesCovered div (LinesCovered + LinesPartiallyCovered + LinesNotCovered) * 100"/>
                    </xsl:attribute>
                    <xsl:attribute name="blocks_covered">
                        <xsl:value-of select="BlocksCovered"/>
                    </xsl:attribute>
                    <xsl:attribute name="blocks_not_covered">
                        <xsl:value-of select="BlocksNotCovered"/>
                    </xsl:attribute>
                    <xsl:attribute name="lines_covered">
                        <xsl:value-of select="LinesCovered"/>
                    </xsl:attribute>
                    <xsl:attribute name="lines_partially_covered">
                        <xsl:value-of select="LinesPartiallyCovered"/>
                    </xsl:attribute>
                    <xsl:attribute name="lines_not_covered">
                        <xsl:value-of select="LinesNotCovered"/>
                    </xsl:attribute>
                    <xsl:for-each select="NamespaceTable">
                        <xsl:for-each select="Class">
                            <functions>
                                <xsl:for-each select="Method">
                                    <xsl:element name="function">
                                        <xsl:attribute name="name">
                                            <xsl:value-of select="substring-before(MethodName, '()')"/>
                                        </xsl:attribute>
                                        <xsl:attribute name="type_name">
                                            <xsl:value-of select="../ClassName"/>
                                        </xsl:attribute>
                                        <xsl:attribute name="block_coverage">
                                            <xsl:value-of select="BlocksCovered div (BlocksCovered + BlocksNotCovered) * 100"/>
                                        </xsl:attribute>
                                        <xsl:attribute name="line_coverage">
                                            <xsl:value-of select="LinesCovered div (LinesCovered + LinesPartiallyCovered + LinesNotCovered) * 100"/>
                                        </xsl:attribute>
                                        <xsl:attribute name="blocks_covered">
                                            <xsl:value-of select="BlocksCovered"/>
                                        </xsl:attribute>
                                        <xsl:attribute name="blocks_not_covered">
                                            <xsl:value-of select="BlocksNotCovered"/>
                                        </xsl:attribute>
                                        <xsl:attribute name="lines_covered">
                                            <xsl:value-of select="LinesCovered"/>
                                        </xsl:attribute>
                                        <xsl:attribute name="lines_partially_covered">
                                            <xsl:value-of select="LinesPartiallyCovered"/>
                                        </xsl:attribute>
                                        <xsl:attribute name="lines_not_covered">
                                            <xsl:value-of select="LinesNotCovered"/>
                                        </xsl:attribute>
                                        <ranges>
                                            <xsl:for-each select="Lines">
                                                <xsl:element name="range">
                                                    <xsl:attribute name="source_id">
                                                        <xsl:value-of select="SourceFileID"/>
                                                    </xsl:attribute>
                                                    <xsl:attribute name="covered">
                                                        <xsl:choose>
                                                            <xsl:when test="Coverage=0">yes</xsl:when>
                                                            <xsl:when test="Coverage=1">partial</xsl:when>
                                                            <xsl:when test="Coverage=2">no</xsl:when>
                                                        </xsl:choose>
                                                    </xsl:attribute>
                                                    <xsl:attribute name="start_line">
                                                        <xsl:value-of select="LnStart"/>
                                                    </xsl:attribute>
                                                    <xsl:attribute name="start_column">
                                                        <xsl:value-of select="ColStart"/>
                                                    </xsl:attribute>
                                                    <xsl:attribute name="end_line">
                                                        <xsl:value-of select="LnEnd"/>
                                                    </xsl:attribute>
                                                    <xsl:attribute name="end_column">
                                                        <xsl:value-of select="ColEnd"/>
                                                    </xsl:attribute>
                                                </xsl:element>
                                            </xsl:for-each>
                                        </ranges>
                                    </xsl:element>
                                </xsl:for-each>
                            </functions>
                            <source_files>
                                <xsl:for-each select="../../../SourceFileNames">
                                    <xsl:element name="source_file">
                                        <xsl:attribute name="id">
                                            <xsl:value-of select="SourceFileID"/>
                                        </xsl:attribute>
                                        <xsl:attribute name="path">
                                            <xsl:value-of select="SourceFileName"/>
                                        </xsl:attribute>
                                    </xsl:element>
                                </xsl:for-each>
                            </source_files>
                        </xsl:for-each>
                    </xsl:for-each>
                </xsl:element>
            </xsl:for-each>
        </modules>
    </results>
</xsl:template>