[英]Handle I/O in TDD based unit tests
我正在练习基于Java的TDD并编写一些代码来读取和写入文件。 现在,我对每个场景(读取和写入)进行了大约100次测试,以测试我的代码,每次我创建文件或读取给定文件。 要写入的文件将在临时目录中创建,并在每次测试运行后删除。 但是这种策略产生了大量的I / O,而且我担心在SSD寿命期间。 模拟不是一种选择。
一种可能性是重新编写/写入一次文件,然后针对(静态)数据结构(伪代码)运行我的测试:
private static Object resultData = null;
@BeforeClass
// Read/Write my stuff here
resultData = ....
@Test
// Check my requirements
assertTrue(resultData....);
问题是,我可以改变测试方法中的预期行为,因此我的测试不再是自治的。
你会怎么处理它?
但是这种策略产生了大量的I / O,而且我担心在SSD寿命期间。
你忽略了这一点:对于SSD磁盘 (现在足够标准),DWPD(每天驱动器写入数)为1适用于许多用例。
DWPD测量您可以在其生命的每一天覆盖驱动器的整个大小的次数。
对于500 GO磁盘,DWPD为1
意味着理论上您可以在未达到产品保修期限的情况下每天写入500 GO。
而这通常是5到10年。
因此,每个构建(100或更多)创建的一些临时文件几乎没有,但如果你每天执行几百万的构建。
此外,由于这种考虑,你不应该使代码或测试更复杂。
SSD可以让开发人员更简单,而不是更复杂。
话虽如此,在单元测试中避免这么多文件写入仍然是有意义的,因为测试必须快速执行。
您可以更改测试类的API,使其也接受ByteArrayInputStream
和ByteArrayOutputStream
。 这样,读取和写入将在内存中工作,而不是在文件系统中。
你会怎么处理它?
我会重构代码,以便使用测试双打(也就是模拟) 是一个选项。
具体来说,我希望创建这样的接缝
在像java这样的语言中,接缝将是一个接口。 我的I / O代码将实现接口,但本身不会在测试中运行。
相反,测试将使用合适的测试双 - 实现相同接口但实际上不执行写入磁盘。
注意:如果我想要模拟各种写入错误的测试,可能会有几种类型的test double,以确保复杂的逻辑能够正确处理这些错误。
当然,生产代码的组合根将需要创建要使用的“真实”实现的实例。 但是测试的组合根可以选择测试双重或内存文件系统,或者其他任何东西,以确保测试结果是确定性的(顺便说一下,不要咀嚼你的SSD寿命)。
Hoare为我们提供了关于场景背后代码的启发式方法
[构建软件设计]的一种方法是使其变得如此简单以至于显然没有缺陷
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.