我正在尝试了解有关 JUnit 和 TDD 的更多信息,但我遇到了一些与测试用例之间的耦合有关的问题。
当我为特定数据类型的 API 编写测试用例时,说 Deque<T>
,如何限制测试用例之间的耦合?例如,如果我正在为 insertFirst(T item)
方法编写测试用例,假设我应该能够在正确初始化的对象上调用方法后断言两件事似乎很简单:
Deque
的大小对象应该增加一个- 如果我随后调用相应的
T removeFirst()
方法,它应该返回对我在初始调用中插入的对象的引用。
但是,这会在我的至少两个测试用例之间造成不良耦合,其中一个测试用例的通过取决于另一个 API 方法的正确实现。例如,为了让这个测试用例通过,我需要一个正确的实现来检查 Deque
中的项目数量。也用于删除项目。如果我对这些方法中的任何一个的测试由于某种原因不正确或不完整,那么我对 insertFirst
的测试方法会自动被怀疑。
避免这种情况的最佳做法是什么?我编写测试用例的方法在某种程度上是错误的吗?
最佳答案
在为一种方法编写测试时,您必须假设类的其余部分工作正常。如果您不做这个假设,唯一的结论就是每个类(class)进行一次大规模测试。而这不是我们所做的。
你可以假设类的其他部分工作正常,因为也会对其他部分进行测试,以确保它们的正确性。
如果一个部分工作不正常,测试就会失败,向您表明某些地方不正确。
一旦测试套件的测试失败,就必须修复错误。您无法再做出任何假设。
例子:
你有一个简单的列表实现,只有三个方法:
- 插入
- 移除
- 计数
你有三个测试:
- 测试
插入
:
- 创建列表实例(排列)
插入
项(行动)- 检查
count
是否等于 1(断言)
- 测试
删除
:- 创建列表实例并
插入
项(排列) 删除
项(行动)- 检查
count
是否等于 0(断言)
- 创建列表实例并
- 测试
计数
:- 创建列表实例并
插入
n 个项目(排列) - 检索
计数
(行动) - 检查
count
是否等于 n(断言)
- 创建列表实例并
现在,如果上述任何测试失败,您将无法确定类(class)中单个成员的正确性:
- 如果第一个测试失败,第三个也会失败。第二个会通过,但实际上并没有测试
remove
,因为没有要删除的东西。 - 如果第二个测试失败,其他两个测试仍然会通过。尽管如此,您仍不能确定
insert
和count
是否正常工作,因为如果这三个成员中的任何一个没有正常工作,第二个测试就会失败。< - 如果第三个测试失败,其他两个很可能也会失败。
虽然失败的测试告诉你一些事情:
根据失败的测试,您通常可以推断出错误所在。
示例:如果只有第二个测试失败而第一个或第三个测试都没有失败,则错误很可能在 remove
方法中。
关于java - 减少测试用例之间的耦合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14980370/