Yazılım
.NET Uygulamalarında Code Coverage Metriklerini Hesaplama ve CI Süreçlerine Dahil Etmek
Code Coverage
Code coverage’ı hesaplayabilmek için cross-platform code coverage framework’ü olan coverlet’i kullanacağız. Coverlet, .NET Core ve .NET 5 xUnit Test projeleri için default VSTest entegre data collector olarak gelmektedir.Data collector’ler test execution işlemleri sırasında code coverage metriklerinin toplanması gibi farklı monitoring işlemlerini gerçekleştirmektedirler.Code coverage metriklerini toplayabilmek için tek yapmamız gereken, –collect=”XPlat Code Coverage” parametresi ile dotnet test işlemini çalıştırmak. Örnek amaçlı oluşturduğum test projesi üzerinde (buradan ulaşabileceğiniz) code coverage metriklerini toplayabilmek için yukarıdaki komutu çalıştırdığımda, coverlet aşağıdaki gibi default formatı olan Cobertura formatında metrikleri toplamaktadır.

<?xml version="1.0" encoding="utf-8" ?>
<RunSettings>
<DataCollectionRunSettings>
<DataCollectors>
<DataCollector friendlyName="XPlat Code Coverage">
<Configuration>
<Format>cobertura</Format>
<ExcludeByFile>**/MyTodoApp.API/Startup.cs</ExcludeByFile>
</Configuration>
</DataCollector>
</DataCollectors>
</DataCollectionRunSettings>
</RunSettings>
dotnet test --settings coverlet.runsettings
Örneğin yukarıdaki configuration ile “MyTodoApp.API” klasörü altındaki “Startup.cs” dosyasının code coverage metriği için dikkate alınmamasını ve metrik formatının “cobertura” formatında olmasını sağladık.
Azure Pipeline
Azure üzerinde CI süreçlerimize code coverage ve test sonuçlarını dahil edebilmek için, aşağıdaki gibi basit bir pipeline oluşturalım.# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
trigger:
- master
pool:
vmImage: ubuntu-latest
variables:
testProjectName: 'MyTodoApp.Tests'
steps:
- task: [email protected]
displayName: "Run dotnet restore"
inputs:
command: 'restore'
projects: '**/$(testProjectName).csproj'
- task: [email protected]
displayName: "Run dotnet test"
inputs:
command: 'test'
projects: '**/$(testProjectName).csproj'
publishTestResults: false
arguments: '--settings $(Build.Repository.LocalPath)/$(testProjectName)/coverlet.runsettings --logger trx'
- task: [email protected]
displayName: "Publish test results"
inputs:
testResultsFormat: 'VSTest'
testResultsFiles: '$(System.DefaultWorkingDirectory)/$(testProjectName)/TestResults/**/*.trx'
- task: [email protected]
displayName: "Publish code coverage results"
inputs:
codeCoverageTool: 'Cobertura'
summaryFileLocation: '$(System.DefaultWorkingDirectory)/$(testProjectName)/TestResults/*/coverage.cobertura.xml'
Bu pipeline tanımlamasında,
- task: [email protected]
displayName: "Run dotnet test"
inputs:
command: 'test'
projects: '**/$(testProjectName).csproj'
publishTestResults: false
arguments: '--settings $(Build.Repository.LocalPath)/$(testProjectName)/coverlet.runsettings --logger trx'
ilk olarak NuGet paketlerini “restore” ediyoruz ve sonra “dotnet test” komutunu, projemize göre tanımlamış olduğumuz “coverlet.runsettings” dosyası ile çalıştırıyoruz. Bu noktada ben ilgili sonuçların agent içerisinde bir temp klasörde oluşturulmasını istemediğim için, “publishTestResults” parametresini “false” olarak set ettim. Böylece ilgili sonuçlar, proje path’i altında “TestResults” klasörü içerisinde oluşturuluyor olacak.
- task: [email protected]
displayName: "Publish test results"
inputs:
testResultsFormat: 'VSTest'
testResultsFiles: '$(System.DefaultWorkingDirectory)/$(testProjectName)/TestResults/**/*.trx'
Bir önceki aşamada test sonuçlarını otomatik olarak publish ettirmediğimiz için, bu aşamada proje path’i altında oluşturulan test sonuçlarını “VSTest” formatında Azure Pipeline’a publish ediyoruz. Böylece detaylı test sonuçlarını da pipeline üzerinden görebileceğiz.
- task: [email protected]
displayName: "Publish code coverage results"
inputs:
codeCoverageTool: 'Cobertura'
summaryFileLocation: '$(System.DefaultWorkingDirectory)/$(testProjectName)/TestResults/*/coverage.cobertura.xml'
Son aşama olarak ise cobertura formatında oluşturttuğumuz code coverage sonuçlarını, “PublishCodeCoverageResults” task’ını kullanarak Azure Pipeline’a publish ediyoruz.
Hepsi bu kadar!
Pipeline’ı çalıştırdığımızda, aşağıdaki gibi Summary kısmında projenin test ve coverage bilgilerine hızlı bir şekilde göz atabileceğiz.



- task: [email protected]
displayName: "Code coverage quality check"
inputs:
checkCoverage: true
coverageFailOption: 'fixed'
coverageType: 'lines'
coverageThreshold: '95'
Bu task kısaca hesaplanan “line coverage” ve “threshold” oranlarına bakarak, build’in başarılı veya başarısız olmasını sağlamaktadır.
Örneğin,

Eline sağlık.