目标###

设计一个轻量级测试用例框架,接口测试编写者只需要编写测试用例相关的内容(入参及结果校验),不需要理会系统的实现,不需要写跟测试校验无关的内容。

思路###

测试用例分析####

一个用例由以下部分组成:

(1) 测试用例名称 ; (2) 接口名及URL/Path; (3) 接口入参; (4) 接口返回结果校验。

测试框架需要读取用例配置信息,根据指定接口及入参调用服务,并根据指定校验函数来对接口返回结果做检验,判断测试用例是否执行成功。

设计考量####

为了灵活调用不同接口,针对以上的配置,(2) 采用 http restful 的方式; (3) 采用 Map ; (4) 需要一套校验语法。这里暂时直接采用 groovy 脚本。

DEMO实现###

使用者需要做什么####

接口测试用例编写者只需要定义一个 TestCase 类即可。这个类含有如下信息:

(1) 待测试接口的 url : http://ip:7001 及 restful 路径 /xxx

(2) 带有 @Case 注解的方法。 里面返回一个 Map,

name: 测试用例名 ;

param: 入参map ;

check: 校验函数。 data 就是返回的顶层。

比如搜索测试用例类SearchTestCases:

  1. package cc.lovesq.study.testcase.qa
  2. import cc.lovesq.study.testcase.Case
  3. class SearchTestCases {
  4. def url = 'http://ip:7001'
  5. def path = '/searchApp/order/search'
  6. @Case
  7. def get() {
  8. return [
  9. 'name': 'testSearchOrderNo',
  10. 'param': ['shopId': 55, 'orderNo': 'E20180507200552032000001', 'source':'service-test'],
  11. 'check': { data ->
  12. data.list.each {
  13. order ->
  14. order.orderNo == 'E20180507200552032000001'
  15. }
  16. }
  17. ]
  18. }
  19. }

详情测试用例类

  1. package cc.lovesq.study.testcase.qa
  2. import cc.lovesq.study.testcase.Case
  3. class DetailTestCases {
  4. def url = 'http://ip:7001'
  5. def path = '/detailApp/orderInfo/byOrderNo'
  6. @Case
  7. def get() {
  8. return [
  9. 'name': 'testSingleOrderDetail',
  10. 'param': ['shopId': 55, 'orderNo': 'E20180507200552032000001', 'source':'service-test', 'bizGroup': 'trade'],
  11. 'check': { data ->
  12. data.mainOrderInfo.orderNo == 'E20180507200552032000001'
  13. }
  14. ]
  15. }
  16. }

框架基本实现####

通过指定的 TestCase 类,读取其用例配置信息,识别其中的用例配置,通过Http调用接口,然后回调指定的校验函数来校验结果。

  1. package cc.lovesq.study.testcase
  2. import groovyx.net.http.ContentType
  3. import groovyx.net.http.HTTPBuilder
  4. import org.slf4j.Logger
  5. import org.slf4j.LoggerFactory
  6. import static groovyx.net.http.Method.POST
  7. class CaseExecutor {
  8. static Logger log = LoggerFactory.getLogger(CaseExecutor.class)
  9. def invokeAllCases(testCase) {
  10. Object tc = testCase
  11. tc.getClass().getDeclaredMethods().findAll {
  12. // 识别测试用例: 带有 @Case
  13. it.getAnnotation(Case.class) != null
  14. }.each {
  15. it ->
  16. def caseInfo = it.invoke(tc, null)
  17. def result = exec(caseInfo['name'], tc.url, tc.path, caseInfo['param'], caseInfo['check'])
  18. println("case=${caseInfo['name']}, result=${result}")
  19. }
  20. }
  21. def exec(name, url, path, param, check) {
  22. def http = new HTTPBuilder(url)
  23. def result
  24. http.request(POST) {
  25. uri.path = path
  26. requestContentType = ContentType.JSON
  27. body = param
  28. response.success = { resp, json ->
  29. def data = json.data.data
  30. try {
  31. log.info("Enter Test Case : {}", name)
  32. check(data)
  33. result = "success"
  34. } catch (Throwable e) {
  35. result = "failed"
  36. } finally {
  37. log.info("Exit Test Case : {}", name)
  38. }
  39. }
  40. response.failure = { resp ->
  41. println "Unexpected error: ${resp.statusLine.statusCode} : ${resp.statusLine.reasonPhrase}"
  42. def errorInfo = """
  43. Call error: ${resp.statusLine.statusCode} : ${resp.statusLine.reasonPhrase}
  44. Name: ${name}
  45. Url: ${url}
  46. Path: ${path}
  47. Param: ${param}
  48. """
  49. log.warn(errorInfo)
  50. result = "failed"
  51. }
  52. }
  53. result
  54. }
  55. }

客户端运行测试用例集合:

  1. package cc.lovesq.study.testcase
  2. import cc.lovesq.study.testcase.qa.DetailTestCases
  3. import cc.lovesq.study.testcase.qa.SearchTestCases
  4. class ClientTest {
  5. def static main(args) {
  6. CaseExecutor caseExecutor = new CaseExecutor()
  7. caseExecutor.invokeAllCases(new SearchTestCases())
  8. caseExecutor.invokeAllCases(new DetailTestCases())
  9. }
  10. }

代码讲解###

  • 使用了HttpBuilder 类来发送HTTP请求。需要添加POM配置:
  1. <dependency>
  2. <groupId>org.codehaus.groovy.modules.http-builder</groupId>
  3. <artifactId>http-builder</artifactId>
  4. <version>0.6</version>
  5. </dependency>
  • 使用注解 @Case 来表示测试用例。注解可以用于标识一类对象。

  • 使用Groovy闭包来传递校验逻辑。闭包可以用来传递变化的逻辑。

自动加载用例集合###

实际应用中,往往不会直接 new 一个 XXXTestCases 对象,而是将这些对象标记为 Component 后,在应用启动时加载这些 TestCases,建立映射。只要对 CaseExecutor 做一些扩展即可。 如下代码所示:

  1. @Component("caseExecutor")
  2. class CaseExecutor implements ApplicationContextAware {
  3. static Logger log = LoggerFactory.getLogger(CaseExecutor.class)
  4. ApplicationContext context
  5. def casePathMap = [:]
  6. @PostConstruct
  7. def init() {
  8. Map<String, Object> components = context.getBeansWithAnnotation(Component.class)
  9. log.info("{}", components)
  10. components.each {
  11. name, comp ->
  12. try {
  13. def property = comp.metaClass.getProperty(comp, 'path')
  14. if ( property) {
  15. casePathMap[property] = comp
  16. }
  17. } catch (e) {
  18. log.warn("not having restPath, omit")
  19. }
  20. }
  21. }
  22. // other codes
  23. @Override
  24. void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  25. this.context = applicationContext
  26. }
  27. }

小结###

本文讲解了一种基于Groovy+HttpRestful的超轻量级的接口测试用例配置的设计方案及DEMO实现。基于这种方法,可以配置化地快速增加指定服务接口的测试用例集合,而不需要额外编写冗余的测试代码。

基于Groovy+HttpRestful的超轻量级的接口测试用例配置的设计方案及DEMO实现的更多相关文章

  1. Yii2 基于RESTful架构的 advanced版API接口开发 配置、实现、测试 (转)

    环境配置: 开启服务器伪静态 本处以apache为例,查看apache的conf目录下httpd.conf,找到下面的代码 LoadModule rewrite_module modules/mod_ ...

  2. Yii2 基于RESTful架构的 advanced版API接口开发 配置、实现、测试

    环境配置: 开启服务器伪静态 本处以apache为例,查看apache的conf目录下httpd.conf,找到下面的代码 LoadModule rewrite_module modules/mod_ ...

  3. Yii2 基于RESTful架构的 advanced版API接口开发 配置、实现、测试【转】

    环境配置: 开启服务器伪静态 本处以apache为例,查看apache的conf目录下httpd.conf,找到下面的代码 LoadModule rewrite_module modules/mod_ ...

  4. 使用Groovy+Spock构建可配置的订单搜索接口测试用例集

    概述 测试是软件成功上线的安全网.基本的测试包含单元测试.接口测试.在 "使用Groovy+Spock轻松写出更简洁的单测" 一文中已经讨论了使用GroovySpock编写简洁的单 ...

  5. API接口开发 配置、实现、测试

    Yii2 基于RESTful架构的 advanced版API接口开发 配置.实现.测试 环境配置: 开启服务器伪静态 本处以apache为例,查看apache的conf目录下httpd.conf,找到 ...

  6. 基于领域驱动设计(DDD)超轻量级快速开发架构

    smartadmin.core.urf 这个项目是基于asp.net core 3.1(最新)基础上参照领域驱动设计(DDD)的理念,并参考目前最为了流行的abp架构开发的一套轻量级的快速开发web ...

  7. 基于领域驱动设计(DDD)超轻量级快速开发架构(二)动态linq查询的实现方式

    -之动态查询,查询逻辑封装复用 基于领域驱动设计(DDD)超轻量级快速开发架构详细介绍请看 https://www.cnblogs.com/neozhu/p/13174234.html 需求 配合Ea ...

  8. 分享自己的超轻量级高性能ORM数据访问框架Deft

    Deft 简介 Deft是一个超轻量级高性能O/R mapping数据访问框架,简单易用,几分钟即可上手. Deft包含如下但不限于此的特点: 1.按照Transact-SQL的语法语义风格来设计,只 ...

  9. Groovy元编程应用之自动生成订单搜索接口测试用例集

    背景 在 "Groovy元编程简明教程" 一文中,简明地介绍了 Groovy 元编程的特性. 那么,元编程可以应用哪些场合呢?元编程通常可以用来自动生成一些相似的模板代码. 在 & ...

随机推荐

  1. Houdini技术体系大纲

    Houdini for UE4 Pipeline的系列教程,前言等想好再写吧

  2. IDEA下搭建Shiro-web环境,总是报BasicDataSource,classnotfound;问题解决

    进入报错跟踪,查看加载的classloader中没有dbcp相关jar包 猜测结果是,jar没有被加载,但是maven引用没错,而且也能找到对应的class 后来又查看IDEA配置中,相关jar也引入 ...

  3. jstat命令详解

    Jstat是JDK自带的一个轻量级小工具.全称“Java Virtual Machine statistics monitoring tool”,它位于java的bin目录下,主要利用JVM内建的指令 ...

  4. 八、Sql Server 基础培训《进度8-查询多种写法》(实际操作)

    知识点: 假设学生表.班级表.年级表 学生表(student) 内码 学生姓名 班级内码 001 张三 1002 002 李四 1002 003 王五 1003 004 钱六 1001 班级表(cla ...

  5. An error occurred. Sorry, the page you are looking for is currently unavailable. Please try again later.

    刚装完 PHP.Nginx,准备跑下 phpMyAdmin 程序,结果报以下错误: An error occurred. Sorry, the page you are looking for is ...

  6. [原] MyBatis 整理

    花了一上午的时间,先整理一个脑图.

  7. mysql limit 性能问题分析

    问题重现 // todo 参考文章: MySQL 单表分页 Limit 性能优化 Scalable MySQL: Avoid offset for large tables 证明为什么用limit时, ...

  8. VS开发入门一:VS常用快捷键大全,工欲善其事必先利其器 只看标红的吧

    1.快速using(这个的快捷键是ctrl+.)2.快速回到之前编辑的代码页面现在的项目动不动就几十个代码页面,经常需要在几个页面之间跳来跳去,这时就需要这两个快捷键:CTRL + - 向后定位,回到 ...

  9. HTML、CSS知识点,面试开发都会需要--No.5 文章段落

    No.5 文章段落 1.文字属性 文字属性包含font-*和text-*两类. 2.基于font的属性 (1)font-family:字体属性,多个字体之前用逗号隔开.如果第一个字体没找到,则依次找后 ...

  10. Emmet.vim 教程

    Emmet.vim 教程 May 5, 2012 目录 1 下载 Emmet.vim 2 安装 Emmet.vim 3 使用 Emmet.vim 4 余话 Emmet 项目原先叫 Zen Coding ...