测试第三方库的智能包装

ins*_*pid 6 testing tdd integration integration-testing unit-testing

假设你需要使用一个不必要的复杂,很难嘲笑(也许它有具体的类不带虚拟接口),与一些外部资源整合,如插座或数据库,以及不可靠的第三方库.您决定创建"包装器"接口/类以大大简化此库的使用,并允许使用包装器的开发人员继续编写可测试代码.包装器的界面看起来与原始界面完全不同.

我有一些关于如何测试这个包装器的问题.

  1. 是否应该在没有外部资源的情况下测试包装器,方法是在可以模拟的坏库上开发方法方法层?

  2. 当您使用第三方库(使用外部资源)测试包装类时,这是单元测试还是集成测试?如果外部资源可以在自动化测试期间嵌入到内存中,它仍然是集成测试吗?

  3. 在什么时候我们放弃嘲弄和抄袭并说我们有一个单位.根据维基百科"一个单元是应用程序中最小的可测试部分".但我发现这很难衡量.如果速度是决定我们是否正在测试一个单元的一个因素,那么您如何确定将该测试称为单元测试的速度有多慢?

Lad*_*nka 9

TDD并没有说一切都必须经过单元测试.TDD说你应该先写一个测试,但它不一定是单元测试.

  1. 从集成测试开始 - 它将根据与真实组件通信的包装器测试您的逻辑.这里没有嘲笑.它是集成测试,因为它测试应用程序的多个层,而实际组件仍然使用套接字或数据库访问.
  2. 集成测试将失败,因为您没有逻辑
  3. 使用模拟包装器编写单元测试来测试逻辑
  4. 单元测试将失败,因为您没有逻辑
  5. 写逻辑以满足单元测试(4.)
  6. 重复3.-5.获得满足集成测试所需的所有逻辑(1.)
  7. 使用下一个集成测试重复整个过程

没有必要为包装器编写单元测试.主包装器的功能是包装组件.如果您为包装器编写单元测试,您将测试它在组件上调用方法,但在这种情况下,您回到开头 - 如何模拟组件?如果您只是为包装器调用组件而编写集成测试,那么您正在重新测试该组件(确定这有时很方便,但在正常情况下您不这样做).

我建议阅读由Steve Freeman和Nat Pryce 测试引导的面向对象的成长软件.


Mar*_*ann 6

我认为这个问题围绕着这个陈述:

包装器的界面看起来与原始界面完全不同

这可能表明包装器和原始接口之间的转换涉及大量逻辑.这听起来很像反腐败层,如果这个逻辑很复杂,那就应该进行测试.

最好的方法是从原始API中提取1:1接口.但是,这不是您向应用程序其余部分公开的接口.您向应用程序其余部分公开的接口可以是提取的接口上的Facade.从某种意义上说,你可以说提取的接口是反腐败层的实现细节,而不是暴露给应用程序其余部分的东西.

这使您可以对Facade界面和提取的界面之间的转换进行单元测试,同时仍然保持原始的,难以测试的组件不在测试之外.

剩下的是提取的界面和原始组件之间的转换.但是,如果将该接口提取为原始组件的1:1映射,则实现应包含纯委托.换句话说,实现的圈复杂度为1,因此是一个不需要进行单元测试的简单对象.

您可能仍希望在已完成的系统上进行一些集成或系统测试,但这些可能会起到冒烟测试的作用,因为您应该已经从单元测试中获得足够的覆盖.