Sonar Runner在处理从Visual Studio的MSTest生成的.coveragexml文件时出错

Lop*_*s08 5 vb.net visual-studio-2013 sonarqube

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

我尝试了几种方法来获取.coveragexml文件:使用命令行中的"vsinstr -coverage ..."和"start vsperfmon -coverage ..."命令(然后运行MSTest),更改.testrunco​​nfig文件和指示我想要覆盖哪些dll,并尝试使用"CodeCoverage.exe collect ...".前两个让我在获取代码覆盖率数据方面取得了成功,但我遇到了"CodeCoverage.exe collect ..."收集结果的问题.即使我可以从前两个获得收集代码覆盖率结果,生成的.coveragexml文件似乎没有SonarQube接受的正确格式,即使他们在他们的VB.NET插件网页上指出他们支持MSTest和VSTest XML代码覆盖文件.我尝试过使用VSTest,可以让Sonarqube接受我的.coveragexml文件,没有任何错误.问题是我实习的公司使用MSTest来运行所有的单元测试,所以我需要从使用MSTest获取.coveragexml数据.

我注意到的另一件事是,当我尝试将.coverage文件导出为Visual Studio中的.coveragexml(对于MSTest或VSTest)时,它会生成一个Sonarqube不接受的.coveragexml格式(由于我上面提到的错误).当我使用"CodeCoverage.exe analyze ..."命令从.VSTest转换.coverage文件时,它会生成Sonarqube接受的.coveragexml格式,因为我没有收到错误,可以在仪表板上看到我的代码覆盖率结果.现在,当我尝试使用"CodeCoverage.exe analyze ..."命令从MSTest转换.coverage文件时,没有任何反应.不会生成.coveragexml文件,也不会出现任何错误或任何反馈.我还尝试编写一个C#方法,使用Microsoft.VisualStudio.Coverage.Analysis将.coverage文件转换为.coveragexml文件.但它生成相同格式的.coveragexml文件,就像我从Visual Studio导出它一样.

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

  • 我正在运行VB.NET代码的分析.
  • 我正在使用Sonarqube的2.2版VB.NET插件.
  • 我正在使用Sonarqube的4.3.2版本和SonarQube Runner的2.4版本.
  • 我正在使用Visual Studio 2013 Premium.

(SonarQube错误输出).coveragexml文件从Visual Studio导出后的格式如下所示:

<CoverageDSPriv>
<xs:schema ...>
  ...
</xs:schema>
<Module>
  <ModuleName>...</ModuleName>
  <ImageSize>...</ImageSize>
  ...
  <NameSpaceTable>
    <BlocksCovered>...</BlocksCovered>
    ...
Run Code Online (Sandbox Code Playgroud)

(SonarQube接受)使用"CodeCoverage.exe analyze ..."后的.coveragexml文件的格式(仅适用于VSTest的.coverage文件)

<?xml version="1.0" encoding="UTF-8" ?>
<results>
  <modules>
    <module name="..." path="..." id="..." block_coverage="..." line_coverage="..."  blocks_covered="..." ... >
      <functions>
        <function id="..." token="..." name="..." type_name="..." block_coverage="..." >
        ...
Run Code Online (Sandbox Code Playgroud)

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

Flo*_*oyd 7

我已创建此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>
Run Code Online (Sandbox Code Playgroud)

  • 我的朋友,这太棒了.我能够使用这个XSLT转换coveragexml.我可以从中导入结果.非常感谢! (3认同)

Din*_*eyn 1

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

C# 和 VB.NET 插件目前仅支持其中一种格式,并且存在添加对另一种格式的支持的票证:https ://jira.codehaus.org/browse/SONARNTEST-3