ThreeMammals/Ocelot · error · Exception
No coverage.cobertura.*.xml files found in
Error message
No coverage.cobertura.*.xml files found in {artifactsForUnitTestsDir} What it means
After unit tests run with the coverlet collector, the build expects at least one 'coverage.cobertura.*.xml' report in the unit-test artifacts directory. If GetFiles finds none, this error aborts the coverage reporting step. It means coverage data was never generated or was written elsewhere.
Solutions
- Check the logged 'ArtifactsForUnitTestsDir = ...' path and verify coverage.cobertura*.xml exists there manually.
- Ensure the dotnet test invocation includes --collect:"XPlat Code Coverage" and the coverlet.collector package.
- Confirm the test run succeeded before the coverage step (fix the earlier failing task first).
- Align the artifacts directory used by the test task and the coverage glob.
- Verify case-sensitivity of the directory path on Linux CI agents.
Example fix
// before GetFiles(artifactsForUnitTestsDir.ToString() + "/coverage.cobertura.*.xml"); // after GetFiles(artifactsForUnitTestsDir.ToString() + "/**/coverage.cobertura*.xml");
Defensive patterns
Strategy: validation
Validate before calling
var coverageFiles = GetFiles(artifactsForUnitTestsDir + "/coverage.cobertura.*.xml");
if (!coverageFiles.Any()) throw new Exception($"No coverage files in {artifactsForUnitTestsDir} — did the test task run with coverlet?"); Try / catch
try { GenerateReport(coverageSummaryFile); }
catch (Exception ex) { Error($"Coverage reporting failed: {ex.Message}"); throw; } Prevention
- Ensure the test task runs before the coverage task in the same invocation
- Keep coverlet.collector referenced in all test projects
- Align test output directory with artifactsForUnitTestsDir
- Mind case-sensitive paths on Linux CI agents
When it happens
Trigger: Tests did not actually run or produce coverage (test run skipped/failed earlier); coverlet collector not enabled via --collect:"XPlat Code Coverage"; output path differs from artifactsForUnitTestsDir; glob case/path mismatch.
Common situations: Running coverage task without the test task; coverlet.collector package missing from test projects; coverage output redirected to a custom directory; stale artifacts folder cleaned before the check.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
AI-assisted analysis of ThreeMammals/Ocelot@d1f22d9304 (2026-09-12).
Data as JSON: /api/errors/7617212afb9aaf73.
Report an issue: GitHub.
Appendix: source
Thrown at build.cake:595
$"--coverlet-exclude \"[Ocelot.Testing]*\"",
WorkingDirectory = "."
});
// Only fail on actual test failures, not on thread exit issues
if (exitCode != 0 && exitCode != 7)
{
throw new Exception($"dotnet test failed with exit code {exitCode}");
}
else if (exitCode == 7)
{
Warning("Tests passed but background threads didn't exit cleanly (exit code 7). Ignoring.");
}
}
Information("ArtifactsForUnitTestsDir = " + artifactsForUnitTestsDir);
// Find all files matching pattern "coverage.cobertura.*.xml"
var coverageFiles = GetFiles(artifactsForUnitTestsDir.ToString() + "/coverage.cobertura.*.xml");
if (!coverageFiles.Any())
throw new Exception($"No coverage.cobertura.*.xml files found in {artifactsForUnitTestsDir}");
// Get the first matching file (or order by creation date if needed)
var coverageSummaryFile = coverageFiles.First();
Information("CoverageSummaryFile = " + coverageSummaryFile);
GenerateReport(coverageSummaryFile);
Information("##############################");
Information("# Code coverage");
Information("#=============================");
// TODO Implement reporting to the Action Run summary as an attachment or artifact
const string CoverallsRepo = "https://coveralls.io/github/ThreeMammals/Ocelot";
Information($"# There is dedicated Coveralls step of GH Action workflows. So, we won't publish the coverage report to coveralls.io");
// Apply code coverage threshold
const double MinCodeCoverage = 0.93D; // consider definition of an env var in GitHub Environment vars
var lineCoverage = XmlPeek(coverageSummaryFile, "//coverage/@line-rate");
var branchCoverage = XmlPeek(coverageSummaryFile, "//coverage/@branch-rate");
Information("# Line Coverage: " + lineCoverage);
Information("# Branch Coverage: " + branchCoverage);
View on GitHub (pinned to d1f22d9304)