作者:Erik Kuefler
原文链接:http://googletesting.blogspot.tw/2014/04/testing-on-toilet-test-behaviors-not.html
在写完一个方法之后,很容易写一个测试用例来验证这个方法的所做的一切。但是,认为测试用例和公共方法应该是一比一的关系是不利于测试的。我们真正要测试的是用户的行为,一个简单方法可以包括很多用户行为,同样一个简单的用户行为有时需要多个方法的来实现。
让我们来看看一个糟糕的测试用例,使用一个测试用例来验证整个方法:
@Test publicvoidtestProcessTransaction() {
User user = newUserWithBalance(LOW_BALANCE_THRESHOLD.plus(dollars(2));
transactionProcessor.processTransaction(
user,
new Transaction("Pileof Beanie Babies", dollars(3)));
assertContains("You bought aPile of Beanie Babies", ui.getText());
assertEquals(1,user.getEmails().size());
assertEquals("Your balanceis low", user.getEmails().get(0).getSubject());
}
显示已购买物品的名称和发送一封关于余额减少的电子邮件是两个独立的用户行为。但从这个测试用例来看,这两个用户行为是一起的,仅仅是因为它们恰巧用同样的方法来实现。像这类型的测试用例随着时间的推移将变得很庞大且难以维护,因为会不断地添加其他行为——最终会很难判断到底是输入的哪一部分决定了断言。事实上测试用例的名称直接采用测试方法的镜像是个不好的迹象。
更好的方式是使用不同的测试用例去验证不同的用户行为:
@Test publicvoid testProcessTransaction_displaysNotification() {
transactionProcessor.processTransaction(
new User(), new Transaction("Pile of Beanie Babies"));
assertContains("You bought a Pile of Beanie Babies", ui.getText());
}
@Test publicvoid testProcessTransaction_sendsEmailWhenBalanceIsLow() {
User user = newUserWithBalance(LOW_BALANCE_THRESHOLD.plus(dollars(2));
transactionProcessor.processTransaction(
user,
new Transaction(dollars(3)));
assertEquals(1, user.getEmails().size());
assertEquals("Your balance is low", user.getEmails().get(0).getSubject());
}