Điều này đã đưa tôi vào thử nghiệm đơn vị và nó làm tôi rất hạnh phúc
Chúng tôi chỉ mới bắt đầu làm thử nghiệm đơn vị. Trong một thời gian dài, tôi biết sẽ tốt khi bắt đầu thực hiện nhưng tôi không biết bắt đầu như thế nào và quan trọng hơn là phải kiểm tra cái gì.
Sau đó, chúng tôi đã phải viết lại một đoạn mã quan trọng trong chương trình kế toán của chúng tôi. Phần này rất phức tạp vì nó liên quan đến rất nhiều tình huống khác nhau. Phần tôi đang nói đến là một phương thức thanh toán hóa đơn bán hàng và / hoặc mua hàng đã được nhập vào hệ thống kế toán.
Tôi chỉ không biết làm thế nào để bắt đầu mã hóa nó, vì có rất nhiều lựa chọn thanh toán khác nhau. Hóa đơn có thể là 100 đô la nhưng khách hàng chỉ chuyển 99 đô la. Có thể bạn đã gửi hóa đơn bán hàng cho một khách hàng nhưng bạn cũng đã mua từ khách hàng đó. Vì vậy, bạn đã bán anh ta với giá 300 đô la nhưng bạn đã mua với giá 100 đô la. Bạn có thể mong đợi khách hàng của bạn trả cho bạn 200 đô la để giải quyết số dư. Và nếu bạn bán được 500 đô la nhưng khách hàng chỉ trả cho bạn 250 đô la thì sao?
Vì vậy, tôi đã có một vấn đề rất phức tạp để giải quyết với nhiều khả năng rằng một kịch bản sẽ hoạt động hoàn hảo nhưng sẽ sai đối với một loại kết hợp thanh toán / thanh toán khác.
Đây là nơi thử nghiệm đơn vị đã đến để giải cứu.
Tôi bắt đầu viết (bên trong mã kiểm tra) một phương pháp để tạo danh sách hóa đơn, cả cho bán hàng và mua hàng. Sau đó, tôi đã viết một phương thức thứ hai để tạo ra khoản thanh toán thực tế. Thông thường người dùng sẽ nhập thông tin đó thông qua giao diện người dùng.
Sau đó, tôi đã tạo TestMethod đầu tiên, thử nghiệm thanh toán rất đơn giản cho một hóa đơn mà không có bất kỳ khoản chiết khấu thanh toán nào. Tất cả các hành động trong hệ thống sẽ xảy ra khi một khoản thanh toán ngân hàng sẽ được lưu vào cơ sở dữ liệu. Như bạn có thể thấy tôi đã tạo hóa đơn, tạo thanh toán (giao dịch ngân hàng) và lưu giao dịch vào đĩa. Trong các xác nhận của mình, tôi đặt số nào phải là số chính xác kết thúc trong giao dịch Ngân hàng và Hóa đơn được liên kết. Tôi kiểm tra số lượng thanh toán, số tiền thanh toán, số tiền chiết khấu và số dư của hóa đơn sau khi giao dịch.
Sau khi chạy thử, tôi sẽ vào cơ sở dữ liệu và kiểm tra lại xem những gì tôi mong đợi có ở đó không.
Sau khi tôi viết bài kiểm tra, tôi bắt đầu mã hóa phương thức thanh toán (một phần của lớp BankHeader). Trong mã hóa tôi chỉ bận tâm với mã để thực hiện bài kiểm tra đầu tiên. Tôi chưa nghĩ về các kịch bản khác, phức tạp hơn.
Tôi đã chạy thử nghiệm đầu tiên, sửa một lỗi nhỏ cho đến khi thử nghiệm của tôi vượt qua.
Sau đó, tôi bắt đầu viết bài kiểm tra thứ hai, lần này làm việc với chiết khấu thanh toán. Sau khi tôi viết bài kiểm tra, tôi đã sửa đổi phương thức thanh toán để hỗ trợ giảm giá.
Trong khi kiểm tra tính chính xác với chiết khấu thanh toán, tôi cũng đã thử nghiệm thanh toán đơn giản. Tất cả các bài kiểm tra nên vượt qua tất nhiên.
Sau đó, tôi làm việc theo cách của tôi xuống các kịch bản phức tạp hơn.
1) Nghĩ về một kịch bản mới
2) Viết một bài kiểm tra cho kịch bản đó
3) Chạy thử nghiệm đơn đó để xem nó có vượt qua không
4) Nếu nó không gỡ lỗi và sửa đổi mã cho đến khi nó vượt qua.
5) Trong khi sửa đổi mã, tôi tiếp tục chạy tất cả các bài kiểm tra
Đây là cách tôi quản lý để tạo phương thức thanh toán rất phức tạp của mình. Không có kiểm thử đơn vị, tôi không biết làm thế nào để bắt đầu viết mã, vấn đề dường như quá lớn. Với thử nghiệm, tôi có thể bắt đầu với một phương pháp đơn giản và từng bước mở rộng nó với sự đảm bảo rằng các kịch bản đơn giản hơn vẫn sẽ hoạt động.
Tôi chắc chắn rằng việc sử dụng thử nghiệm đơn vị đã giúp tôi tiết kiệm được một vài ngày (hoặc vài tuần) mã hóa và ít nhiều đảm bảo tính chính xác của phương pháp của tôi.
Nếu sau này tôi nghĩ ra một kịch bản mới, tôi có thể thêm nó vào các thử nghiệm để xem nó có hoạt động hay không. Nếu không tôi có thể sửa đổi mã nhưng vẫn chắc chắn các kịch bản khác vẫn hoạt động chính xác. Điều này sẽ tiết kiệm ngày và ngày trong giai đoạn bảo trì và sửa lỗi.
Có, ngay cả mã được kiểm tra vẫn có thể có lỗi nếu người dùng thực hiện những việc bạn không nghĩ hoặc ngăn cản anh ta thực hiện
Dưới đây chỉ là một số thử nghiệm tôi đã tạo để kiểm tra phương thức thanh toán của mình.
public class TestPayments
{
InvoiceDiaryHeader invoiceHeader = null;
InvoiceDiaryDetail invoiceDetail = null;
BankCashDiaryHeader bankHeader = null;
BankCashDiaryDetail bankDetail = null;
public InvoiceDiaryHeader CreateSales(string amountIncVat, bool sales, int invoiceNumber, string date)
{
......
......
}
public BankCashDiaryHeader CreateMultiplePayments(IList<InvoiceDiaryHeader> invoices, int headerNumber, decimal amount, decimal discount)
{
......
......
......
}
[TestMethod]
public void TestSingleSalesPaymentNoDiscount()
{
IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
list.Add(CreateSales("119", true, 1, "01-09-2008"));
bankHeader = CreateMultiplePayments(list, 1, 119.00M, 0);
bankHeader.Save();
Assert.AreEqual(1, bankHeader.BankCashDetails.Count);
Assert.AreEqual(1, bankHeader.BankCashDetails[0].Payments.Count);
Assert.AreEqual(119M, bankHeader.BankCashDetails[0].Payments[0].PaymentAmount);
Assert.AreEqual(0M, bankHeader.BankCashDetails[0].Payments[0].PaymentDiscount);
Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[0].InvoiceHeader.Balance);
}
[TestMethod]
public void TestSingleSalesPaymentDiscount()
{
IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
list.Add(CreateSales("119", true, 2, "01-09-2008"));
bankHeader = CreateMultiplePayments(list, 2, 118.00M, 1M);
bankHeader.Save();
Assert.AreEqual(1, bankHeader.BankCashDetails.Count);
Assert.AreEqual(1, bankHeader.BankCashDetails[0].Payments.Count);
Assert.AreEqual(118M, bankHeader.BankCashDetails[0].Payments[0].PaymentAmount);
Assert.AreEqual(1M, bankHeader.BankCashDetails[0].Payments[0].PaymentDiscount);
Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[0].InvoiceHeader.Balance);
}
[TestMethod]
[ExpectedException(typeof(ApplicationException))]
public void TestDuplicateInvoiceNumber()
{
IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
list.Add(CreateSales("100", true, 2, "01-09-2008"));
list.Add(CreateSales("200", true, 2, "01-09-2008"));
bankHeader = CreateMultiplePayments(list, 3, 300, 0);
bankHeader.Save();
Assert.Fail("expected an ApplicationException");
}
[TestMethod]
public void TestMultipleSalesPaymentWithPaymentDiscount()
{
IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
list.Add(CreateSales("119", true, 11, "01-09-2008"));
list.Add(CreateSales("400", true, 12, "02-09-2008"));
list.Add(CreateSales("600", true, 13, "03-09-2008"));
list.Add(CreateSales("25,40", true, 14, "04-09-2008"));
bankHeader = CreateMultiplePayments(list, 5, 1144.00M, 0.40M);
bankHeader.Save();
Assert.AreEqual(1, bankHeader.BankCashDetails.Count);
Assert.AreEqual(4, bankHeader.BankCashDetails[0].Payments.Count);
Assert.AreEqual(118.60M, bankHeader.BankCashDetails[0].Payments[0].PaymentAmount);
Assert.AreEqual(400, bankHeader.BankCashDetails[0].Payments[1].PaymentAmount);
Assert.AreEqual(600, bankHeader.BankCashDetails[0].Payments[2].PaymentAmount);
Assert.AreEqual(25.40M, bankHeader.BankCashDetails[0].Payments[3].PaymentAmount);
Assert.AreEqual(0.40M, bankHeader.BankCashDetails[0].Payments[0].PaymentDiscount);
Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[1].PaymentDiscount);
Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[2].PaymentDiscount);
Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[3].PaymentDiscount);
Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[0].InvoiceHeader.Balance);
Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[1].InvoiceHeader.Balance);
Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[2].InvoiceHeader.Balance);
Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[3].InvoiceHeader.Balance);
}
[TestMethod]
public void TestSettlement()
{
IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
list.Add(CreateSales("300", true, 43, "01-09-2008")); //Sales
list.Add(CreateSales("100", false, 6453, "02-09-2008")); //Purchase
bankHeader = CreateMultiplePayments(list, 22, 200, 0);
bankHeader.Save();
Assert.AreEqual(1, bankHeader.BankCashDetails.Count);
Assert.AreEqual(2, bankHeader.BankCashDetails[0].Payments.Count);
Assert.AreEqual(300, bankHeader.BankCashDetails[0].Payments[0].PaymentAmount);
Assert.AreEqual(-100, bankHeader.BankCashDetails[0].Payments[1].PaymentAmount);
Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[0].InvoiceHeader.Balance);
Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[1].InvoiceHeader.Balance);
}