自托管Azure DevOps流水线SonarCloud未拾取代码覆盖率文件问题
.NET Core 3.1应用Azure DevOps自托管流水线SonarCloud无法拾取代码覆盖率文件排查
我为.NET Core 3.1.0应用配置了Azure DevOps自托管流水线,但SonarCloud未能拾取到代码覆盖率文件。扫描日志显示从trx文件中未找到代码覆盖率附件,以下是相关日志、流水线配置及测试项目文件,求问可能遗漏了哪些配置?自托管代理是否需要额外设置?
扫描日志
C:\agent\_work\_tasks\SonarCloudPrepare_14d9cde6-c1da-4d55-aa01-2965cd301255\2.2.0\classic-sonar-scanner-msbuild\SonarScanner.MSBuild.exe end SonarScanner for MSBuild 6.2 Using the .NET Framework version of the Scanner for MSBuild Post-processing started. 11:17:30.481 11:17:30.481 WARNING: File 'C:\agent\_work\1\s\Services\Internal\WebJob\WebJob_TemporaryKey.pfx' does not exist. 11:17:30.496 11:17:30.496 WARNING: File 'C:\agent\_work\1\s\Services\External\Api\Properties\PublishProfiles\vodacom-api-fs-sme-dev - Web Deploy.pubxml' does not exist. 11:17:30.496 11:17:30.496 WARNING: File 'C:\agent\_work\1\s\Tests\Functional\Helpers.Tests\libman.json' does not exist. 11:17:30.715 11:17:30.715 WARNING: File 'C:\agent\_work\1\s\Services\Internal\Credit.Internal.Api\Properties\PublishProfiles\api-credit-uat - FTP.pubxml' does not exist. 11:17:30.715 11:17:30.715 WARNING: File 'C:\agent\_work\1\s\Services\Internal\Credit.Internal.Api\Properties\PublishProfiles\api-credit-uat - ReadOnly - FTP.pubxml' does not exist. Calling the TFS Processor executable... Fetching code coverage report information from TFS... Attempting to locate a test results (.trx) file... Looking for TRX files in: C:\agent\_work\1\TestResults The following test results files were found: C:\agent\_work\1\TestResults\agentdevopsvm1$_agentdevopsvm1_2024-07-22_11_15_24.trx **No code coverage attachments were found from the trx files.** Not using the fallback mechanism to detect binary coverage files. Coverage report conversion completed successfully.
流水线YAML配置
trigger: - feature/EE-14 pool: name: DevOpsAgent variables: - name: BuildConfiguration value: Dev - name: BuildPlatform value: any cpu jobs: - job: Job_1 displayName: Code Quality Job steps: - checkout: self clean: true fetchTags: false - task: VisualStudioTestPlatformInstaller@1 inputs: packageFeedSelector: 'nugetOrg' versionSelector: 'latestStable' - task: NuGetToolInstaller@1 displayName: NuGet install inputs: versionSpec: 6.6.1 - task: NuGetCommand@2 displayName: NuGet Restore inputs: command: restore includeSymbols: false includeNuGetOrg: true restoreSolution: '**/*.sln' - task: UseDotNet@2 inputs: packageType: 'runtime' version: '3.1.0' installationPath: C:\Program Files\dotnet\ - task: SonarCloudPrepare@2 displayName: Prepare Sonar Cloud Analysis inputs: SonarCloud: '********' organization: '*******' scannerMode: 'MSBuild' projectKey: '*******' projectName: '*****' - task: VSBuild@1 displayName: Build Solution retryCountOnTaskFailure: 1 inputs: vsVersion: latest platform: $(BuildPlatform) configuration: $(BuildConfiguration) clean: true - task: VSTest@2 displayName: Run Tests inputs: testAssemblyVer2: | Tests\Functional\*.*[Tt]ests\**\$(BuildConfiguration)\*[Tt]ests*.dll Tests\Functional\*.*[Tt]ests\**\$(BuildConfiguration)\net6.0\*[Tt]ests*.dll Tests\Functional\*.*[Tt]ests\**\$(BuildConfiguration)\netcoreapp3.1\*[Tt]ests*.dll !**\*dMVC.Tests.Common* !**\*Microsoft.VisualStudio.TestPlatform* !**\obj\** platform: '$(BuildPlatform)' configuration: '$(BuildConfiguration)' runInParallel: true pathtoCustomTestAdapters: $(System.DefaultWorkingDirectory)\packages resultsFolder: 'C:\agent\_work\1\TestResults' codeCoverageEnabled: true # customCoverletOptions: '--format cobertura' # Example for .NET Core with Coverlet diagnosticsEnabled: true - task: SonarCloudAnalyze@2 displayName: Run Code Analysis inputs: jdkversion: 'JAVA_HOME_17_X64' - task: SonarCloudPublish@2 inputs: pollingTimeoutSec: '300'
测试项目文件
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netcoreapp3.1</TargetFramework> <IsPackable>false</IsPackable> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" /> <PackageReference Include="NUnit" Version="3.14.0" /> <PackageReference Include="NUnit3TestAdapter" Version="4.5.0" /> <PackageReference Include="NUnit.Analyzers" Version="3.9.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> <PackageReference Include="coverlet.collector" Version="3.1.2" /> <PackageReference Include="IdentityModel" Version="6.0.0" /> <PackageReference Include="Refit.HttpClientFactory" Version="6.3.2" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\..\..\Services\Shared\Credit.Internal.Api.Client\Credit.Internal.Api.Client.csproj" /> </ItemGroup> <ItemGroup> <None Update="Resources\blank.pdf"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> </ItemGroup> </Project>
可能的问题及排查方向
1. 覆盖率生成方式与SonarCloud读取逻辑不匹配
你同时启用了VSTest自带的codeCoverageEnabled: true和项目中的coverlet.collector,两者会冲突:SonarCloud默认从trx附件读取VS格式的覆盖率,但coverlet生成的是独立的coverage.cobertura.xml文件,不会附加到trx里。
解决:
- 注释掉
codeCoverageEnabled: true,取消注释customCoverletOptions: '--format cobertura' - 在
SonarCloudPrepare任务的inputs中添加覆盖率报告路径配置:extraProperties: | sonar.cs.cobertura.reportPaths=$(System.DefaultWorkingDirectory)/**/coverage.cobertura.xml
2. 自托管代理缺少必要组件
- 若要使用VS自带的覆盖率工具,代理机器必须安装Visual Studio Test Agent或完整Visual Studio(包含测试工具和代码覆盖率组件)
- 若使用coverlet,确保代理上的.NET Core 3.1 runtime环境正常,且coverlet.collector能正常执行
3. 测试任务配置缺失
在VSTest@2任务中添加参数,强制触发coverlet收集覆盖率:
arguments: '--collect:"XPlat Code Coverage"'
4. 路径验证
检查测试任务的resultsFolder目录,确认是否生成了coverage.cobertura.xml文件;若文件存在,确保SonarCloud的报告路径配置能匹配到该文件。
内容的提问来源于stack exchange,提问作者Nicholas Namacha
相关产品推荐
相关产品推荐

