这让我进入了单元测试,这让我很开心
我们刚刚开始进行单元测试。
很长一段时间以来,我都知道开始这样做会很好,但我不知道如何开始,更重要的是要测试什么。
然后我们不得不在我们的会计程序中重写一段重要的代码。
这部分非常复杂,因为它涉及许多不同的场景。
我所说的部分是一种支付已输入会计系统的销售和/或采购发票的方法。
我只是不知道如何开始编写代码,因为有很多不同的付款方式。
一张发票可能是 100 美元,但客户只转了 99 美元。
也许您已经向客户发送了销售发票,但您也从该客户那里购买了产品。
所以你以 300 美元的价格卖掉了他,但你以 100 美元的价格买下了他。您可以期望您的客户向您支付 200 美元来结清余额。
如果你卖了 500 美元,但客户只付给你 250 美元怎么办?
因此,我有一个非常复杂的问题需要解决,其中一种方案可以完美运行,但在另一种类型的发票/付款组合上会出错。
这就是单元测试的用武之地。
我开始(在测试代码中)编写一种方法来创建发票列表,包括销售和采购。
然后我编写了第二种方法来创建实际付款。
通常,用户会通过用户界面输入该信息。
然后我创建了第一个 TestMethod,测试了一个非常简单的单张发票付款,没有任何付款折扣。
当银行付款被保存到数据库时,系统中的所有操作都会发生。
如您所见,我创建了一张发票,创建了一笔付款(银行交易)并将交易保存到磁盘。
在我的断言中,我在银行交易和链接的发票中输入了正确的数字。
我在交易后检查付款次数、付款金额、折扣金额和发票余额。
测试运行后,我会去数据库并仔细检查我所期望的是否存在。
写完测试后,我开始编写支付方式(BankHeader 类的一部分)。
在编码中,我只关心代码以使第一次测试通过。我还没有考虑其他更复杂的场景。
我运行了第一个测试,修复了一个小错误,直到我的测试通过。
然后我开始编写第二个测试,这次是使用付款折扣。
写完测试后,我修改了付款方式以支持折扣。
在使用付款折扣测试正确性的同时,我还测试了简单付款。
当然,这两个测试都应该通过。
然后我逐步解决了更复杂的场景。
1) 想一个新的场景
2) 为该场景编写测试
3) 运行该单一测试以查看它是否会通过
4) 如果没有,我会调试和修改代码,直到它通过。
5) 在修改代码时,我继续运行所有测试
这就是我设法创建非常复杂的付款方式的方法。
如果没有单元测试,我不知道如何开始编码,这个问题似乎很严重。
通过测试,我可以从一个简单的方法开始,然后逐步扩展它,确保更简单的场景仍然有效。
我确信使用单元测试为我节省了几天(或几周)的编码时间,并且或多或少地保证了我的方法的正确性。
如果我以后想到一个新场景,我可以将它添加到测试中,看看它是否有效。
如果不是,我可以修改代码,但仍然可以确保其他方案仍然正常工作。
这将在维护和错误修复阶段节省大量时间。
是的,如果用户做了您没有想到或阻止他做的事情,即使经过测试的代码仍然可能存在错误
以下只是我为测试付款方式而创建的一些测试。
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);
}