Ошибки Sonar Runner при обработке файла.coveragexml, созданного из Visual Studio MSTest

Я пытаюсь обработать мой файл.coveragexml (после преобразования файла.coverage), который я получаю после использования MSTest из командной строки, но Sonar Runner продолжает давать сбой, когда пытается проанализировать файл. Ошибки состоят из ошибок синтаксического анализа, таких как неожиданное '?' а также не в состоянии найти тег в файле.

Я попробовал несколько способов получить файл.coveragexml: с помощью команд "vsinstr -coverage ..." и "start vsperfmon -coverage ..." (затем запустив MSTest) из командной строки, изменив файл.testrunconfig и указав, какие библиотеки я хочу получить покрытие, и попытался с помощью "CodeCoverage.exe собирать...". Первые два дали мне успех при получении данных о покрытии кода, но у меня были проблемы с получением "CodeCoverage.exe collect ..." для сбора результатов. Несмотря на то, что я могу получить результаты покрытия кода кода из первых двух, созданный файл.coveragexml, похоже, не в том формате, который принимает SonarQube, даже несмотря на то, что они указывают на своей веб-странице плагина VB.NET, что они поддерживают MSTest и VSTest XML-файлы покрытия кода. Я попытался использовать VSTest и могу получить мои файлы.coveragexml, которые будут приняты Sonarqube без каких-либо ошибок просто отлично. Проблема в том, что компания, для которой я стажируюсь, использует MSTest для запуска всех своих модульных тестов, поэтому мне нужно получить данные.coveragexml от использования MSTest.

Еще я заметил, что когда я пытаюсь экспортировать файл.coverage в виде.coveragexml в Visual Studio (как для MSTest, так и для VSTest), он создает формат.coveragexml, который Sonarqube не принимает (он просто выдает ошибку из-за ошибки я упоминал выше). Когда я использую команду "CodeCoverage.exe analysis..." для преобразования файла.coverage из VSTest, он создает формат.coveragexml, который Sonarqube принимает, так как я не получаю ошибок и вижу результаты покрытия моего кода на панели инструментов. Теперь, когда я пытаюсь использовать команду "CodeCoverage.exe analysis..." для преобразования файла.coverage из MSTest, ничего не происходит. Файл.coveragexml не создается, а также нет ошибок или каких-либо отзывов. Я также попытался написать метод C# для преобразования файла.coverage в файл.coveragexml с помощью Microsoft.VisualStudio.Coverage.Analysis. Но он создает тот же формат файла.coveragexml, как если бы я экспортировал его из Visual Studio.

Другие вещи, которые может быть полезно знать:

  • Я выполняю анализ кода VB.NET.
  • Я использую версию 2.2 плагина VB.NET от Sonarqube.
  • Я использую версию 4.3.2 Sonarqube и версию 2.4 Runar SonarQube.
  • Я использую Visual Studio 2013 Premium.

(Ошибка SonarQube) Формат файла.coveragexml после его экспорта из Visual Studio выглядит следующим образом:

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

(SonarQube принимает) Формат файла.coveragexml после использования "CodeCoverage.exe анализ..." (работает только с файлом 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="..." >
        ...

Похоже, что есть две совершенно разные схемы для этих данных, и SonarQube принимает только одну из них, так ли это? Есть ли другой способ преобразовать данные.coverage в тот, который принимает SonarQube?

2 ответа

Решение

Я думаю, что вы отлично описали ситуацию: действительно есть два совершенно разных отчета о покрытии кода, в обоих из которых используется расширение *.coveragexml.

Плагин C# и VB.NET на данный момент поддерживает только один из этих форматов, и существует билет для добавления поддержки другого: https://jira.codehaus.org/browse/SONARNTEST-3

Я создал этот XSLT, чтобы преобразовать файл coverxml в хороший формат.

<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>
Другие вопросы по тегам