Raf*_*cci 12 delphi ftp unit-testing delphi-2010
我正在为我的应用程序开发实时更新.到目前为止,我已经创建了几乎所有单元测试,但我不知道如何测试连接到FTP服务器并下载新版本的特定类.
要测试这个类,我应该创建一个FTP测试服务器并在我的单元测试中使用它吗?如果是这样,我如何确保此FTP服务器始终与我的测试保持一致?我应该在测试开始之前手动创建我需要的每个文件,还是应该在我的测试类中自动执行此操作(拆除和设置方法)?
这个问题也适用于连接任何类型服务器的单元测试类.
编辑
我已经在模拟我的ftp类,所以我不需要在其他测试中连接到ftp服务器.
让我看看沃伦在评论中所说的话我是否正确:
我认为,一旦你通过TCP/IP与一个单独的应用程序交谈,我们就应该称之为"集成测试".一个是不再测试一个单元或方法,而是一个系统.
当单元测试需要与另一个应用程序(可以是HTTP服务器或FTP服务器)通信时,这不再是单元测试而是集成服务器吗?如果是这样,我是否通过尝试使用单元测试技术来创建此测试?说我不应该对这个班级进行单元测试是否正确?这对我来说很有意义,因为单元测试似乎需要做很多工作.
在测试中,目的始终是首先回答问题:测试的是什么 - 即测试的范围.
因此,如果您正在测试FTP服务器实现,则必须创建FTP客户端.
如果您正在测试FTP客户端,则必须创建FTP服务器.
因此,您必须缩小测试范围,直到达到统一级别.
例如,它可能是出于您的目的:
每个测试项目都有一些模拟和存根.请参阅这篇文章,了解两者之间的区别.简而言之(AFAIK),存根只是一个仿真对象,它始终有效.并且模拟(在每个测试中应该是唯一的)是可以改变测试结果的元素(通过或失败).
对于FTP连接的确切目的,您可以(例如,在测试客户端时)有一些返回文件列表的存根,以及一个可以测试FTP服务器的几个可能问题的模拟(超时,连接丢失,错误)内容).然后您的客户端将按预期做出反应.您的模拟可能是一个真正的FTP服务器实例,但它会按预期运行以触发所有潜在的错误.通常,每个错误都会引发一个异常,由测试单元跟踪,以便通过/不通过每个测试.
编写好的测试代码有点困难.测试驱动的方法起初有点耗时,但从长远来看总是更好.这里有一本好书,或者至少是一些参考文章(如上面链接的Martin Fowler).在Delphi中,使用接口和SOLID原则可以帮助您编写此类代码,并创建存根/模拟来编写测试.
从我的实验来看,每个程序员有时会在编写测试时丢失...良好的测试编写可能比编写功能更耗时,在某些情况下......你会受到警告!每项测试都应视为一项功能,并评估其成本:是否值得?这里不是另一种测试更合适吗?我的测试是否与它正在测试的功能分离?它尚未经过测试吗?我在测试我的代码或第三方/库功能吗?
超出主题,但我的两分钱:HTTP/1.1现在可能是比FTP更好的候选者,即使是文件更新.您可以恢复HTTP连接,并行地通过块加载HTTP内容,并且此协议比FTP更加代理友好.托管一些HTTP内容比FTP更容易(一些FTP服务器也已知安全问题).目前大多数软件更新都是通过HTTP/1.1执行的,而不是FTP(例如Microsoft产品或大多数Linux存储库).
编辑:
当您使用远程协议时,您可能会争辩说您正在进行集成测试.这可能有意义,但恕我直言,这是不一样的.
据我所知,当您让所有组件与实际应用程序一起工作时,就会进行集成测试,然后检查它们是否按预期工作.我关于FTP测试的建议是你正在模拟FTP服务器,以便明确地测试所有潜在的问题(超时,连接或传输错误......).这不是集成测试:代码覆盖范围要大得多.而且您只测试代码的一部分,而不是整个代码集成.这不是因为您正在使用某些远程连接进行集成测试:这仍然是单一测试.
当然,集成和系统测试应在单一测试后进行.但FTP客户端单一测试可以模拟FTP服务器,在本地运行它,但测试可能在真正的大型万维网上发生的所有潜在问题.
如果您使用的是Indy 10的TIdFTP组件,那么您可以利用Indy的TIdIOHandlerStream类假冒FTP连接,而无需实际连接到真正的FTP服务器.
创建一个TStream对象,例如TMemoryStream或TStringStream,包含您希望TIdFTP为其发送的所有命令接收的FTP响应(使用数据包嗅探器预先捕获这些,以便让您了解需要包含的内容),并放置副本您通常下载到的本地文件夹中的更新文件的.创建一个TIdIOHandlerStream对象并将其指定TStream为ReceiveStream,然后TIdFTP.IOHandler在调用之前将IOHandler分配给该属性Connect().
例如:
ResponseData := TStringStream.Create(
'220 Welcome' + EOL +
... + // login responses here, etc...
'150 Opening BINARY mode data connection for filename.ext' + EOL +
'226 Transfer finished' + EOL +
'221 Goodbye' + EOL);
IO := TIdIOHandlerStream.Create(FTP, ResponseData); // TIdIOHandlerStream takes ownership of ResponseData by default
FTP.IOHandler := IO;
FTP.Passive := False; // Passive=True does not work under this setup
FTP.Connect;
try
FTP.Get('filename.ext', 'c:\path\filename.ext');
// copy your test update file to 'c:\path\filename.ext'...
finally
FTP.Disconnect;
end;
Run Code Online (Sandbox Code Playgroud)