GitLab CI流水线中dotnet-reportgenerator无法找到coverage.cobertura.xml,如何避免重复构建解决该问题?
Let's break down your issue and fix it without repeating the build step.
The Problem
You're trying to reuse the build artifacts from your build stage in the unit-tests stage with --no-build, but the coverage.cobertura.xml files aren't being found by reportgenerator. When you remove --no-build, it works but runs an unnecessary second build.
Why This Happens
When you use --output build with dotnet test --no-build, the test results (including coverage files) get generated in the build directory structure instead of the test project's default TestResults folder. Your original reportgenerator command was searching for **/coverage.cobertura.xml across the entire repo, but the files were actually tucked away in the build directory (or not being generated correctly because of misaligned output paths with the pre-built artifacts).
Fixes to Avoid Redundant Builds
Here are a couple of reliable solutions to get this working while reusing your build artifacts:
Solution 1: Explicitly Set the Test Results Directory
Specify where test results (and coverage files) should be saved, then point reportgenerator to that exact location:
unit-tests: stage: unit-tests script: - |- # Generate coverage files in a predictable subdirectory of build dotnet test --no-build --output build --results-directory build/TestResults --collect:"XPlat Code Coverage" # Install reportgenerator tool dotnet tool install -g dotnet-reportgenerator-globaltool # Target the specific path where coverage files were saved reportgenerator -reports:'build/TestResults/**/coverage.cobertura.xml' -targetdir:'CoverageReports' -reporttypes:'Cobertura' artifacts: reports: cobertura: CoverageReports/Cobertura.xml dependencies: - build
Solution 2: Use Coverlet Directly for More Control
Instead of relying on the XPlat Code Coverage collector, use Coverlet's MSBuild properties to generate coverage files directly to a fixed path. This avoids the random GUID-named folders and makes file lookup straightforward:
unit-tests: stage: unit-tests script: - |- # Generate coverage files directly to a Coverage folder dotnet test --no-build --output build -p:CollectCoverage=true -p:CoverletOutput=./Coverage/ -p:CoverletOutputFormat=cobertura # Install reportgenerator tool dotnet tool install -g dotnet-reportgenerator-globaltool # Pick up the coverage files from the fixed path reportgenerator -reports:'Coverage/**/*.cobertura.xml' -targetdir:'CoverageReports' -reporttypes:'Cobertura' artifacts: reports: cobertura: CoverageReports/Cobertura.xml dependencies: - build
How These Work
- Solution 1 uses
--results-directoryto force all test output (including coverage files) into a predictable location under your pre-builtbuilddirectory. This letsreportgeneratoreasily find the files without searching the entire repo. - Solution 2 leverages Coverlet's native MSBuild parameters to generate coverage files directly to a specified folder, skipping the default random subfolders entirely. This is often more reliable for CI/CD pipelines where consistent paths are key.
Both approaches let you keep the --no-build flag, so you're reusing the build artifacts from the build stage and eliminating the redundant build step.
内容的提问来源于stack exchange,提问作者user13755987

