LoginSignup
2
1

More than 3 years have passed since last update.

dotnet test で --no-build を指定するとテストカバレッジが出力されない現象の解決方法

Posted at

テストが実行されない現象の解決方法についてはこちら

概要

コマンドラインから普通にdotnet test --no-build /p:CollectCoverage=true /p:CoverletOutput=./TestResults/ /p:CoverletOutputFormat=coberturaしたらテスト実行後にカバレッジファイルが出力されるのに、CIで自動テストをしようとするとなぜか動かない現象の解決方法です。

再現方法

以下のファイルを用意します。

gitlab-ci.yml
image: mcr.microsoft.com/dotnet/core/sdk:latest

stages:
  - build
  - test

build:
  stage: build
  script:
    - "dotnet build"
  artifacts:
    expire_in: 10 min
    paths:
      - "*/bin/"
      - "*/obj/"
  only:
    - branches
  except:
    - master

Web_test:
  stage: test
  script:
    - dotnet test Web.Test --no-build /p:CollectCoverage=true /p:CoverletOutput=./TestResults/ /p:CoverletOutputFormat=cobertura
    # もしくは、  dotnet test Web.Test --no-build --collect:"XPlat Code Coverage"
  dependencies:
    - build
  only:
    - branches
  except:
    - master

Web.Testというテストプロジェクトがあるとします。
これをGitLabのmasterブランチ以外にPushすればbuidとtestが実行されます。

説明

テストが実行されない現象の解決方法でやっとテストが実行される様になりましたが、今度はなぜかテストカバレッジが出力されない・・・
これも、--no-buildを付けなければ動作するのに。

解決方法

.gitlab-ci.ymlを以下の通り修正します。

gitlab-ci.yml
image: mcr.microsoft.com/dotnet/core/sdk:latest

variables:
  NUGET_PACKAGES: ${CI_PROJECT_DIR}/.nuget/packages # ←これを追加!

stages:
  - build
  - test

build:
  stage: build
  script:
    - "dotnet build"
  artifacts:
    expire_in: 10 min
    paths:
      - ".nuget/packages/coverlet.msbuild" # ←これを追加!
      - "*/bin/"
      - "*/obj/"
  only:
    - branches
  except:
    - master

Web_test:
  stage: test
  script:
    - dotnet test Web.Test --no-build /p:CollectCoverage=true /p:CoverletOutput=./TestResults/ /p:CoverletOutputFormat=cobertura
    # もしくは、  dotnet test Web.Test --no-build --collect:"XPlat Code Coverage"
  dependencies:
    - build
  only:
    - branches
  except:
    - master

テストカバレッジの出力には、テストプロジェクトで依存関係に登録しているcoverlet.msbuildを内部で使用しています。
しかし、--no-buildを指定した場合はビルドを行わないだけではなく、ビルドの前に暗黙的に実行されるdotnet restoreもスキップしています。
つまり、NuGetが実行されず依存関係にあるライブラリを取得していない状態となっています。
これが原因で出力に失敗していました。

解決方法としては、dotnet restoreを事前に実行する方法もありますが、依存関係が大きい場合は時間も掛かってしまいます。
そして、buildステージで既に行なっていることを繰り返すのもスマートではないので、
buildステージから必要なパッケージだけをtestステージに送ってもらうことにしました。

ただ、パッケージの保存場所がそのままでは到達困難なのでNUGET_PACKAGES環境変数で無理やりパスを移動して、
それをアーティファクトにしてジョブ間で共有できる様にしています。
(たぶんartifactsではなくcacheを使った方が良いのでしょうがイマイチ動作がわからなくて今回は使ってないです)

実はこれも(ローカル環境で成功している時に出力される)詳細ログにヒントがありました。

"Coverlet.MSbuild.Tasks.CoverageResultTask" タスクをアセンブリ "C:\Users\user\.nuget\packages\coverlet.msbuild\2.9.0\build\coverlet.msbuild.tasks.dll" から使用しています。

ログを見るって大事ですね。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1