文档章节

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

evexu
 evexu
发布于 09/16 21:09
字数 1361
阅读 6
收藏 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
粉丝 4
博文 17
码字总数 11728
作品 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
Groovy 1.8 正式版发行说明

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

红薯
2010/12/31
1K
8
Groovy 2.2 Beta2 发布,JVM 动态脚本语言

Groovy 2.2 Beta2 发布了,这是 Groovy 2.1.7 的 bug 修复版本。详情请看 Groovy 2.1.7 Groovy 2.2.0-beta-2 下载地址 download area Groovy是一种基于JVM的敏捷开发语言,它结合了Python、R...

oschina
2013/09/07
1K
7
测试框架--easyb

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

匿名
2008/12/04
1K
0
Groovy 1.8.3 和 1.9 Beta4 发布

Groovy 发布了 1.8.3 版本和 1.9 的第四个 beta 版,这是一个小bug修复版本。 Groovy是一种基于JVM的敏捷开发语言,它结合了Python、Ruby和Smalltalk的许多强大的特性。 Groovy 主要的特点包...

红薯
2011/10/13
473
2

没有更多内容

加载失败,请刷新页面

加载更多

web打印控件 LODOP的详细api

web打印控件 LODOP的详细api

wangxujun59
26分钟前
1
0
从一次小哥哥与小姐姐的转账开始, 浅谈分布式事务从理论到实践

分布式事务是个业界难题,在看分布式事务方案之前,先从单机数据库事务开始看起。 什么是事务 事务(Transaction)是数据库系统中一系列操作的一个逻辑单元,所有操作要么全部成功要么全部失...

中间件小哥
28分钟前
5
0
荣登Github日榜!微信最新开源MMKV

MMKV 开源当日即登Github Trending日榜,三日后荣登周榜。MMKV 在腾讯内部开源半年,得到公司内部团队的广泛应用和一致好评。 MMKV 是基于 mmap 内存映射的移动端通用 key-value 组件,底层序...

腾讯开源
37分钟前
2
0
前端取色工具:jcpicker

http://annystudio.com/software/colorpicker/#jcp-download

轻量级赤影
39分钟前
1
0
Swift - 将图片保存到相册

import Photos func loadImage(image:UIImage) { UIImageWriteToSavedPhotosAlbum(image, self, #selector(saveImage(image:didFinishSavingWithError:contextInfo:)), ni......

west_zll
46分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部