如果您要处理的大量遗留代码目前未在测试中,那么现在就进行测试,而不是等待将来的假设性大笔重写是正确的做法。不是通过编写单元测试开始的。
如果没有自动测试,则在对代码进行任何更改之后,您需要对应用程序进行一些手动的端到端测试,以确保其正常运行。首先编写高级集成测试来代替它。如果您的应用程序读取文件,对其进行验证,以某种方式处理数据,并显示您想要捕获所有内容的测试结果。
理想情况下,您将获得来自手动测试计划的数据,或者能够获取要使用的实际生产数据的样本。如果不是这样,则由于该应用程序已经投入生产,在大多数情况下,它正在按照应有的方式工作,因此只需弥补将达到所有高点的数据,并假设目前的输出是正确的即可。这并不比承担一个小的功能,假设它正在执行其名称或任何注释表明应执行的功能以及编写测试(假设其正常工作)更糟糕。
IntegrationTestCase1()
{
var input = ReadDataFile("path\to\test\data\case1in.ext");
bool validInput = ValidateData(input);
Assert.IsTrue(validInput);
var processedData = ProcessData(input);
Assert.AreEqual(0, processedData.Errors.Count);
bool writeError = WriteFile(processedData, "temp\file.ext");
Assert.IsFalse(writeError);
bool filesAreEqual = CompareFiles("temp\file.ext", "path\to\test\data\case1out.ext");
Assert.IsTrue(filesAreEqual);
}
一旦编写了足够的这些高级测试来捕获应用程序的正常运行和最常见的错误情况,您将需要花费大量时间在键盘上敲打,以尝试从代码中捕获错误,而不是执行其他操作您以为应该做的事情会大大减少,从而使将来的重构(甚至大笔重写)变得更加容易。
由于您能够扩展单元测试的覆盖范围,因此您可以缩减甚至淘汰大多数集成测试。如果您的应用程序正在读取/写入文件或访问数据库,则隔离测试这些部分,然后模拟它们或通过创建从文件/数据库读取的数据结构开始进行测试是一个显而易见的起点。实际上,创建该测试基础结构将比编写一组快速而肮脏的测试花费更多的时间。并且每次您运行2分钟的集成测试集,而不是花30分钟手动测试集成测试所涵盖内容的一小部分,您就已经取得了巨大的成功。