Kiểm thử đơn vị trong C# với Nunit và .Net Core

Bài viết được sự cho phép của BBT Tạp chí Lập trình

Bài viết sẽ hướng dẫn từng bước xây dựng giải pháp kiểm thử đơn vị. Bài viết này đề cập tới việc kiểm thử một dự án .NET Core.

  So sánh tốc độ List collection và HashSet collection trong C#
  Namespace trong C#

Tạo dự án

Tạo một thư mục có tên là “unit-tests-using-nunit” để lưu trữ solution. Trong thư mục này, hãy chạy lệnh sau để tạo solution mới cho class library và test project:

>> dotnet new sln

Tiếp theo, tạo thư mục PrimeService. Các phác thảo sau đây cho thấy cấu trúc thư mục và tập tin:

Đi đến thư mục PrimeService và chạy lệnh sau để tạo dự án nguồn:

>> dotnet new classlib

Đổi tên Class1.cs thành PrimeService.cs. Tạo ra một triển khai fail của lớp PrimeService:

using System;
namespace Prime.Services
{
    public class PrimeService
    {
        public bool IsPrime(int candidate)
        {
            throw new NotImplementedException("Please create a test first.");
        }
    }
}

Đi đến thư mục “unit-tests-using-nunit”. Chạy lệnh sau để thêm dự án class library vào solution:

>> dotnet sln add PrimeService/PrimeService.csproj

Tạo dự án test

Tiếp theo, tạo thư mục “PrimeService.Tests”. Các phác thảo sau đây cho thấy cấu trúc thư mục:

Đi đến thư mục “PrimeService.Tests” và tạo dự án mới bằng lệnh sau:

>> dotnet new nunit

Lệnh “dotnet new” tạo ra một dự án test sử dụng NUnit làm thư viện test. Xem file cấu hình PrimeService:

using System;
namespace Prime.Services
{
    public class PrimeService
    {
        public bool IsPrime(int candidate)
        {
            throw new NotImplementedException("Please create a test first.");
        }
    }
}

Dự án test yêu cầu các gói khác để tạo và chạy kiểm thử đơn vị. Lệnh “dotnet new” trong bước trước đã thêm SDK test của Microsoft, NUnit test framework và bộ điều hợp thử nghiệm NUnit. Bây giờ, thêm class library PrimeService như một phụ thuộc khác vào dự án. Sử dụng lệnh “dotnet add reference”:

>> dotnet add reference ../PrimeService/PrimeService.csproj

Các phác thảo sau đây cho thấy cấu trúc của solution:

Thực hiện lệnh sau trong thư mục “unit-tests-using-nunit”:

>> dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj

Tạo test

Bạn viết một test fail, làm cho nó pass, sau đó lặp lại quá trình. Trong thư mục “PrimeService.Tests”, đổi tên tệp UnitTest1.cs thành PrimeService_IsPrimeShould.cs và thay thế toàn bộ nội dung của nó bằng mã sau:

using NUnit.Framework;
using Prime.Services;

namespace Prime.UnitTests.Services
{
    [TestFixture]
    public class PrimeService_IsPrimeShould
    {
        private PrimeService _primeService;

        [SetUp]
        public void SetUp()
        {
            _primeService = new PrimeService();
        }

        [Test]
        public void IsPrime_InputIs1_ReturnFalse()
        {
            var result = _primeService.IsPrime(1);

            Assert.IsFalse(result, "1 should not be prime");
        }
    }        
}

Thuộc tính [TestFixture] biểu thị một lớp có chứa các phương thức kiểm thử đơn vị. Thuộc tính [Test] chỉ ra một phương thức là một phương thức kiểm thử.

Lưu tệp này và thực hiện lệnh “dotnet test” để build các kiểm thử và class library và sau đó chạy các kiểm thử. NUnit chứa Entry Point (điểm bắt đầu của chương trình)  để chạy các kiểm thử. “dotnet test” bắt đầu trình chạy thử bằng cách sử dụng dự án kiểm thử đơn vị đã tạo.

Kiểm thử sẽ thất bại. Thực hiện kiểm thử này bằng cách viết mã đơn giản nhất trong lớp PrimeService:

public bool IsPrime(int candidate)
{
    if (candidate == 1)
    {
        return false;
    }
    throw new NotImplementedException("Please create a test first.");
}

Trong thư mục “unit-testing-using-nunit”, chạy lại lệnh “dotnet test”. Lệnh “dotnet test” build dự án PrimeService và sau đó là dự án PrimeService.Tests. Sau khi build cả hai dự án, nó chạy test này, kết quả là pass.

Thêm tính năng

Có một vài trường hợp đơn giản khác cho các số nguyên tố: 0, -1. Có thể thêm các test mới với thuộc tính [Test]. Tuy nhiên, có các thuộc tính NUnit khác cho phép viết một bộ các test tương tự.

Thuộc tính [TestCase] ​​được sử dụng để tạo một bộ các test thực thi cùng một mã nhưng có các đối số đầu vào khác nhau. Bạn có thể sử dụng thuộc tính [TestCase] ​​để chỉ định các giá trị cho các đầu vào đó.

Thay vì tạo các test mới, hãy áp dụng thuộc tính này để tạo một test theo hướng dữ liệu. Test hướng dữ liệu là phương pháp test một vài giá trị nhỏ hơn hai, là số nguyên tố thấp nhất:



public bool IsPrime(int candidate)
{
    if (candidate == 1)
    {
        return false;
    }
    throw new NotImplementedException("Please create a test first.");
}

Chạy lệnh “dotnet test” và hai trong số các test này thất bại. Để thực hiện tất cả các test, hãy thay đổi mệnh đề if ở đầu phương thức Main trong file PrimeService.cs:

public bool IsPrime(int candidate)
{
    if (candidate == 1)
    {
        return false;
    }
    throw new NotImplementedException("Please create a test first.");
}

Bài viết đã hoàn thành xây dựng một thư viện nhỏ và một bộ các kiểm thử đơn vị cho thư viện đó.

Author: Nguyễn Khánh Tùng

Bài viết gốc được đăng tải tại Tạp chí Lập trình

Có thể bạn quan tâm:

Xem thêm các việc làm Developer hấp dẫn tại TopDev