VieTopik
Tiếng HànTiếng AnhIT
  • Góc học tập
Tải app
  • Thư viện
  • Luyện thi
  • Cẩm nang
  • Góc học tập
Kiến trúc và chất lượng codeTest
Bài 7/17
5 phút

Test đáng tin

Nội dung bài · 5 mục
  1. 1.Khái niệm
  2. 2.Ví dụ
  3. 3.Thử ngay
  4. 4.Lỗi hay gặp
  5. 5.Tóm tắt

Một test hôm qua còn qua, hôm nay lại đỏ, dù không ai sửa code. Chạy lại thì qua. Test như vậy làm cả nhóm mất lòng tin: thấy đỏ mà không biết là code lỗi thật hay do chính test. Bài này chỉ ra các nguyên nhân hay gặp và cách tránh.

Khái niệm

🕰️ Test ổn định (deterministic test): test cho cùng một kết quả mỗi lần chạy, bất kể chạy ngày nào, trên máy nào, trước hay sau test khác.

Ba nguồn làm test mất ổn định hay gặp nhất: phụ thuộc giờ hệ thống như DateTime.Now, phụ thuộc thứ tự chạy của các test, và phụ thuộc database hay mạng (bài trước đã thay bằng fake).

Ví dụ

Giảm 10% vào thứ bảy, chủ nhật. Method nhận ngày qua tham số thay vì tự đọc giờ hệ thống:

using Xunit;

public class Promo
{
    public decimal DiscountPercent(DateTime day)
    {
        if (day.DayOfWeek == DayOfWeek.Saturday
            || day.DayOfWeek == DayOfWeek.Sunday)
        {
            return 10;
        }
        return 0;
    }
}

public class PromoTests
{
    [Theory]
    [InlineData(2026, 9, 26, 10)]   // thứ bảy
    [InlineData(2026, 9, 28, 0)]    // thứ hai
    public void DiscountPercent_ByDay(
        int year, int month, int day, int expected)
    {
        var promo = new Promo();

        decimal percent = promo.DiscountPercent(
            new DateTime(year, month, day));

        Assert.Equal(expected, percent);
    }
}
  • day.DayOfWeek cho biết ngày đó là thứ mấy.
  • Test tự chọn ngày cố định, nên chạy hôm nào cũng cho cùng kết quả.
  • DateTime không viết được trong [InlineData], nên truyền năm, tháng, ngày rồi tạo DateTime trong test.
  • Tên test theo mẫu Method_TìnhHuống hoặc Method_TìnhHuống_KếtQuả, như Total_Under500k_NoDiscount ở bài Viết test cho API. Đọc tên là biết test kiểm gì.
  • Mỗi test chỉ kiểm một hành vi. Đỏ thì biết ngay hành vi nào hỏng.

Thử ngay

xUnit không chạy test theo thứ tự viết trong file. Thêm class này rồi chạy dotnet test:

using Xunit;

public class CounterTests
{
    private int _count = 0;

    [Fact]
    public void First()
    {
        _count++;
        Assert.Equal(1, _count);
    }

    [Fact]
    public void Second()
    {
        _count++;
        Assert.Equal(1, _count);
    }
}

Đoán trước khi chạy: hai test cùng tăng _count. Test chạy sau sẽ thấy _count bằng 2 và đỏ, hay cả hai đều qua?

Xem kết quả
Passed!  - Failed: 0, ...

Cả hai qua. xUnit tạo một object CounterTests mới cho mỗi test, nên mỗi test có _count riêng, bắt đầu từ 0. Nhờ vậy các test không ảnh hưởng nhau qua field.

Đổi _count thành static thì hai test dùng chung một biến, và test chạy sau sẽ đỏ.

Lỗi hay gặp

Đọc DateTime.Now bên trong method cần test. Test chỉ qua vào cuối tuần, ngày thường thì đỏ, dù code không đổi.

// SAI — kết quả phụ thuộc hôm nay là thứ mấy
public class Promo
{
    public decimal DiscountPercent()
    {
        DayOfWeek today = DateTime.Now.DayOfWeek;
        if (today == DayOfWeek.Saturday
            || today == DayOfWeek.Sunday)
        {
            return 10;
        }
        return 0;
    }
}
// ĐÚNG — nhận ngày qua tham số
public class Promo
{
    public decimal DiscountPercent(DateTime day)
    {
        if (day.DayOfWeek == DayOfWeek.Saturday
            || day.DayOfWeek == DayOfWeek.Sunday)
        {
            return 10;
        }
        return 0;
    }
}

Tóm tắt

  • Test đáng tin cho cùng kết quả mỗi lần chạy.
  • Không đọc DateTime.Now trong code cần test, truyền ngày vào qua tham số.
  • xUnit tạo object test mới cho mỗi test. Tránh field static dùng chung giữa các test.
  • Tên test nói rõ tình huống, mỗi test kiểm một hành vi.

Tự kiểm tra

0/3 câu
Câu 1

Test tính phí giao hàng đêm khuya qua lúc 23 giờ nhưng đỏ lúc 9 giờ sáng. Nguyên nhân nhiều khả năng nhất?

Câu 2

Hai test trong cùng class cùng thêm phần tử vào một field List (không static). Test thứ hai có thấy phần tử của test thứ nhất không?

Câu 3

Một test kiểm cùng lúc giá, tồn kho, email và log, rồi đỏ. Vấn đề là gì?

Fake thay phụ thuộcĐặt tên và method ngắn

Nội dung bài

  1. 1.Khái niệm
  2. 2.Ví dụ
  3. 3.Thử ngay
  4. 4.Lỗi hay gặp
  5. 5.Tóm tắt