在测试中,首要目的是回答一个问题:什么被测试了——也就是测试的范围。
因此,如果你正在测试FTP服务器的实现,你将需要创建一个FTP客户端。
如果你正在测试FTP客户端,则需要创建一个FTP服务器。
因此,你必须缩小测试范围,直到达到单元级别。
例如,对于你的目的,可能包括:
- 获取应用程序当前安装文件的列表;
- 获取远程可用文件的列表;
- 获取文件更新;
- 检查文件是否正确(校验和?);
- 等等……
每个被测试的项都需要一些模拟和存根。关于两者之间的区别,请参见这篇文章。简而言之(依我所知),存根只是一个仿真对象,总是有效的。而模拟(在每个测试中应该是唯一的)是可能改变测试结果(通过或失败)的元素。
对于FTP连接的确切目的,例如(在测试客户端时)你可能会有一些返回文件列表的存根,并且有一个模拟将测试FTP服务器的几个可能的问题(超时,连接丢失,错误内容)。然后你的客户端应该按预期反应。你的模拟可能是一个真正的FTP服务器实例,但它将像预期的那样运行以触发所有潜在的错误。通常,每个错误都会引发异常,这些异常需要由测试单元跟踪,以通过/失败每个测试。
编写良好的测试代码有点困难。测试驱动的方法一开始可能需要花费一些时间,但从长远来看总是更好的。必须阅读一本好书,或至少参考一些参考文章(如上面链接的Martin Fowler的文章)。在Delphi中,使用接口和SOLID原则可以帮助你编写这样的代码,并创建存根/模拟来编写测试。
通过我的实验,每个程序员有时会在编写测试时感到迷失...好的测试编写可能比功能编写更耗费时间,在某些情况下...你被警告了!每个测试都应该被视为一个特性,并且它的成本应该得到评估:这值得吗?这里难道没有更适合的另一个测试吗?我的测试与正在测试的特性分离了吗?它不是已经被测试了吗?我是在测试我的代码,还是第三方/库的特性?
题外话,但我想说一下:HTTP / 1.1 现在甚至对于文件更新可能是一个更好的选择,而非 FTP。您可以恢复 HTTP 连接,分块并行加载 HTTP 内容,并且这种协议比 FTP 更容易在代理中使用。而且,与 FTP 相比,托管一些 HTTP 内容要容易得多(一些 FTP 服务器也存在已知的安全问题)。大多数软件更新现在都是通过 HTTP / 1.1 进行的,而不是 FTP(例如 Microsoft 产品或大多数 Linux 资源库)。
编辑:
您可能会认为,当您使用远程协议时,您正在进行集成测试。这可能是有道理的,但我认为这并不相同。
据我了解,当您让所有组件一起工作并检查它们是否按预期工作时,集成测试就会发生。我的关于 FTP 测试的建议是,在模拟 FTP 服务器以明确测试所有潜在问题(超时、连接或传输错误等)之前,您需要进行测试。这与集成测试不同:代码覆盖范围更大。而且,您只测试了一部分代码,而不是整个代码集成。这并不是因为您正在使用某些远程连接,所以您正在进行集成测试:这仍然是单元测试。
当然,在单元测试之后,还应执行集成和系统测试。但是,FTP 客户端单元测试可以模拟本地运行的 FTP 服务器,同时测试可能出现在真正的全球网络中的所有潜在问题。