一、背景描述

在版本开发中,时间段大致的划分为:需求,开发,测试;

  • 需求阶段:理解需求做好接口设计;
  • 开发阶段:完成功能开发和对接;
  • 测试上线:自测,提测,修复,上线;

实际上开发阶段两个核心的工作,开发和流程自测,自测的根本目的是为自己提前解决可能出现的问题;如果缺少自测和提测两个关键步骤,那么问题就会被传递给更多的用户,产生更多的资源消耗;

自测是于开发而言,提测是对专业的测试人员而言,如果尽可能在自测阶段就发现问题,并解决问题,那么一个问题就不会影响到团队协作上的更多人员,如果一个简单的问题上升到团队协作层面,很可能会导致问题本身被放大

工欲善其事必先利其器,开发如果要做好自测流程,学会使用工具提高效率是十分关键的,自测的关键在于发现问题和解决问题,所以选择好用和高效的工具可以极大的降低自测的时间消耗。

下面围绕几个自己开发过程中常用的测试工具和手段,做简单的总结,不在于对比方式的好坏,存在即合理,在不同场景中对合理手段的选择,快速解决问题才是根本目的

二、PostMan工具

PostMan很常用的接口测试工具,开发过程中快速测试接口,功能强大并且简单方便,不但可以单个接口测试,也可以对接口分块管理批量运行:

整体来说工具比较好用,适应于开发阶段的接口快速测试,或者在解决问题的过程中单个接口的测试,同时对测试参数有存储和记忆能力,这也是受欢迎的一大原因。

但是该工具不适应于复杂的流程化测试,例如需要根据上次接口的响应报文做分别处理,或者下次请求需要填充某个接口响应的数据。

三、Swagger文档

Swagger管理接口文档,是当下服务中很常用的组件,通过对接口和对象的简单注释,快速生成接口描述信息,并且可以对接口发送请求,协助调试,该文档在前后端联调中极大的提高效率。

接口文档的管理本身是一件麻烦事,接口通常会根据业务不断的调整,如果单独维护一份接口文档,需要付出很多时间成本,并且容易出问题,利用swagger就可以避免这个问题。

借助swagger注解标记对象

@TableName("jt_activity")
@ApiModel(value="活动PO对象", description="活动信息表【jt_activity】")
public class Activity {@ApiModelProperty(value = "主键ID")@TableId(type = IdType.AUTO)private Integer id;@ApiModelProperty(value = "活动主题")private String activityTitle;@ApiModelProperty(value = "联系号码")private String contactPhone;@ApiModelProperty(value = "1线上、2线下")private Integer isOnline;@ApiModelProperty(value = "举办地址")private String address;@ApiModelProperty(value = "主办单位")private String organizer;@ApiModelProperty(value = "创建时间")private Date createTime;
}

借助swagger注解标记接口

@Api(tags = "活动主体接口")
@RestController
public class ActivityWeb {@Resourceprivate ActivityService activityService ;@ApiOperation("新增活动")@PostMapping("/activity")public Integer save (@RequestBody Activity activity){activityService.save(activity) ;return activity.getId() ;}@ApiOperation("主键查询")@GetMapping("/activity/{id}")public Activity getById (@PathVariable("id") Integer id){return activityService.getById(id) ;}@ApiOperation("修改活动")@PutMapping("/activity")public Boolean updateById (@RequestBody Activity activity){return activityService.updateById(activity) ;}
}

通常来说,基于swagger注解标记接口类和方法上的入参和关键返参对象即可,这样可以避免再单独维护接口文档。

Swagger接口文档在开发的过程中更多是扮演文档的角色,真正使用swagger去调试的接口也常是一些增删改查的简单接口,这个工具也同样不适应于复杂流程的测试。

四、TestRestTemplate类

SpringBoot测试包中集成的测试API,需要依赖测试包,可以访问控制层接口,非常方便的完成交互过程:

Jar包依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency>

使用案例

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ActivityTest01 {protected static Logger logger = LoggerFactory.getLogger(ActivityTest01.class) ;@Resourceprivate TestRestTemplate restTemplate;private Activity activity = null ;@Beforepublic void before (){activity = restTemplate.getForObject("/activity/{id}", Activity.class,1);logger.info("\n"+JSONUtil.toJsonPrettyStr(activity));}@Testpublic void updateById (){if (activity != null){activity.setCreateTime(new Date());activity.setOrganizer("One商家");restTemplate.put("/activity",activity);}}@Afterpublic void after (){activity = restTemplate.getForObject("/activity/{id}", Activity.class,1);logger.info("\n"+JSONUtil.toJsonPrettyStr(activity));activity = null ;}
}

在TestRestTemplate源码中可以发现,基于RestTemplate做封装,很多功能的实现都是调用RestTemplate方法。

用写代码的方式去实现接口测试,灵活度非常高,可以根据流程做定制开发,很适应于中等复杂的场景测试,这里为什么这样描述,下面对比Http请求再细说。

五、Http请求模式

通过模拟接口的Http请求实现的方式,目前来说个人感觉灵活的最高的方式,先看简单的案例:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class ActivityTest03 {protected static Logger logger = LoggerFactory.getLogger(ActivityTest03.class) ;protected static String REQ_URL = "服务地址+端口";@Testpublic void testHttp (){// 查询String getRes = HttpUtil.get(REQ_URL+"activity/1");logger.info("\n {} ",JSONUtil.toJsonPrettyStr(getRes));Activity activity = JSONUtil.toBean(getRes, Activity.class) ;// 新增activity.setId(null);activity.setOrganizer("Http商家");String saveRes = HttpUtil.post(REQ_URL+"/activity",JSONUtil.toJsonStr(activity));logger.info("\n {} ",saveRes);// 更新activity.setId(Integer.parseInt(saveRes));activity.setOrganizer("Put商家");String putRes = HttpRequest.put(REQ_URL+"/activity").body(JSONUtil.toJsonStr(activity)).execute().body();logger.info("\n {} ",putRes);}
}

这种方式对于复杂的业务流程来说非常好用,当然这里不排除个人习惯,在测试复杂流程的时候,一个简单方案:

  • 用户信息:模拟http中token数据;
  • 业务流程:通过数据获取包装参数模型;
  • 独立服务管理,模拟并发场景;
  • 根据执行过程生成分析数据结果;

对于复杂业务流程的测试,每个节点的模拟都具有一定的难度,通常在完整的流程中涉及到的服务和库表都是多个,并且请求链路复杂,基于一个灵活的自动化流程,去测试完整的链路,可以对效率有极大的提升。

六、Service层测试

针对服务层的测试手段,其本意在于业务实现的逻辑测试:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class ActivityTest04 {protected static Logger logger = LoggerFactory.getLogger(ActivityTest04.class) ;@Autowiredprivate ActivityService activityService ;@Testpublic void testService (){// 查询Activity activity = activityService.getById(1) ;// 新增activity.setId(null);activityService.save(activity) ;// 修改activity.setOrganizer("Ser商家");activityService.updateById(activity) ;// 删除activityService.removeById(activity.getId()) ;}
}

该测试在实际的开发过程也并不常用,偶尔在于某个业务方法实现难度很大,用来针对性测试。

七、MockMvc方式

MockMvc同样是SpringBoot集成测试包提供的测试方式,通过对象的模拟,验证接口是否符合预期:

@AutoConfigureMockMvc
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
public class ActivityTest02 {protected static Logger logger = LoggerFactory.getLogger(ActivityTest02.class) ;@Resourceprivate MockMvc mockMvc ;private Activity activity = null ;@Beforepublic void before () throws Exception {ResultActions resultAction = mockMvc.perform(MockMvcRequestBuilders.get("/activity/{id}",1)) ;MvcResult mvcResult = resultAction.andReturn() ;String result = mvcResult.getResponse().getContentAsString();activity = JSONUtil.toBean(result,Activity.class) ;}@Testpublic void updateById () throws Exception {activity.setId(null);activity.setCreateTime(new Date());activity.setOrganizer("One商家");ResultActions resultAction = mockMvc.perform(MockMvcRequestBuilders.post("/activity").contentType(MediaType.APPLICATION_JSON).content(JSONUtil.toJsonStr(activity))) ;MvcResult mvcResult = resultAction.andReturn() ;String result = mvcResult.getResponse().getContentAsString();activity.setId(Integer.parseInt(result));logger.info("result : {} ",result);}@Afterpublic void after () throws Exception {activity.setCreateTime(new Date());activity.setOrganizer("Update商家");ResultActions resultAction = mockMvc.perform(MockMvcRequestBuilders.put("/activity").contentType(MediaType.APPLICATION_JSON).content(JSONUtil.toJsonStr(activity))) ;MvcResult mvcResult = resultAction.andReturn() ;String result = mvcResult.getResponse().getContentAsString();logger.info("result : {} ",result);}
}

对于这种Mock类型的测试,非常专业,通常个人使用极少,暂时没有Get到其精髓思想。

八、Mockito测试

Mock属于非常专业和标准的测试手段,需要依赖powermock包:

<dependency><groupId>org.powermock</groupId><artifactId>powermock-core</artifactId><scope>test</scope>
</dependency>
<dependency><groupId>org.powermock</groupId><artifactId>powermock-api-mockito2</artifactId><scope>test</scope>
</dependency>
<dependency><groupId>org.powermock</groupId><artifactId>powermock-module-junit4</artifactId><scope>test</scope>
</dependency>

简单使用案例:

@RunWith(PowerMockRunner.class)
@SpringBootTest
public class ActivityTest05 {@Testpublic void testMock (){Set mockSet = PowerMockito.mock(Set.class);PowerMockito.when(mockSet.size()).thenReturn(10);int actual = mockSet.size();int expected = 15 ;Assert.assertEquals("返回值不符合预期",expected, actual);}@Testpublic void testTitle (){String expectTitle = "Mock主题" ;Activity activity = PowerMockito.mock(Activity.class);PowerMockito.when(activity.getMockTitle()).thenReturn(expectTitle);String actualTitle = activity.getMockTitle();Assert.assertNotEquals("主题相符", expectTitle, actualTitle);}
}

可以通过Mock方式,快速模拟出复杂的对象结构,以便构建测试方法,由于使用很少,同样个人暂时没Get到点。

九、源代码地址

GitHub·地址
https://github.com/cicadasmile/middle-ware-parent
GitEE·地址
https://gitee.com/cicadasmile/middle-ware-parent

阅读标签

【Java基础】【设计模式】【结构与算法】【Linux系统】【数据库】

【分布式架构】【微服务】【大数据组件】【SpringBoot进阶】【Spring&Boot基础】

【数据分析】【技术导图】【 职场】

SpringBoot2 集成测试组件,七种测试手段对比相关推荐

  1. 常见七种排序算法对比(超全!!!)

    文章目录 一, 直接插入排序 二,希尔排序 三.选择排序 四,堆排序 五,冒泡排序 六,快速排序 如何优化快排呢? 三数取中法优化快排 七,归并排序 怎么判断是不是稳定的排序呢? 如果当前这个序列,在 ...

  2. gis差值分析_arcgis中七种插值方法的对比分析

    1 地形转栅格工具属于一种插值方法,专门用于创建符合真实地表的数字高程模型 (DEM).该方法基于由 Michael Hutchinson(1988.1989.1996.2000.2011)开发的 A ...

  3. 面向SecDevOps七种武器

    如果数字世界是一个江湖,技术人员则是自各门派侠士,例如: 拥有一双慧眼洞察一切蛛丝马迹的SecOps 手持各种脚本掌握线上大权的Net/Site Ops 以敲击机械键盘比拼手速为乐的DevOps 纵观 ...

  4. 面向SecDevOps七种武器 1

    如果数字世界是一个江湖,技术人员则是自各门派侠士,例如: 拥有一双慧眼洞察一切蛛丝马迹的SecOps 手持各种脚本掌握线上大权的Net/Site Ops 以敲击机械键盘比拼手速为乐的DevOps 纵观 ...

  5. 自动化测试(二)01-前端测试分为单元测试、集成测试和E2E测试 测试工具对比-适合TDD或 BDD、断言、异步测试 测试工具的类型

    自动化测试(二)01-前端测试分为单元测试.集成测试和E2E测试 & 测试工具对比-适合TDD或 BDD.断言.异步测试 & 测试工具的类型 前端自动化测试 测试是一个庞大的主题,包括 ...

  6. 基于Virtex-6 FPGA的三种串行通信协议测试及对比

    在高性能雷达信号处理机研制中,高速串行总线正逐步取代并行总线.业界广泛使用的Xilinx公司Virtex-6系列FPGA支持多种高速串行通信协议,本文针对其中较为常用的Aurora 8B/10B和PC ...

  7. 让 Python 代码更易维护的七种武器——代码风格(pylint、Flake8、Isort、Autopep8、Yapf、Black)测试覆盖率(Coverage)CI(JK)...

    让 Python 代码更易维护的七种武器 2018/09/29 · 基础知识 · 武器 原文出处: Jeff Triplett   译文出处:linux中国-Hank Chow    检查你的代码的质 ...

  8. Vue.js 定义组件模板的七种方式

    转载自  Vue.js 定义组件模板的七种方式 在 Vue 中定义一个组件模板,至少有七种不同的方式(或许还有其它我不知道的方式): 字符串 模板字面量 x-template 内联模板 render ...

  9. 第十二期:七种优秀的浏览器兼容性测试工具

    本文向您介绍目前最为流行的.面向开发人员的七大浏览器兼容性测试工具. 作者:陈峻 在许多谈及网站或Web应用开发的场合,开发人员最为关心的莫过于跨浏览器的兼容性问题.如您所知,诸如:计划.设计.测试等 ...

最新文章

  1. c语言输入数字变成星期几,C语言程序设计: 输入年月日 然后输出是星期几
  2. android控件---自定义带文本的ImageButton
  3. asyncio协程与并发
  4. 我是不是在浪费生命?
  5. 华为悬红“奥林帕斯奖”,促进数据产业基础技术研究与生态建设
  6. 《信息存储与管理(第二版):数字信息的存储、管理和保护》—— 2.6 磁盘驱动部件...
  7. 邮箱可以群发邮件吗?邮件群发怎么发?推荐邮箱邮件群发平台
  8. 文本对比工具哪些好用?竟然有在线的。真香。
  9. 1-7华为HCNA认证eNSP基础B
  10. 陈丹琦组最新力作:仅需dropout两次的对比学习框架
  11. QThread 线程终止
  12. 【3D音效增强神器】Boom 3D for Mac中文版 v1.2.2
  13. 高级算法日记9:图(2)
  14. Java最新学习笔记(2020版)丨基于JKD1.8
  15. 直播回顾|论道原生:云原生时代的中间件
  16. 1055 集体照 Python实现
  17. 基于freemarker ,xdocreport生成word,pdf
  18. ECIF OCRM ACRM关系
  19. ES6(ECMAScript6)学习笔记
  20. 【学习笔记】嵌入式三级

热门文章

  1. css毛玻璃效果白边_使用css模拟vista毛玻璃效果
  2. hdl四位二进制计数器_四位二进制加法计数器
  3. KVM虚拟机搭建增量镜像(一个基本镜像拷贝成无数多个子镜像)
  4. 从零开始学PowerShell(7)编写一个函数体
  5. Linux chroot命令
  6. 7. OD-破解收费版限制天数的软件
  7. Logstash 基础入门
  8. 设计模式之代理模式,学习笔记
  9. [网络流24题]圆桌问题
  10. JavaEE实战班第19天