テストが実行されない現象の解決方法についてはこちら
概要
コマンドラインから普通にdotnet test --no-build /p:CollectCoverage=true /p:CoverletOutput=./TestResults/ /p:CoverletOutputFormat=cobertura
したらテスト実行後にカバレッジファイルが出力されるのに、CIで自動テストをしようとするとなぜか動かない現象の解決方法です。
再現方法
以下のファイルを用意します。
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
を以下の通り修正します。
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" から使用しています。
ログを見るって大事ですね。