文档章节

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

evexu
 evexu
发布于 09/16 21:09
字数 1361
阅读 9
收藏 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
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
测试框架--easyb

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

匿名
2008/12/04
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

什么是自然语言处理技术

自然语言处理(NLP)是计算机科学,人工智能,语言学关注计算机和人类(自然)语言之间的相互作用的领域。自然语言处理是计算机科学领域与人工智能领域中的一个重要方向。它研究能实现人与计...

本宫没空2
2分钟前
0
0
移动端关闭虚拟键盘

$("#select_date").focus(function(){ document.activeElement.blur(); });

niuhongxia
2分钟前
0
0
Ubuntu18.04安装RabbitMQ(正确安装)

1、安装erlang 由于rabbitMq需要erlang语言的支持,在安装rabbitMq之前需要安装erlang sudo apt-get install erlang-nox 2、安装Rabbitmq 更新源 sudo apt-get update 安装 sudo apt-get ins...

hansonwong
11分钟前
0
0
如何在以太坊开发发行自己的ERC-20数字货币

今天我将向你展示如何在以太坊区块链上开发你自己的加密货币并将其出售!我将向你展示如何使用以太坊智能合约逐步创建自己的ERC-20代币和众筹销售,如何测试智能合约,如何将智能合约部署到以...

geek12345
12分钟前
0
0
Vlock用于有多个用户访问控制台的共享 Linux 系统

当你在共享的系统上工作时,你可能不希望其他用户偷窥你的控制台中看你在做什么。如果是这样,我知道有个简单的技巧来锁定自己的会话,同时仍然允许其他用户在其他虚拟控制台上使用该系统。 ...

linuxprobe16
13分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部