này đã cho tôi vào kiểm tra đơn vị và nó khiến tôi rất hạnh phúc
Chúng tôi chỉ mới bắt đầu để làm kiểm tra đơn vị. Trong một thời gian dài tôi biết nó sẽ là tốt để bắt đầu làm điều đó nhưng tôi không có ý tưởng làm thế nào để bắt đầu và quan trọng hơn những gì để kiểm tra.
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 kịch bản khác nhau. Phần tôi đang nói đến là 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 bắt đầu viết mã như thế nào, vì có quá nhiều tùy 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 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 để thanh toán số dư. Và nếu bạn bán với giá 500 đô la nhưng khách hàng chỉ trả cho bạn 250 đô la?
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 trên một loại kết hợp invocie/thanh toán khác.
Đây là nơi thử nghiệm đơn vị được 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 pháp thứ hai để tạo 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 một khoản thanh toán rất đơn giản của 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 qua ngân hàng sẽ được lưu vào cơ sở dữ liệu. Như bạn thấy, tôi đã tạo một hóa đơn, tạo một khoản thanh toán (một giao dịch ngân hàng) và lưu giao dịch vào đĩa. Trong xác nhận của tôi, tôi đặt những con số chính xác sẽ kết thúc trong giao dịch Ngân hàng và trong Hóa đơn được liên kết. Tôi kiểm tra số lần 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 giao dịch.
Sau khi chạy thử, tôi sẽ chuyển đến cơ sở dữ liệu và kiểm tra kỹ xem tôi có dự kiến gì không.
Sau Tôi đã viết bài kiểm tra, tôi bắt đầu viết mã phương thức thanh toán (một phần của lớp BankHeader). Trong mã, tôi chỉ làm phiền với mã để thực hiện lần 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 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. Cả hai 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 mình xuống các tình huống phức tạp hơn.
1) Hãy 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 mà
3) Chạy rằng thử nghiệm duy nhất để xem nếu nó sẽ vượt qua
4) Nếu nó didn' Tôi muốn 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 thử nghiệm
Đâ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. Nếu không có thử nghiệm đơn vị, tôi không biết bắt đầu viết mã như thế nào, vấn đề dường như quá tải. Với thử nghiệm tôi có thể bắt đầu với một phương pháp đơn giản và mở rộng nó từng bước với sự đảm bảo rằng các kịch bản đơn giản hơn sẽ vẫn hoạt động.
Tôi chắc chắn rằng việc sử dụng kiểm tra đơn vị đã tiết kiệm cho tôi 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ĩ về một tình huống mới, tôi có thể thêm nó vào các thử nghiệm để xem nó có đang hoạt động hay không. Nếu không, tôi có thể sửa đổi mã nhưng vẫn đảm bảo các tình huống 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 sửa chữa và sửa lỗi.
Có, mã thậm chí thử nghiệm vẫn có thể có lỗi nếu người dùng làm những việc bạn không nghĩ đến hoặc ngăn cản ông làm
Dưới đây là một số bài kiểm tra tôi tạo ra để thử nghiệm phương thức thanh toán của tôi.
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);
}
"Nếu bạn biết có vấn đề, hãy viết một bài kiểm tra cho nó. Nếu không, đừng bận tâm." Tôi sẽ không đồng ý với cách này được diễn đạt.Tôi đã được ấn tượng rằng các bài kiểm tra đơn vị nên bao gồm tất cả các đường dẫn thực hiện có thể. –
Trong khi một số người có thể ủng hộ những điều như vậy, cá nhân tôi thì không. 90% cơn đau đầu của tôi đến từ việc chỉ đơn giản là cố gắng làm "mọi thứ". Tôi nói thử nghiệm cho những gì bạn mong đợi xảy ra (vì vậy bạn biết bạn đang nhận được các giá trị đúng trở lại) nhưng không cố gắng và con số nó tất cả ra ngoài. YAGNI. –
Tôi cũng ủng hộ cách tiếp cận "kiểm tra lỗi của bạn". Nếu tất cả chúng ta đều có thời gian và kiên nhẫn vô hạn, chúng tôi sẽ kiểm tra mọi con đường thi hành có thể. Nhưng chúng tôi không, vì vậy bạn phải dành nhiều nỗ lực của bạn, nơi nó sẽ có hiệu quả lớn nhất. – Schwern