厕所、想测试Google Testing on the Toilet (TotT):测试行为,而不是方法

上厕所、想测试Google Testing on the Toilet (TotT):测试行为,而不是方法

由Erik Kuefler 
本文改编自谷歌测试上厕所(TOTT)插曲。你可以下载一个打印机友好的版本,这TOTT插曲并张贴在你的办公室, 

 

写完一个方法后,很容易写只是一个测试来验证这个方法所做的一切。但是,认为测试和公有方法应该存在1:1的关系,这是非常有害的。我们真正要测试的是行为,而一个方法可能表现出很多的行为,另外,一个单一的行为有时会跨越多个方法。 让我们来看看一个验证了整个方法的糟糕的测试: 
@Test publicvoid testProcessTransaction() {
  User user = newUserWithBalance(LOW_BALANCE_THRESHOLD.plus(dollars(2));
  transactionProcessor.processTransaction(
      user,
      new Transaction("Pile of Beanie Babies", dollars(3)));
  assertContains("You bought a Pile of Beanie Babies", ui.getText());
  assertEquals(1, user.getEmails().size());
  assertEquals("Your balance is 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());
}


现在,当有人添加新的行为,他们会写针对该行为写新的测试用例。无论有多少行为被添加,每个测试用例将保持集中和易于理解。这会让你的测试用例更具弹性,因为增加新的行为的测试是不太可能破坏现有的测试;使得测试用例更清晰,因为每个用例只包含的测试一个行为的代码。 

原文地址:http://googletesting.blogspot.com/2014/04/testing-on-toilet-test-behaviors-not.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+blogspot%2FRLXA+%28Google+Testing+Blog%29

你可能感兴趣的:(测试代码)