ساخت گزارش Code coverage مربوط به تست‌ها
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: سه دقیقه

اگر برای پروژه‌های خود تست نویسی انجام می‌دهید، یکی از موارد مهم، Code coverage مربوط به تست‌ها می‌باشد که نشان می‌دهد چند درصد از کدهای شما تست شده، کدام قسمت از کد، تست نشده‌است و ... .
در این مطلب نحوه‌ی استفاده از ReportGenerator را برای ایجاد گزارش مربوط به Code coverage، ارائه می‌دهیم. ReportGenerator دیتاهای تولید شده‌ی توسط coverlet, OpenCover, dotCover, Visual Studio, NCover, Cobertura, JaCoCo, Clover و ... را به یک گزارش قابل درک در فرمت‌های Html, Coberura و CSV تبدیل می‌کند. در  این مطلب چند موردتست نویسی با xUnit در Asp.Net Core  را نوشته‌ام و اکنون می‌خواهیم برای تست‌های نوشته شده، Code coverage آنها را بدست آوریم.
در کد زیر، سه تست برای متد AverageUsersAge نوشته شده است:
[Fact]
public async Task AverageUsersAge_When_Repository_Return_Null_Then_Zero_Should_Be_Returned()
{
    _userRepository.Setup(a => a.GetAllUsers())
        .ReturnsAsync((List<User>)null);
    var result = await _userService.AverageUsersAge();
    result.Should().Be(0);
}
[Fact]
public async Task AverageUsersAge_When_Repository_Return_Empty_Then_Zero_Should_Be_Returned()
{
    _userRepository.Setup(a => a.GetAllUsers())
        .ReturnsAsync(new List<User>());
    var result = await _userService.AverageUsersAge();
    result.Should().Be(0);
}
[Fact]
public async Task AverageUsersAge_When_Repository_Return_List_Of_Users_Then_Average_Of_Age_Should_Be_Retunred()
{

    _userRepository.Setup(a => a.GetAllUsers())
        .ReturnsAsync(UserMockData.People);
    var result = await _userService.AverageUsersAge();
    var expected = (UserMockData.AdultUser.Age + UserMockData.ChildUser.Age + UserMockData.InfantUser.Age) / 3;
    result.Should().Be(expected);
}
اکنون اگر بخواهیم Code coverage مربوط به این تست‌ها را مشاهده کنیم، ابتدا باید پکیج coverlet.collector  را در پروژه‌ی تست نصب کنیم. سپس باید دستور زیر را برای نصب ReportGenerator اجرا کنید؛ درون powershell:
dotnet tool install -g dotnet-reportgenerator-globaltool
اکنون میتوانیم Code coverage تست‌ها را تولید کنیم و با استفاده از ReportGenerator، آن‌را به قالب HTML تبدیل کنیم. اگر به مسیر پروژه تست خود بروید و دستور زیر را وارد کنید:
dotnet test --collect:"XPlat Code Coverage"
در پروژه‌ی تست شما، یک پوشه به نام TestResults ایجاد می‌شود و همچنین یک فایل xml با عنوان coverage.cobertura ایجاد شده‌است که نتیجه‌ی Code coverage مربوط به تست‌های شما در آن قرار دارد. 
اکنون می‌توانید با استفاده از ReportGenerator گزارش تست‌های خود را از فایل ایجاد شده، تهیه کنید. برای این کار باید دستور زیر را در مسیر پروژه تست، در powershell  وارد کنید:
reportgenerator -reports:"C:\Users\Farhad\source\repos\xUnitExample\xUnitExample.Tests\TestResults\*\coverage.cobertura.xml" -targetdir:"coveragereport" -reporttypes:Html
در پارامتر reports باید مسیر فایل xml ایجاد شده مربوط به Code coverage را قرار دهید (با هر بار اجرای دستور "dotnet test --collect:"XPlat Code Coverage یک فایل xml جدید ایجاد می‌شود و ممکن است در سیستم شما مقدار GUID ایجاد شده، تفاوت داشته باشد). 
درون پوشه TestResults یک پوشه دیگر قرار دارد که نام آن پوشه، یک GUID می‎‌باشد و به همین دلیل به جای استفاده از GUID از * استفاده کرده‌ایم.
 اگر دستور بالا را اجرا کنید باید خروجی زیر را مشاهده کنید:
2021-11-18T14:05:02: Arguments
2021-11-18T14:05:02:  -reports:C:\Users\Farhad\source\repos\xUnitExample\xUnitExample.Tests\TestResults\*\coverage.cobertura.xml
2021-11-18T14:05:02:  -targetdir:coveragereport
2021-11-18T14:05:02:  -reporttypes:Html
2021-11-18T14:05:02: Writing report file 'coveragereport\index.html'
2021-11-18T14:05:02: Report generation took 0.3 seconds
اکنون اگر در مسیری که دستور بالا را اجرا کردید بروید، یک پوشه به نام coveragereport مشاهده می‌کنید که یک فایل index.html دارد و اگر آنرا در مرورگر مشاهده کنید، Code coverage مربوط به تست‌های نوشته شده را مشاهده میکنید:


در عکس ارسال شده، تست‌های نوشته شده برای تمامی لایه‌ها به صورت جدا ایجاد شده‌است.
تست مربوط به UserService:

در عکس بالا قسمت‌هایی که تست شده‌اند، با رنگ سبز مشخص می‌شود و اگر قسمتی از کد تست نشده باشد، با رنگ قرمز مشخص می‌شود. 

برای مثال در عکس زیر مشخص شده‌است که برای فایل ApplicationConfiguration هیچ تستی نوشته نشده‌است.


اگر از CICD استفاده میکنید، می‌توانید در قسمت CI پروژه، هربار دستورات بالا را اجرا کنید و Code coverage مربوط به هر Build را به صورت جداگانه در کنار فایل‌های آپلود شده داشته باشد.
نکته: برای اجرای دستورات بالا و ساخت گزارش باید ورژن SDK نصب شده بر روی سیستم شما برابر 2.2.401 یا بیشتر باشد و ورژن Microsoft.NET.Test.Sdk برابر 16.5.0 یا بیشتر باشد.