3

次の構造のアプリケーションがあります。

my-application
  +- pom.xml
  +- app
  |   +- scripts
  |   |   +- app.js
  |   |   +- **/*.js
  |   +- 3rd-party-libs
  +- build
  +- node_modules
  +- test

pom.xmlSonarQube 分析を実行するためだけに作成しました。それ以外の場合、すべてのタスクは Grunt によって実行されます (テストは Karma で実行されます)。

の内容はpom.xml次のとおりです。

<properties>
    <sonar.language>js</sonar.language>
    <sonar.sourceEncoding>UTF-8</sonar.sourceEncoding>
    <sonar.javascript.coveragePlugin>lcov</sonar.javascript.coveragePlugin>
    <sonar.javascript.lcov.reportPath>build/karma/coverage/lcov.info</sonar.javascript.lcov.reportPath>
    <sonar.exclusions>app/3rd-party-libs/**,node_modules/**</sonar.exclusions>
    <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
</properties>

<build>
    <sourceDirectory>app/scripts</sourceDirectory>
    <testSourceDirectory>test</testSourceDirectory>
</build>

を実行すると、次の情報を含む がgrunt test作成されます。build/karma/coverage/lcov.info

TN:
SF:./app/scripts/app.js
FN:16,(anonymous_1)
FN:26,(anonymous_2)
FNF:2
...

SonarQube 分析の後、ダッシュボードには 0% のコード カバレッジが表示されます。

のパスがSF:エラーの原因であると思われました。したがって、別の値をテストするために別のプロパティを使用するsonar.javascript.lcov.reportPathようにプロパティを変更しました。lcov.infoapp.js./app.jsapp/scripts/app.js./app/scripts/app.js

私は何が欠けていますか?

念のため、に次の構成がありますkarma.conf.js

coverageReporter: {
  reporters: [
    {
      type: 'lcov',
      dir: 'build/karma/coverage',
      subdir: '.'
    }
  ]
},

ps: ソナーのバージョンは 3.7.2 ですが、4.3 でも試してみましたが、同じ結果でした...


編集: Sonar-runner を直接使用するように構成を更新しました。最新バージョンの Sonar (5.0.1) と JS プラグイン (2.3) を使用しています。lcov.infoまた、「適切な」形式 (Sonar リポジトリの例と一致する少なくとも 1 つの形式) を持つように手動で変更しました。

SF:./app/scripts/app.js
DA:2,1
DA:20,1
DA:29,1
DA:34,1
end_of_record
SF:./app/scripts/services/exampleService.js
DA:1,1
DA:11,1
DA:12,0
end_of_record

次のsonar-project.propertiesようになります。

sonar.projectKey=xxx
sonar.projectName=xxx
sonar.projectVersion=xxx
sonar.sourceEncoding=UTF-8

sonar.sources=app/scripts
sonar.tests=test
sonar.exclusions=app/3rd-party-libs/**,node_modules/**
sonar.dynamicAnalysis=reuseReports
sonar.language=js
sonar.projectBaseDir=.
sonar.javascript.coveragePlugin=lcov
sonar.javascript.lcov.reportPath=build/karma/coverage/lcov.info

それでも、カバレッジの 0% :(

4

1 に答える 1

6

私は無知だったので、JavaScript プラグインを変更してログを追加することにしました。そして、ついにエラーを見つけました。これは、大文字と小文字の区別の悪質な問題です。

説明させてください。saveMeasureFromLCOVFileのメソッドを考えてみましょうCoverageSensor.java:

  protected void saveMeasureFromLCOVFile(SensorContext context) {
    String providedPath = settings.getString(JavaScriptPlugin.LCOV_REPORT_PATH);
    File lcovFile = getIOFile(fileSystem.baseDir(), providedPath);
    ...
    LOG.info("Analysing {}", lcovFile);

    LCOVParser parser = new LCOVParser(fileSystem.baseDir());
    Map<String, CoverageMeasuresBuilder> coveredFiles = parser.parseFile(lcovFile);

    for (InputFile inputFile : fileSystem.inputFiles(mainFilePredicate)) {
      try {
        CoverageMeasuresBuilder fileCoverage = coveredFiles.get(inputFile.file().getAbsolutePath());
        org.sonar.api.resources.File resource = org.sonar.api.resources.File.create(inputFile.relativePath());

        if (fileCoverage != null) {
          for (Measure measure : fileCoverage.createMeasures()) {
            context.saveMeasure(resource, measure);
          }
        } else {
          // colour all lines as not executed
          LOG.debug("Default value of zero will be saved for file: {}", resource.getPath());
          LOG.debug("Because: either was not present in LCOV report either was not able to retrieve associated SonarQube resource");
          saveZeroValueForResource(resource, context);
        }
      } catch (Exception e) {
        LOG.error("Problem while calculating coverage for " + inputFile.absolutePath(), e);
      }
   }
  }

まず、lcov.info指定されたファイルを読み取り、どのファイルのカバレッジ データがあるかを確認します (ファイルを解析して取得し、LCOVParserクラスで実行します)。その後、coveredFilesマップから同じファイルを取得して、メトリックとコードの照合を行います。ファイルが見つからない場合 (elseの一部if (fileCoverage != null) {)、コード カバレッジは強制的に 0 になります。

それが私のプロジェクトで起こったことです。

では、なぜそれが起こっているのですか?単純に、私の環境でinputFileは が に等しくd:\dev\my-application\app\scripts\app.jscoveredFilesマップでは があるからD:\dev\my-application\app\scripts\app.jsです。ドライブ文字の大文字と小文字の違いに注意してください (d:に対してD:)。map.get(...)は大文字と小文字を区別するため、カバレッジは計算されませんfileCoveragenull

さて、パスに正しい大文字と小文字を強制する方法を調査する必要があります...


さらに調査した結果、機能するプラグイン コードの変更を見つけました (少なくとも私にとっては、考えられるすべての影響については調べていませんでした)。ではLCOVParser、最初のものは のようなパスを返し、2 番目のものは を返すため、filePath = CoverageSensor.getIOFile(moduleBaseDir, filePath).getCanonicalPath();を に変更できます。filePath = CoverageSensor.getIOFile(moduleBaseDir, filePath).getAbsolutePath();D:\...d:\...

実際、私はWindows で使用するのに適したケースでさえありません。次のコード:

public static void main(String[] args) throws IOException {
    System.out.println("PATH 1 : " + new File(".").getAbsolutePath());
    System.out.println("PATH 2 : " + new File(".").getCanonicalPath());
}

戻ります:

PATH 1 : D:\dev\preclosing\preclosing-eme\.
PATH 2 : D:\dev\preclosing\preclosing-eme

とにかく、私は今のところ立ち往生しており、JSプラグインの修正を待たずに問題を解決する方法さえわかりません(私の「公式」ソナーは今のところ少し古く、JSプラグインのみをサポートしているため) v2.1 に)。

于 2015-02-25T15:11:07.893 に答える