在每个系统上线正式发布之前,开发同事对其中功能点进行自测,测试同事根据前期设计的测试用例进行功能测试的都是保障系统可靠稳定运行的重要前提。但是,系统上线后故障还偶有发生,那么如何才能将系统代码质量提高一个档次做到上线后0故障的目标呢?我想这个问题一直是许多研发同学和测试同学共同追求的一个目标,但光靠代码review、简单的自测和功能测试用例覆盖还是不够,需要从代码覆盖率(包括语句覆盖率、分支覆盖率和路径覆盖率等)的角度来解决。因此,本文从解决问题的根本原因出发介绍以Spring Boot工程的自动化单元测试用例结合Cobetura插件来实现定时跑测试任务并生成测试报告。

01

代码质量与单元测试

追求代码质量是一个优秀程序员对自我的要求。我们写一段代码、一个方法和一个类,不仅仅说完成了编码,保证代码能正常得跑起来就行了,而且也必须使得代码是优雅和干净的。一般来说正常的情况大家都能考虑到,比较关键和重要的是,我们在写代码时除了能够执行正常业务逻辑以外,还要能考虑和覆盖到各种不同的异常情况。我想在编码时候,考虑正常和异常情况的时间分配比例应该是30%:70%。

从主观上来说,代码质量一般是跟程序员的专业技能熟练度,比如编程语言(C++/Java/go等)、技术框架(Spring/Dubbo/Spring Cloud/Spring Boot等)、设计模式(工厂/抽象/代理模式等),成正比的。但是,对于极为优秀的程序员来说即使能够尽可能地确保自己的千行代码没有缺陷,却不一定能够保证几万行都没有任何缺陷。所以,我们需要借鉴其他的方法来提高自己的代码质量,尽可能少地让潜在的问题暴露在生产环境上。

增加功能测试用例和接口单元测试都是能够提高代码质量的方式,各有优劣。本文从编程者的角度出发,更加注重的是代码覆盖测试,毕竟只有写代码的人才能更容易地把控代码中的业务逻辑,能够更好的编写单元测试用例以覆盖正常和异常的业务场景。

在做单元接口测试时,代码覆盖率常常是被拿来作为衡量测试好坏的指标,甚至,用代码覆盖率来考核测试任务完成情况。通常来说,我们会关注方法覆盖、语句覆盖、条件覆盖和分支覆盖这几种度量方式。

02

Spring Boot工程的代码单元测试

本文第一节主要都是讲了理论,相对比较枯燥。下面这一节将从实践的角度,来一步一步向大家展示如何在Spring Boot工程中对业务代码写单元测试用例。

版本环境

Spring Boot 1.4.1.RELEASE、JDK 1.8

Spring Boot工程引入单元测试

在Spring Boot工程中引入单元测试比较简单,只需要简单地在pom文件中引入依赖如下:

在工程中引入spring-boot-starter-test后,就会有如下几个库:

(a)JUnit:Java语言的单元测试框架;

(b)Spring Test & Spring Boot Test:为Spring Boot程序提供集成测试的工具;

(c)AssertJ: 一种断言库;

(d)Hamcrest:也是一种断言库,不过更新频度较慢;

(e)Mockito :Java程序Mock测试的框架;

(f)JsonPath :Xpath在Json中的应用库;

(g)JSONassert:Json的断言库;

spring-boot-starter-test的pom依赖图如下:

工程中Service/Dao的单元测试

对于Spring Boot工程中的Service/Dao层的类来说,创建其单元测试方法比较简单,直接手动创建即可。

  1. @SpringBootTest(classes = OpHuaweiAgentApplication.class)

  2. @Slf4j

  3. public class VmServiceTest {

  4.    private ObjectMapper mapper = new ObjectMapper();

  5.    private static final String JSON_CREATE_VM_REQUEST = "/vm/createVmReq.json";

  6.    @Autowired

  7.    private VmService vmService;

  8.    @Before

  9.    public void setUp() throws Exception {

  10.        //测试用例数据准备

  11.        //code here

  12.    }

  13.    @Test

  14.    public void create() throws Exception {

  15.        String createBody = getResource(JSON_CREATE_VM_REQUEST);

  16.        JSONObject body = JSONObject.parseObject(createBody);

  17.        HwTokenWrapper token = getDomainToken();

  18.        String projectId = token.getToken().getProject().getId();

  19.        CreateJobRespDto respDto = vmService.create(token.getId(), projectId, body);

  20.        assertTrue(null != respDto.getJobId());

  21.        log.debug("create vm job 创建成功,jobId:{}", respDto);

  22.    }

  23.    @After

  24.    public void cleanUp() throws Exception(){

  25.        //测试数据清理

  26.        //code here

  27.     }

  28. }

如上面的对Service层的单元测试用例代码可见,在带有@Before注解的方法setUp中完成对测试用例的数据准备,可以提前在测试环境数据库中插入测试用例所需依赖的测试局数据。在@Test注解的方法—create是单元测试真正执行的方法,示例中使用提前组织好的创建主机规格的Json数据作为参数调用被测试的Service层的VmService方法,执行创建主机的验证。同时使用断言机制,来判断返回结果是否跟预期的一致。其中,准备好的Json数据放在Spring Boot工程src/test/resources下面。最后在,@After注解的方法cleanUp下执行提前插入数据的回滚和清理。

工程中Controller Api的单元测试

对Service/Dao层的类进行接口单元测试还是比较简便的。然而,一般的Spring Boot工程都需要对外部提供Api接口,因此有必要对Controller层进行单元测试以保证控制器执行的业务逻辑正确,这时候就得用到MockMvc了。使用MockMvc可以使得开发或者测试不必再借助postman这种Http调试工具进行手动测试,既提高测试的效率,也能够反复跑单元测试用例来进行回归验证。

Spring Test框架中的MockMvc实现了对Http请求的模拟,能够直接通过网络的形式,转换到Controller层的Api调用,这样在提高测试效率的同时可以不依赖外部环境。

  1. @RunWith(SpringJUnit4ClassRunner.class)

  2. @SpringBootTest(classes = OpHuaweiAgentApplication.class)

  3. @WebAppConfiguration

  4. @Slf4j

  5. public   class OrderManageControllerTest extends AbstractTest {

  6.    //此处API URL为示例代码

  7.    public static final String   GENERATE_ORDERID_API_URL = "/rest/xxxxxxxxx";

  8.    //此处为鉴权的Json测试数据

  9.    private static final String   JSON_AUTH_TOKEN_REQ = "/api/order/authTokenReq.json";

  10.    @Autowired

  11.    private WebApplicationContext context;

  12.    private MockMvc mvc;

  13.    @Before

  14.    public void setUp() {

  15.        //测试用例数据准备

  16.        //code here

  17.        this.mvc =   MockMvcBuilders.webAppContextSetup(this.context).build();

  18.    }

  19.    @Test

  20.    public void generateOrderIdTest() throws   Exception {

  21.        JSONObject jsonObject = JSONObject.parseObject(getResource(JSON_AUTH_TOKEN_REQ));

  22.        MockHttpServletRequestBuilder builder   =                post(GENERATE_ORDERID_API_URL).

  23.        header("X-Auth-Token",   jsonObject.getString("token"));

  24.        MvcResult result =   mvc.perform(builder).andReturn();

  25.        assertEquals(HttpStatus.OK.value(),   result.getResponse().getStatus());

  26.    }

  27.    @After

  28.    public void cleanUp() throws   Exception(){

  29.         //测试数据清理

  30.         //code here

  31.    }

  32. }

从上面对Controller层Api接口的单元测试示例代码可见,在带有@Before注解的setUp方法中,通过MockMvcBuilders工具类使用注入的WebApplicationContext上下文对象创建MockMvc对象。这里,MockMvc对象提供一组工具函数用来执行assert判断,都是针对web请求的判断。这组工具的使用方式是函数的链式调用,允许程序员将多个测试用例链接在一起,并进行多个判断。在带有@Test注解的generateOrderIdTest测试方法中,先加载提前准备好的鉴权请求JsonObject对象,然后MockMvc对象执行相应的post请求,其中参数为带有Header头的MockHttpServletRequestBuilder对象。最后,通过assertEquals断言机制来确认接口返回是否为Http响应的正确编码(200)。如同之前的一样,@After注解的方法cleanUp下执行提前插入数据的回滚和清理。

03

Spring Boot工程集成Cobetura插件

通过上面的内容,可以在Spring Boot工程中完成对Controller/Service/Dao层的添加单元测试用例,但仅限于此只能通过单元测试用例的结果(是否跑成功)来判断用例正确与否,而无法来判断测试的其他度量指标,比如本文前面提到的方法覆盖、语句覆盖、条件覆盖和分支覆盖等。因此,这节通过引入第三方组件—Cobertura来完成这一目标。

Cobertura 是一种开源的代码覆盖率检测工具,它通过检测基本的代码,并观察在测试包运行时执行了哪些代码和没有执行哪些代码,并最终以html或者xml的格式来呈现最终测试的度量指标结果(比如分支覆盖率和代码行覆盖率)。

Spring Boot工程的pom文件中添加Cobertura插件

在Spring Boot工程的pom文件中添加Cobertuar插件的配置如下:

  1. <build>

  2. <plugins>

  3.        <plugin>

  4.            <groupId>org.springframework.boot</groupId>

  5.            <artifactId>spring-boot-maven-plugin</artifactId>

  6.        </plugin>

  7.        <plugin>

  8.            <groupId>org.codehaus.mojo</groupId>

  9.            <artifactId>cobertura-maven-plugin</artifactId>

  10.            <version>2.7</version>

  11.            <configuration>

  12.                <formats>

  13.                    <!-- The XML report (in target/site/cobertura/coverage.xml)

  14.                         is useful for uploading to Coveralls.

  15.                     -->

  16.                    <format>xml</format>

  17.                    <format>html</format>

  18.                </formats>

  19.                <maxmem>256m</maxmem>

  20.                <instrumentation>

  21.                 <excludes>

  22.                  <exclude>com/alertavert/**/*Configuration.class</exclude>

  23.                 <exclude>com/alertavert/**/*Application.class</exclude>

  24.                </excludes>

  25.                </instrumentation>

  26.                <check>

  27.                    <totalLineRate>70</totalLineRate>

  28.                </check>

  29.         </configuration>

  30.        </plugin>

  31.        <plugin>

  32.            <groupId>org.eluder.coveralls</groupId>

  33.            <artifactId>coveralls-maven-plugin</artifactId>

  34.            <version>3.0.1</version>

  35.        </plugin>

  36.    </plugins>

  37. </build>

运行Coberuta插件生成测试报告

在Spring Boot工程目录下执行以下maven命令—“mvn cobertura:cobertura”,执行完后会在target目录里找到site目录,用浏览器打开里面的index.html,这就是测试用例执行完后cobertura-maven-plugin得出的覆盖率报告。如图下所示:

04

Cobertura与自动化构建工具Jenkins的集成

仅在本地对Spring Boot工程执行Cobertura的maven命令,并不能很好的实现自动持续集成的目标。这一节主要将介绍如何在Jenkins工具中一步步集成Cobertura插件并完成Spring Boot工程的代码覆盖率测试报告输出。

1、首先需要在Jenkins工具上完成Cobertura插件的安装。

2、配置jenkins工具,修改maven的执行命令,这里主要是添加cobertura执行命令clean cobertura:cobertura package。

3、在Add post build action这个配置项中选择如下Publish Cobertura Coverage Report。

4、这一步中需要选择一个配置项,该配置项目是最终cobertura生成xml/html report的路径,在示例中的路径为**/target/site/cobertura/coverage.xml。

5、最后,重新build该项目,即可在项目中看到本工程代码覆盖率的测试用例报告了。

05

总结

本文从代码质量与单元测试用例方面切入,先介绍了如何在Spring Boot工程中完成各层(Controller Api/Service/Dao层)的接口单元白盒测试,随后介绍了如何在Spring Boot工程中集成Cobertura插件,并利用Jenkins工具进行自动化持续集成以产生代码覆盖率的测试报告。限于笔者的才疏学浅,对本文内容可能还有理解不到位的地方,如有阐述不合理之处还望留言一起探讨。

热文推荐

你的微服务敢独立交付么?

理解JWT的使用场景和优劣

从Spring-Session源码看Session机制的实现细节

理解使用 JWT 设计的单点登录系统

JDK 1.5 - 1.8 各版本的新特性总结

Spring Boot快速开发利器:Spring Boot CLI

IntelliJ IDEA 2018.1正式发布!还能这么玩?

消息中间件选型分析

其他推荐

Spring Cloud Contract 契约测试实践

Spring Boot使用@Async实现异步调用:线程池的优雅关闭

Spring Boot使用@Async实现异步调用:自定义线程池

Spring Boot 2.0正式发布,升还是不升呢?

Spring Boot 2.0 新特性概览

Spring Boot/Cloud干货汇总

长按指纹

一键关注

深入交流、更多福利

扫码加入我的知识星球


点击 “阅读原文” 看看本号其他精彩内容

实践Jenkins集成Cobertura自动化构建SpringBoot工程相关推荐

  1. 使用Jenkins配置iOS自动化构建工具

    关于iOS自动化构建其实并不复杂,通过一些简单的Git与Xcode指令,加上UI,我们自己也可以动手编写一款自动化构建工具.这在之前的博客中也有涉及,有兴趣的朋友可以在如下地址找到这篇博客: 自己动手 ...

  2. Jenkins集成GitLab自动化部署

    一.申请一台linux系统 二.搭建docker环境 参考:Install docker 三.搭建Jenkins环境 参考:Install Jenkins 使用docker搭建完Jenkins环境后, ...

  3. jenkins搭建cc++自动化构建

    设置git源码管理 内网搭建GitLab源码托管平台,如下设置,使用的是http方式,点击Add添加gitlab用户名和密码. 立即执行构建会出现以下信息 表示从gitlab拉取代码成功,clone路 ...

  4. Jmeter+ant+jenkins 实现接口自动化构建

    目录 引言 一.安装并配置环境 1.下载安装jdk1.8并且配置环境变量 2.下载ant包 二.安装验证 1.拷贝jar包 2.修改jmeter报告输出格式 3.创建demo文件夹 4.建立build ...

  5. linux maven自动构建,Centos7.3+Jenkins+Git+Maven 自动化构建部署项目

    第一步 禁止 SELINUX 访问控制 修改配置之前先备份(良好习惯) sudo cp /etc/selinux/config /etc/selinux/config.bak 备份后,修改selinu ...

  6. Docker容器整合wagon-ssh自动化部署SpringBoot工程

    一.前提条件:  机器上已经安装了docker(安装过程) 准备部署的springboot的jar包 Dockerfile文件 部署脚本deploy.sh 升级脚本upgrade.sh 二.准备Doc ...

  7. 手把手0基础项目实战(一)——教你搭建一套可自动化构建的微服务框架(SpringBoot+Dubbo+Docker+Jenkins)...

    本文你将学到什么? 本文将以原理+实战的方式,首先对"微服务"相关的概念进行知识点扫盲,然后开始手把手教你搭建这一整套的微服务系统. 项目完整源码下载 https://github ...

  8. 手把手0基础项目实战(一)——教你搭建一套可自动化构建的微服务框架(SpringBoot+Dubbo+Docker+Jenkins)......

    手把手0基础项目实战(一)--教你搭建一套可自动化构建的微服务框架(SpringBoot+Dubbo+Docker+Jenkins)... 原文: 手把手0基础项目实战(一)--教你搭建一套可自动化构 ...

  9. 0基础教你搭建一套可自动化构建的微服务框架(SpringBoot+Dubbo+Docker+Jenkins)

    2019独角兽企业重金招聘Python工程师标准>>> 本文你将学到什么? 本文将以原理+实战的方式,首先对"微服务"相关的概念进行知识点扫盲,然后开始手把手教你 ...

最新文章

  1. CSS中Float概念相关文章
  2. Android-View点击事件短时间重复点击的过滤
  3. C/C++:Windows编程—Inline Hook内联钩子(下)
  4. 将来时的条件句_58
  5. Poj 1936,3302 Subsequence(LCS)
  6. 浅谈DOMContentLoaded事件及其封装方法
  7. 机器为什么可以学习(2)---一般化理论
  8. 【1002】Eclipse安装(编程软件)、Eclipse创建第一Java项目、eclipse安装包
  9. 搭建自己的聊天室平台、公司内部聊天平台,Rocket.Chat搭建及使用
  10. 二级c语言考试怎么调试程序,计算机二级C语言上机考试操作步骤及流程和注意事项...
  11. Linux C++后端开发学习路线参考汇总
  12. git文件标识添加绿色和红色图标
  13. RTD温度测量系统的实现
  14. 计算机网络原理 谢希仁(第8版)第三章习题答案
  15. IE innerHTMLi(转载)
  16. Taro开发微信小程序实现简单的登录退出功能
  17. 误删微信聊天记录觉得手足无措?免费教你如何恢复
  18. 软考java题目_软件工程软考题目总结
  19. win10如何获得管理员权限
  20. 英雄传奇-1.专用浏览器问题

热门文章

  1. webrtc 泄漏真实 ip 地址
  2. 多目录cmake工程 CmakeLists.txt编写
  3. 高并发网络编程之epoll详解
  4. RGBA和ARGB的区别
  5. linux 同步与异步--阻塞与非阻塞型I/O
  6. Centos7.2 基于LAMP框架部署Discuz论坛
  7. 使用google云(GCP)二次利用安装kali Linux(kali browser)
  8. 设置计算机网络为家用,两台电脑怎么同时上网 家用宽带路由器设置【设置方法】...
  9. mac搭建php审计环境,[php审计实战篇]Simple-Log v1.6 安装逻辑问题
  10. java属性_Java Properties 类