如何在不知道其实现的情况下对堆栈 ADT 进行单元测试
How to unit test a stack ADT without knowing its implementation
假设一个栈有以下函数,pop
、push
、peek
和toArray
。
如果我想为推送操作编写单元测试,如何在不知道底层实现的情况下完成?一种可能性是将某些东西推入空堆栈并根据预期结果测试 stack.toArray()
,但这涉及未测试的功能。
您无法真正孤立地测试功能。如果你想测试 push()
你必须 pop()
以测试元素以正确的顺序弹出。
你不需要使用 toArray()
除非你也想为它编写测试。
你提出了一个有趣的问题。事实上,您必须根据使用模式而不是个别方法来测试 ADT。
考虑堆栈的要求:
- 当我将项目 X 推入堆栈时,我希望没有响应。
嗯,这当然是可以测试的,但它内置于 return 类型中,即 void
或 unit
。
只有推动动作没有什么可以直接观察到的。相反,它是定义行为的特定操作组合。
- 当我将项目 X 推入空堆栈时,我希望 X 位于堆栈顶部且下方没有任何内容。
嗯。这测试 push
,但正如您所指出的,如果没有其他堆栈函数,您无法真正解决后半部分问题。
在这种情况下,推动时发生的事情重要吗?不!您关心的是某些操作序列会导致可验证且一致的结果。
一般的单元测试都是如此:如果可以,单独测试每个函数。但是当这样做没有意义时,请改用行为模式。
您不能假设推送到堆栈会立即产生结果的部分原因是您从未得到这种保证。例如,假设您的堆栈实现使用了一个奇特的缓冲区:每次推送时,它都会将元素添加到缓冲区,但还没有将其放入正式堆栈。然后,当您调用 peek
或 pop
时,它会立即处理所有缓冲项,然后执行操作。对您来说,内部结构是不可见的:您只关心整体行为是否与堆栈的行为一致。
从本质上讲,这就是它成为 ADT 的原因。我们关心行为模式,而不是具体实施。
假设一个栈有以下函数,pop
、push
、peek
和toArray
。
如果我想为推送操作编写单元测试,如何在不知道底层实现的情况下完成?一种可能性是将某些东西推入空堆栈并根据预期结果测试 stack.toArray()
,但这涉及未测试的功能。
您无法真正孤立地测试功能。如果你想测试 push()
你必须 pop()
以测试元素以正确的顺序弹出。
你不需要使用 toArray()
除非你也想为它编写测试。
你提出了一个有趣的问题。事实上,您必须根据使用模式而不是个别方法来测试 ADT。
考虑堆栈的要求:
- 当我将项目 X 推入堆栈时,我希望没有响应。
嗯,这当然是可以测试的,但它内置于 return 类型中,即 void
或 unit
。
只有推动动作没有什么可以直接观察到的。相反,它是定义行为的特定操作组合。
- 当我将项目 X 推入空堆栈时,我希望 X 位于堆栈顶部且下方没有任何内容。
嗯。这测试 push
,但正如您所指出的,如果没有其他堆栈函数,您无法真正解决后半部分问题。
在这种情况下,推动时发生的事情重要吗?不!您关心的是某些操作序列会导致可验证且一致的结果。
一般的单元测试都是如此:如果可以,单独测试每个函数。但是当这样做没有意义时,请改用行为模式。
您不能假设推送到堆栈会立即产生结果的部分原因是您从未得到这种保证。例如,假设您的堆栈实现使用了一个奇特的缓冲区:每次推送时,它都会将元素添加到缓冲区,但还没有将其放入正式堆栈。然后,当您调用 peek
或 pop
时,它会立即处理所有缓冲项,然后执行操作。对您来说,内部结构是不可见的:您只关心整体行为是否与堆栈的行为一致。
从本质上讲,这就是它成为 ADT 的原因。我们关心行为模式,而不是具体实施。