我目前正在阅读一本关于使用 testNG 和 Mockito 进行测试的书,以提高我使用这些工具的技能,拓宽我对一般测试的了解并提高我创建的代码的质量。
在第 4 章“测试驱动开发”之后,我应该做很多练习来巩固我刚刚学到的关于 TDD 的知识,并养成循环红色测试 -> 实现代码 -> 绿色测试 -> 的习惯重构。其中之一称为“PasswordValidator”,它应该可以验证密码的强度。
此类开发的推荐方法之一是从最简单的测试开始,然后通过编写更复杂的测试用例逐步实现更复杂的功能。说实话,通常我会通过编写一个适当的正则表达式(例如这个:https://stackoverflow.com/a/5142164/2576122)来解决这个问题,编写一些测试来涵盖我可能想象的任何边界情况并完成它。
在这里,我首先创建 PasswordValidatorTest 类并在其中进行测试,例如:
@Test
public void returnsTrueWhenPasswordIsAtLeastEightCharsLong() {
assertTrue(atLeastEightCharactersLong(EIGHT_CHARACTERS_LONG_PASSWORD));
}
我检查它是否失败,在 PasswordValidator 中实现逻辑:
public static boolean atLeastEightCharactersLong(String passwordToValidate) {
if (passwordToValidate.length() >= 8) {
return true;
} else {
return false;
}
}
我检查它是绿色的,然后重构:
public static boolean atLeastEightCharactersLong(String passwordToValidate) {
return (passwordToValidate.length() >= 8);
}
对于包含数字、特殊符号等的测试也是如此。在此类过程的某个时刻,我最终进行了最终测试:
@Test
public void shouldReturnTrueIfPasswordIsValid() {
assertTrue(PasswordValidator.isValid(VALID_PASSWORD_EXAMPLE));
}
实现是:
public static boolean isValid(String passwordToValidate) {
return atLeastEightCharactersLong(passwordToValidate) && containsAtLeastTwoDigits(passwordToValidate) &&
containsAtLeastOneSpecialSign(passwordToValidate);
}
然后在测试为绿色之后我可以清楚地看到,所有早期测试的方法从一开始就应该是私有(private)方法。
在编码过程中,TDD 中的一些最初有用的测试被删除的情况是否经常发生并且被接受?因为可以肯定的一件事 - 这些方法根本不应该暴露给该类用户,所以像“保护它们”这样的回答对我没有吸引力。
或者也许我的方法从一开始就是无效的,我应该只为 isValid() 方法编写一个测试,以测试 API 的行为?如果我这样做的话,这样的测试会太笼统,并且不允许我在开发时检查所有边界情况,或者我可能完全错了?测试什么和根本不应该测试什么之间有界限吗?粒度应该是多少?
最佳答案
Or maybe my approach from the very beginning is invalid and I should have only written a test for isValid() method
是的,这个。
所以你写这样的东西作为起点:
public static boolean isValid(String passwordToValidate) {
return false;
}
然后你可以编写你的第一个测试:
@Test
public void returnsTrueWhenPasswordIsAtLeastEightCharsLong() {
assertTrue(isValid(EIGHT_CHARACTERS_LONG_PASSWORD));
}
哪个会失败:RED。
因此,您对被测代码进行了最简单的更改以使其通过:
public static boolean isValid(String passwordToValidate) {
return true;
}
然后测试将通过:绿色。
但是您还没有完全测试 8 个字符的限制:
@Test
public void returnsFalseWhenPasswordIsLessThanEightCharsLong() {
assertFalse(isValid(SEVEN_CHARACTERS_LONG_PASSWORD));
}
这将失败——红色——因为被测试的方法现在总是返回真。
所以你做出最小的改变来使所有测试通过:
public static boolean isValid(String passwordToValidate) {
return passwordToValidate.length() >= 8;
}
你又变绿了。
然后您继续这样做,添加其他测试,并且每次都尽可能少地更改您正在测试的代码以使测试通过。
您可能会发现在某个阶段通过将 isValid
方法拆分为您调用的一些私有(private)方法来重构它很有用。没关系:它是重构步骤的一部分,而且您的测试应该仍然通过,因为公共(public)接口(interface)没有改变。
关于java - 在 TDD 过程中删除单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25473626/