文档章节

单元测试之--groovy的DSL测试

evexu
 evexu
发布于 2018/09/16 21:09
字数 1361
阅读 16
收藏 1

如何写出更好的单元测试

作为一个大型电商后台业务系统,系统的稳定性和可用性有很高的要求。良好以及高覆盖的单元测试是其中重要的一环。在日常项目开发中时常会思考如何才能更加低成本,可读性高以及维护性高的单元测试方式。

目前负责的系统,作为一个衔接上下游的中间系统,有十分复杂的业务场景以及众多的RPC调用,通常一个域的系统单元测试就超过500个,所以在单元测试上从来没有停止过探索和优化。

RPC Mock

首先为了能够更好的完成RPC调用的mock,针对公司的RPC框架编写了一个对应的mock服务。 1、扩展SpringJUnitClassRunner,在createTest中初始化一个本地的RPC服务,同时执行了所有的RPC服务目标地址为本地 2、整合mockito实现对象的mock。mockito是java常用的mock框架,所以对于使用者来说机会是零成本。

BeanMock

Mock只是解决了RPC调用的问题,但是对于测试过程中很多的嵌套调用mock的场景,往往都是通过很复杂的反射方式实现。反射方式在实现上麻烦不说,最严重的就是反射设置了mock对象之后,在测试完成之后并没有将mock对象还原回真实的值。由于整个测试都是使用同一个spring上下文(通过spring注解可以实现每次都是新的上下文,但是影响测试执行效率),导致其他单元测试失败。并且这些单元测试失败的原因都是十分难排查的。

事实上一些其他的mock组件能够实现private的mock,甚至是静态对象的mock,比如power mock。 但基于整个团队二三十人都是使用mockito的情况下,转为使用另外一个mock组件,无言之间引入了新的使用以及维护成本。所以为了解决这个问题,基于spring的bean的特性,实现了Bean Mock,通过注解就能实现对嵌套对象的mock,十分简洁。详细介绍参见:BeanMock的使用介绍与说明

使用Groovy编写类DSL的单元测试

上面的两个Mock都是解决了单元测试过程中的mock问题,除了对象的mock之外,单元测试更多的工作是在测试数据的构造,场景的模拟以及最终执行结果的断言验证。这个时候groovy的语言特性以及其对java的无缝结合就派上用场。 同时参加日常项目的QA用例评审过程中,是对一个个业务场景的设计。这些测试用例可以看作特定的领域语言来描述特定的业务场景。

比如对于电商平台库存扣减的场景来说,从订单库存领域,描述一个典型的业务场景如下:

一个订单,购买两个sku。其中一个是A库存,需要3件;另外一个是B库存,需要2件。库存都占用成功。 执行订单库存扣减,验证结果:订单库存占用成功,占用明细有3个。占用明细1:占用数2 …

通过Groovy的语言特性,可以编写基于上面这个特定的领域语言,通过DSL的方式来进行单元测试,代码实例如下:

 @Test 
 void testSingleOrderJit() throws OspException { 
 	makeRequest { 
 		header { 
 			detailList { 
 				[invType: Inv.A ] 
 			} 
 		} 
 	}withOccupy OccupancyResult.success execute{ 
 		oimsService.allocateOccupancy(it) 
 	} verify{ 
 		validateHeader { 
 			[status:3, detailNum:1] 
 		} 
 		validateDetail { 
 			[occupancyQty:-10, isShortAlloc:2] 
 			} 
 		} 
 	}
}

从上面的代码看出,Groovy的语言特性在测试数据的构造以及断言上,相比java语言更为清晰与简洁。

示例中试图通过定义:

  1. makeRequest
  2. withInv
  3. withBrand
  4. withOccupancy

这样的领域名词帮助测试数据的模拟。比如在示例中就使用makeRequest创建了一个订单,有一个明细,明细是Inv.A的库存。通过withOccupancy来模拟这些库存都是能占用成功的。

通过定义execute,在execute中触发所要测试的业务方法

通过定义:

  1. verify
  2. verifyHeader
  3. verifyDetail

领域名词来帮助执行业务方法执行的结果验证。

上述的例子是一个很简单的DSL语言用法,希望通过逐渐完善领域的DSL,让单元测试(其实这个阶段在很多人看来属于功能测试的范畴)具有可描述的特性。更加能够表达单元测试的意图,从各种数据构造和测试验证的场景中抽离出来,专注于要验证的结果。

 

当然,这个并不能适用于所有的单元测试场景,应该结合实际的场景和测试目选择合适的工具。这里目的是为了提供一种思路作为参考

 

© 著作权归作者所有

共有 人打赏支持
evexu
粉丝 5
博文 17
码字总数 11782
作品 0
广州
程序员
私信 提问
groovy学习资料收藏

groovy学习资料收藏 Xstream Deserializable Vulnerablity And Groovy(CVE-2015-3253) Apache Groovy 2.4.6 发布 Groovy阅读小注 使用Groovy语言替代JUnit为Java程序编写单元测试 使用Gro...

d_watson
2016/03/16
80
0
测试框架--easyb

easyb 是基于Groovy的DSL实现的可适用于Java和Groovy的测试框架。它提供了对Ant和Maven的支持来执行stories测试。 它的目的就是: 让我们的单元测试跟接近于业务语言,为此他提供了三个关键字...

匿名
2008/12/04
1K
0
Groovy 即将加入 Apache 软件基金会

Groovy 项目负责人 Guillaume Laforge 于近日宣布 Groovy 将加入 Apache Software Foundation。 如果该提案被接受,Apache PMCs,负责管理 groovy 项目 更多内容请看这里:http://jaxenter...

s3051024
2015/03/09
3.9K
18
JVM 动态脚本语言--Groovy

Groovy 是一种基于 JVM 的敏捷开发语言,它结合了 Python、Ruby 和 Smalltalk 的许多强大的特性。 Groovy 主要的特点包括: 是一个基于Java 虚拟机的敏捷动态语言。 构建在强大的 Java 语言之...

匿名
2008/09/11
62.9K
3
Vert.x入坑须知(3)

随着Vert.x进化到3.5.0,本系列也迎来了新篇章。 CORS的新变化 对于CORS,搞Web开发(不论你是前端,还是后端)的同志应该不陌生,尤其是如今微服务盛行的时代,CORS更是最常用的配置项之一。...

胡键
2017/12/03
0
0

没有更多内容

加载失败,请刷新页面

加载更多

vue 对对象的属性进行修改时,不能渲染页面 vue.$set()

我在vue里的方法里给一个对象添加某个属性时,我console.log出来的是已经更改的object ,但是页面始终没有变化 原因如下: **受现代 JavaScript 的限制 (而且 Object.observe 也已经被废弃),...

Js_Mei
今天
2
0
开始看《Java学习笔记》

虽然书买了很久,但一直没看。这其中也写过一些Java程序,但都是基于IDE的帮助和对C#的理解来写的,感觉不踏实。 林信良的书写得蛮好的,能够帮助打好基础,看得出作者是比较用心的。 第1章概...

max佩恩
昨天
12
0
Redux 三大原则

1.单一数据源 在传统的MVC架构中,我们可以根据需要创建无数个Model,而Model之间可以互相监听、触发事件甚至循环或嵌套触发事件,这些在Redux中都是不被允许的。 因为在Redux的思想里,一个...

wenxingjun
昨天
8
0
跟我学Spring Cloud(Finchley版)-12-微服务容错三板斧

至此,我们已实现服务发现、负载均衡,同时,使用Feign也实现了良好的远程调用——我们的代码是可读、可维护的。理论上,我们现在已经能构建一个不错的分布式应用了,但微服务之间是通过网络...

周立_ITMuch
昨天
5
0
XML

学习目标  能够说出XML的作用  能够编写XML文档声明  能够编写符合语法的XML  能够通过DTD约束编写XML文档  能够通过Schema约束编写XML文档  能够通过Dom4j解析XML文档 第1章 xm...

stars永恒
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部