最近我想通过开发真实的东西来学习TDD,所以我决定使用简单的数据打包器/解包器。在纸上设计后,一切看起来都不错,但是当我尝试编码时,我意识到我不知道如何测试它,所以在TDD中 - 如何做任何事情。
我有两个课程:ArchiveReader
和ArchiveWriter
。问题是,当我用ArchiveWriter
保存文件时,我无法在没有ArchiveReader
的情况下正确测试它,没有它我不得不逐字节地比较输出,我想这就是' s不好主意 - 稍后可能发生轻微的,相关的变化。 ArchiveReader
测试也需要阅读,所以我必须使用ArchiveWriter
来制作测试包。
TDD在这方面失败了吗?有没有方法来测试这样的案例?
答案 0 :(得分:5)
如果您已经拥有这两个类的代码,那么它不是真正的TDD,因为 tests 没有驱动 设计。
您仍然可以测试代码,具体取决于如何处理这些类的依赖关系。例如,如果ArchiveWriter
类写入流,您可以将其输出到内存流而不是文件流,编写者不应该关心它是什么类型的流,它将允许您比较写方法的结果。
同样适用于ArchiveReader
类,如果它从流中读取,则它可以是内存流。
关于ArchiveWriter
和ArchiveReader
相互依赖于相互验证的问题,我认为这不一定是个问题。虽然能够独立测试它们是理想的,但是没有规则单元测试只能测试单个类。
至于这些类,在制作中,它们可能总是彼此相切使用,如果你以后再也不能再读它,那么写一个档案是毫无意义的。
答案 1 :(得分:2)
我开发了这种代码,它有两个必须读写相同二进制格式的类或方法,一直使用TDD。
您提到逐字节检查输出。我更喜欢输入代码的类似测试,因为虽然我必须手工制作二进制输入,但输入代码的行为通常更容易检查。它将委托给方法或创建对象,您可以通常的方式检查它是否正确。
我还有对称性测试。这些使用输出代码创建二进制表示,然后让输入代码从该二进制表示创建一组新对象。测试检查原始对象和新对象是否等效。这些测试很容易编写,并在失败时产生有用的duagnostics。
现在,有些人会说,哦,但是你没有进行单元测试,因为你的对称性测试测试输出代码和输入代码;您正在进行集成测试,因此做错了。这不应该让你担心。在进行集成测试之前,单元测试与集成测试之间存在整齐划分以及所有必须通过单元测试进行测试的想法是错误的。在实践中,几乎没有代码在完美隔离中进行测试;大多数经过测试的代码都使用其他类,即使它们是String
和HashMap
等基础知识。将测试视为完美单元测试和完美集成测试之间的连续性更有用,更喜欢所有代码在单元测试结束附近进行测试,但如果某些代码不这样做则不要太担心。
答案 2 :(得分:1)
在您的示例中,这意味着如果您想要对ArchiveReader或ArchiveWriter进行单元测试,首先应将其与实际I / O隔离并仅测试逻辑(C#/ java / ...“您的代码”)。
如果您以复杂的方式测试应用程序,那么主要是关于集成测试。因此,您的断言需要针对ArchiveWriter生成的文件。
在进入TDD之前,我建议你至少阅读一本关于单元测试的好书。 Roy Osherove的书非常适合我。