进行集成和验收测试的效率陷阱(自动化)

时间:2011-01-05 19:08:41

标签: unit-testing testing tdd integration-testing

单元测试的优点对我来说很明显,它们由开发人员自己完成(测试或代码优先)并且是自动化的。

我有点不确定的是,当团队已经由一个专门的测试人员组成时,开发人员是否也应该进行集成测试,他们会尽可能地自动化并对整个系统进行黑盒测试(端到端)测试或更常见的称为验收测试。)

简短背景更多详情:

示例集成测试(MVC webapp)

  • 设置:在测试设置期间,仅控制器本身和控制器下面的层被引导。没有任何东西被嘲笑或残留。
  • 测试条目:裸控制器,大多数情况下,控制器入口点是带参数的方法(例如Spring MVC),可以本机执行。测试夹具期间不涉及浏览器
  • 断言目标:模型数据和视图名称被声明为直接输出。也可以断言间接输出(例如写入数据库的数据)。渲染的有效负载(通常是HTML)将被完全忽略。

示例验收测试(MVC webapp)

  • 设置:整个webapp都是自举的(就像从最终用户那里看到的那样)。
  • 测试条目:HTTP调用本身。浏览器可以作为测试执行者(例如Selenium
  • 断言目标:测试输出是完整的渲染响应(HTML和其他工件,如javascript)。还可以包括数据库上的断言(例如插入的数据)。

陷阱双重测试(积分+验收)

在包含两种测试样式时,我发现了主要问题:

  • 控制器测试接近一般系统行为(例如,提交登录表单,密码验证,成功登录)。这与验收测试的作用非常接近。最终可能会发生“双重测试”,这是非常低效的。
  • 控制器是更多的白盒测试,并且往往是脆弱的,因为它们依赖于较低层的许多依赖性(与非常细粒度的单元测试不同)。由于这种设置维护控制器测试很费力,接受测试整个应用程序启动时,黑盒子更加琐碎,并且更有利于接近生产。

以上两点得出的结论是,如果您的测试仪具有良好的自动化策略,则应跳过开发人员完成的集成测试。他们应该更多地关注单元测试。

你怎么看?你能解释一下你的测试策略吗?你有好的/坏的经历,包括两种测试风格吗?

感谢您阅读我的长篇问题;)

编辑:验收测试似乎是更常见的术语,因为我改变了条款。

4 个答案:

答案 0 :(得分:1)

我们在工作中接受TDD验收。

当我第一次开始时,我被告知只要工作以及时和可预测的方式完成,我就可以实施我想要的任何政策。在过去完成单元测试后,我意识到我们遇到的一个问题是集成错误。有些可能需要很长时间才能修复,而且往往是一个惊喜。我们会在扩展应用程序功能时遇到细微的错误。

我决定避免过去遇到的那些问题,更多地关注我们想要提供的最终结果功能。我们会编写测试接受行为的测试,不仅在单元级别,而且在整个系统级别。我想这样做是因为在一天结束时我并不关心设备是否正常工作,我关心整个系统是否正常工作。我们发现自动验收测试有以下好处。

  • 我们从不回归最终用户功能,因为它已经过明确测试。
  • 重构更容易,因为我们不必更新一堆单元测试。我们必须确保我们的验收测试仍然通过。
  • 隐含地涵盖了“单位”的整合。
  • 测试成为所需最终用户功能的非常明确的定义。
  • 集成问题早先暴露出来并且不那么令人意外。

这样做的一些折衷

  • 在使用模拟,存根,固定装置等方面,测试可能会更复杂。
  • 测试对缩小哪个“单位”存在缺陷的作用不大。

我们还通过持续集成服务器使测试套件可运行,该服务器使用标签和包进行部署。与大多数CI设置一样,它与每次提交一起运行。

关于你的观点/关注点:

  

设置:整个webapp是   引导(就像它会被看到   来自最终用户)。

我们倾向于做出的一个妥协是在单元测试的相同进程空间中运行测试。我们的入口点是应用程序堆栈的顶部。我们不打算尝试将应用程序作为服务器运行,因为这会增加复杂性并且不会增加覆盖范围。

  

测试条目:HTTP调用本身。浏览器   可以作为测试执行者参与(例如   硒)

我们所有的自动化测试都是通过模拟HTTP GET,POST,PUT或DELETE来实现的。我们实际上并没有使用浏览器,但是调用应用程序堆栈顶部的方式与特定HTTP调用的映射方式一样正常。

  

断言目标:测试输出是   完整呈现的响应(HTML和   其他工件,如javascript)。   断言数据库(例如数据得到)   插入)也可以包括在内。

我认为这是自动验收测试真正发挥作用的地方。您断言的是您希望保证实施的最终用户功能。

  

控制器测试接近一般   系统行为(例如提交登录   表单,密码验证,成功   登录)。这非常接近   端到端测试可以做到。到底   可能会发生“双重测试”   是非常低效的。

我们实际上只进行了很少的单元测试,并且几乎完全依赖于我们的自动验收测试。因此,我们没有太多的双重测试。

  

控制器是更多的白盒测试   因为它们往往很脆弱   依赖于较低的许多依赖   层(非常精细   粒度单位测试)。因为这个   设置维护控制器   测试是高效的端到端测试   整个应用程序的启动位置   因为黑匣子更琐碎而且有   优势更接近生产。

他们可能有更多的依赖关系,但可以通过使用模拟和固定装置来减轻这些依赖关系。我们通常也会使用2种执行模式来实现测试。非托管模式,其中测试完全连接到网络,dbs等。管理模式,其中测试运行时非托管资源被模拟。虽然你的断言是正确的,但测试可能需要更多的努力来创建和维护。

答案 1 :(得分:1)

开发人员应该对他更改/实施的部分进行集成测试。在集成测试中,我的意思是他们应该看看他们实现的功能是否真的按预期工作。如果你不这样做,你怎么知道你刚刚完成的是什么?单元测试本身并不是最终目标 - 重要的是产品。

这应该是为了加快查找错误。毕竟,集成测试需要很长时间才能执行(至少在我公司,因为复杂性需要1-2天才能执行所有集成测试)。之前发现错误比以后更好。

答案 2 :(得分:0)

通过系统测试测试的测试行为进行集成测试(实际上是单元测试)有助于通过缩小缺陷位置来进行调试。如果您的系统具有 ABC 组件并且系统测试用例失败,但程序集 AB 通过了类似的集成测试用例,则缺陷可能在组件 C中

答案 3 :(得分:0)

考虑到这篇文章正在处理测试陷阱,我想让你知道我最近出版的书,Common System和Software Testing Trafalls,它是Addison Wesley上个月发布的。它记录了92个测试陷阱,分为14个类别。每个陷阱都包括描述,潜在适用性,特征症状,潜在的负面后果,潜在原因以及避免陷阱的建议以及如果您已经陷入困境而攀爬的建议。请在Amazon.com上查看:http://www.amazon.com/Common-System-Software-Testing-Pitfalls/dp/0133748553/ref=la_B001HQ006A_1_1?s=books&ie=UTF8&qid=1389613893&sr=1-1