2013年测试基于Web的Spring应用程序(第1部分)

2013年测试基于Web的Spring应用程序(第1部分)

LJCer和TDD / BDD的一位拥护者最近开始使用广受欢迎的Spring堆栈开发应用程序,他就如何最好地在这种情况下实施测试驱动的方法向我提出了建议。 我开始回覆一封电子邮件作为回应,但后来我突然想到这也可能对其他人有用……所以在这里–我希望它能对您有所帮助

假设条件

本文的其余部分假定以下内容:

  • 应用程序将使用Spring堆栈的以下组件在Java中实现:核心,MVC,数据,安全性等,但我们将不涉及Spring Integration或Batch(尽管推荐的测试框架和工具可能非常相似,但我发现测试这些组件的技术可能大不相同,因此必须等到另一篇博客文章为止)
  • “最终用户”将通过基于Web的UI和/或基于HTTP的API与开发的应用程序进行交互(通常,但不仅限于REST)
  • 为了进行生产,将使用外部数据存储在应用程序中保持长期状态。 我们假设您也将要测试您的应用程序如何与此交互。
  • 除了使用简单的内存中的servlet容器(如Jetty)来部署整个打包的应用程序之外,我们将不涉及通过远程或嵌入式容器进行的测试。 诸如Arquillian之类的框架提供了一些非常酷的功能,这些功能允许针对实际(嵌入式)容器(例如Tomcat,GlassFish和JBoss Application Server)进行单元测试。 这是通过提供机制来模拟生产类包装(“ ShrinkWrapping ”)和在嵌入式容器内测试组件的任意子集(直至类级别)的方式来实现的,所有这些过程都可以通过您喜欢的测试框架进行,例如JUnit的。

一般建议

如果您是新的测试驱动开发人员,那么我推荐以下书籍:

  • 有效的单元测试:Java开发人员指南 -这是对基于Java的单元测试中所有关键概念和技术的出色介绍(并且是最新的)。 本书不仅涵盖了动机和方法,而且还介绍了如何编写具有表现力和可维护性的“良好”测试,并针对每种用例选择了最合适的技术。
  • 使用JUnit和Mockito进行 实用单元测试和/或使用TestNG和Mockito进行实用单元测试 。 这些都是很棒的书,其中包含有关如何测试Java应用程序的大量实用示例,还讨论了TDD的原因和方式。 这两本书非常相似,主要区别在于用于驱动测试的框架。 我的建议是购买结合“有效单元测试”(主要侧重于JUnit)的TestNG版本,因为很高兴知道两种最流行的基于Java的测试引擎的区别和优势/劣势。
  • 由测试指导的不断增长的面向对象软件(贝克签名) –这是经典的TDD书籍之一,它讨论了测试驱动应用程序设计的所有高级概念和动机。 本书还详细介绍了基于拍卖网站的整个应用程序的构建和演进过程,为如何使用规定的方法提供了一个很好的实践示例。
  • 有几本关于单元测试JavaScript的书,尽管我没有机会阅读所有这些书,但我还是推荐Testable JavaScript。

测试核心

单元测试

目的 :应用程序的核心对要解决的问题进行建模,通常包含特定于域的表示形式和相关的“业务”规则,这些规则主要由您负责编写(即,在此处可以重用第三方代码的机会是有点受限制)。

因此,很容易有人争辩说,该代码应该经过良好的测试-您在这里实现的组件不仅可能是唯一的,而且还希望在将它们连接到提供样板功能的框架(例如,坚持不懈。 编写良好的测试还可以在微观级别上“记录”您的代码(及相关功能)。

工具

  • JUnit / TestNG –用于运行Java测试的事实上的框架。 我喜欢通过surefire插件将这些作为我的Maven构建过程的一部分运行
  • Spock –基于Groovy的出色测试和规范框架。 如果您还没有听说过,请立即停止阅读并访问该网页。 说真的 现在查看Spock基础页面 。 那有多棒? 而且它在Spring中也能很好地发挥作用
  • Mockito –我最喜欢的模拟框架。 其他确实存在,但我发现Mockito在易用性,表达性和可维护性之间取得了很好的平衡
  • PowerMock –当您遇到Mockito无法解决的困难情况时(例如,模拟依赖静态方法的旧库,模拟私有或最终方法,或模拟对象实例化),Mockito的强大扩展。 我的建议是,在开始接触PowerMock时,始终对您的组件设计进行三重检查–通常,使用PowerMock的愿望表明测试“有异味”,并可能表明您应该改进组件设计或您的方式。具有外部依赖性的代码接口可以得到增强。 例如,除了模拟第三方库的静态构造方法之外,您是否可以不将此方法调用隐藏在自己的接口后面(遵循decoractor / adapter模式),这将简化模拟?
  • ConcurrentUnit –一个强大的实用程序框架,用于测试组件内并发的艰巨任务
  • 轻松制作 -一个用于创建“测试数据”构建器的小框架(其概念来自前述的“ 不断增长的面向对象的软件,由测试指导”)
  • junitparams –一个很好的框架,用于增强JUnits参数化测试(或如创建者所言–“不烂的参数化测试”)

  • 隔离测试中的类和组件。 单元测试应专注于测试小型工作单元 ,因此应具有最小的依赖关系(或应模拟依赖关系)
  • 创建覆盖整个代码所有路径的测试用例,而不仅仅是简单的路径
  • 创建测试复制边缘案例
  • 利用参数化测试的功能来促进快速发现数据驱动的测试用例

不要

  • 编写琐碎的测试只是为了增加单元测试的覆盖范围
  • 创建脆弱的测试,使您的代码发生丝毫变化,即如果您使用超过10行代码来设置模拟和期望,那么您可能做错了
  • 测试getter和setter,除非它们包含逻辑
  • 直接测试与基础操作系统(文件,网络等),数据存储或任何容器/服务器的任何交互。 在此测试级别上应该模拟这种交互

塞在一起

集成测试–持久层

目的 :考虑对您的持久性或DAO层进行单元测试,但在这里您要模拟外部资源提供的行为,而不是模拟此功能。

工具

  • 上面提到的所有单元测试工具以及…
  • 利用Spring的@ContextConfiguration来管理诸如EntityManager或MongoOperations之类的依赖关系的连接,以及利用AbstractTransactionalJUnit4SpringContextTests来管理具有明确定义的事务语义的测试的运行
  • 您选择的数据存储的嵌入式(内存中)版本,例如
    • H2 –出色的嵌入式SQL数据存储区,在99%的标准用例中,其行为类似于MySQL(尽管您的里程可能有所不同……)

  • 断言实体可以按您期望的那样持久。 我忘记了错误配置XToMany JPA批注的次数,这导致对子实体的级联操作不正确。
  • 旨在使测试执行时间保持在合理范围内。
  • 测试DAO /存储库界面上公开的所有公共方法
  • 创建允许加载预先罐装的测试数据的线束。 从Spring的AbstractTransactionalJUnit4SpringContextTests中考虑executeSqlScript()
  • 在每次测试结束时销毁(或删除)数据,以防止以前的测试数据影响结果。 如果您选择的测试框架不能保证执行测试的顺序,这一点尤其重要!

  • 单元测试的覆盖范围过于重复,即大多数业务逻辑将调用持久层来加载数据,进行处理,然后再次调用持久层以保存结果。 此级别的测试只需要关注负载并保存
  • 测试所有可能的数据排列
  • 将太多的操作链接在一起–应该由服务集成测试或端到端测试覆盖
即将第二部分...

我将尽快尝试发布第2部分,它将涵盖诸如服务级别集成测试,基于Web的测试和API测试之类的主题。 第3部分将介绍端到端(E2E)测试和BDD。


翻译自: https://www.javacodegeeks.com/2013/07/testing-web-based-spring-applications-in-2013-part-one.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值