کشف نیازمندیها و سناریوهای مبهم با اولویتدادن به نوشتن تست در GitHub Copilot
نویسنده: وحید نصیری
تاریخ: ۱۴۰۵/۰۵/۲۹ ۱۲:۱۱
آدرس: www.dntips.ir
public decimal CalculateDiscount(Customer customer, decimal orderTotal)
{
if (customer.IsPremium && orderTotal >= 1000)
return orderTotal * 0.20m;
if (customer.IsPremium)
return orderTotal * 0.10m;
return 0;
}پیش از نوشتن تستها، رفتارهای پیشبینیشده و حالتهای مبهم این متد را تحلیل کن. سپس یک مجموعه تست xUnit با کتابخانه FluentAssertions تولید کن.
تمرکز روی مقادیر مرزی و اعتبارسنجی:
orderTotal = 0)orderTotal = 999.99m و orderTotal = 1000m)orderTotal < 0)customer == null)customer == null: اگر مشتری پاس داده نشود، متد با خطای NullReferenceException متوقف میشود.using FluentAssertions;
using Xunit;
public class DiscountCalculatorTests
{
private readonly DiscountCalculator _sut = new();
[Theory]
[InlineData(1000, 200)] // روی مرز تخفیف ۲۰ درصدی
[InlineData(1500, 300)] // بالاتر از مرز
public void CalculateDiscount_PremiumCustomerWithHighTotal_ReturnsTwentyPercent(
decimal orderTotal, decimal expectedDiscount)
{
var customer = new Customer { IsPremium = true };
var result = _sut.CalculateDiscount(customer, orderTotal);
result.Should().Be(expectedDiscount);
}
[Theory]
[InlineData(999.99, 99.999)] // درست زیر مرز تخفیف حداکثری
[InlineData(100, 10)]
public void CalculateDiscount_PremiumCustomerWithStandardTotal_ReturnsTenPercent(
decimal orderTotal, decimal expectedDiscount)
{
var customer = new Customer { IsPremium = true };
var result = _sut.CalculateDiscount(customer, orderTotal);
result.Should().Be(expectedDiscount);
}
[Fact]
public void CalculateDiscount_NonPremiumCustomer_ReturnsZero()
{
var customer = new Customer { IsPremium = false };
var result = _sut.CalculateDiscount(customer, 1000m);
result.Should().Be(0);
}
[Fact]
public void CalculateDiscount_NullCustomer_ThrowsArgumentNullException()
{
var act = () => _sut.CalculateDiscount(null!, 1000m);
act.Should().Throw<ArgumentNullException>();
}
[Fact]
public void CalculateDiscount_NegativeOrderTotal_ThrowsArgumentOutOfRangeException()
{
var customer = new Customer { IsPremium = true };
var act = () => _sut.CalculateDiscount(customer, -50m);
act.Should().Throw<ArgumentOutOfRangeException>();
}
}public decimal CalculateDiscount(Customer customer, decimal orderTotal)
{
ArgumentNullException.ThrowIfNull(customer);
ArgumentOutOfRangeException.ThrowIfNegative(orderTotal);
return customer.IsPremium switch
{
true when orderTotal >= 1000m => orderTotal * 0.20m,
true => orderTotal * 0.10m,
false => 0m
};
}/tests در Copilot Chat: با انتخاب متد و ارسال دستور /tests، مدل به صورت خودکار شروع به تولید ساختار اولیه تست میکند؛ اضافه کردن قیود مدنظر بلافاصله بعد از این دستور، تستها را به سمت موارد مرزی هدایت خواهد کرد.Bogus یا متدهای سازنده کمکی (Factory Methods) شبیهسازی کند تا تستها از شلوغی کدهای اولیهسازی پاک بمانند.OperationCanceledException هنگام لغو CancellationToken را تست کند.