我正在练习基于Java的TDD,并编写一些代码来读写文件。现在,对于每种情况(读写),我都有大约100个测试来测试我的代码,在这里我每次都创建一个文件或读取一个给定的文件。要写入的文件将在临时目录中创建,并且在每次测试运行后都会被删除。 但是这种策略会产生大量的I / O,例如SSD寿命。不能选择模拟。
一种可能性是读取/写入一次文件,然后针对(静态)数据结构(伪代码)运行我的测试:
private static Object resultData = null;
@BeforeClass
// Read/Write my stuff here
resultData = ....
@Test
// Check my requirements
assertTrue(resultData....);
问题是,我可以在测试方法内更改预期的行为,因此我的测试不再是自治的。
您将如何处理?
答案 0 :(得分:2)
但是这种策略会产生大量的I / O,例如 SSD使用寿命。
您对此有所考虑:SSD Disk(今天已经足够标准)的DWPD(每日驱动器写入)设置为1适合许多用例。
DWPD衡量您一天可以覆盖驱动器整个大小的次数。
对于500 GO磁盘,DWPD到1
意味着理论上您可以在未达到产品保修政策期限的情况下每天写入500 GO。
一般在5到10年之间。
因此,如果每天执行数百万次构建,那么每次构建时创建的一些临时文件(100个或更多)几乎什么都没有。
此外,由于这种考虑,您不应该使代码或测试变得更复杂。
SSD可以使开发人员更轻松,而不是更复杂。
话虽如此,在单元测试中避免写太多文件仍然有意义,因为必须快速执行测试。
您可以更改测试类的API,以使其也接受ByteArrayInputStream
和ByteArrayOutputStream
。这样,读取和写入将在内存中进行,而不是在文件系统中进行。
答案 1 :(得分:0)
您将如何处理?
我将重构代码,以便使用测试双精度(也称为模拟) 是一个选项。
具体来说,我希望创建这样的接缝
在像Java这样的语言中,接缝将是一个接口。我的I / O代码会实现接口,但本身不会在测试中运行。
相反,该测试将使用合适的双重测试-实现相同接口但实际上不执行磁盘写入操作。
注意:如果我想要模拟各种写入错误的测试,以确保复杂的逻辑能够正确处理这些故障,则可能会有多种类型的双重测试。
生产代码的composition root当然需要创建要使用的“真实”实现的实例。但是测试的组合根目录可以选择测试双倍,内存文件系统或其他确保测试结果具有确定性的选项(顺便说一下,不要占用SSD的使用寿命)。>
是我们对幕后代码的启发[构建软件设计]的一种方法是使其变得如此简单,以至于显然没有缺陷