单元测试高效之路——持续集成

>>>> 持续集成

>>>> 持续集成的概念与好处

互联网软件的开发和发布,已经形成了一套标准流程,最重要的组成部分就是持续集成(Continuous integration,简称CI)。

持续集成的好处大概可以概括为两点:

1)快速发现错误

每完成一点更新,就集成到主干,可以快速发现错误,定位错误也比较容易。

2)防止分支大幅偏离主干

如果不是经常集成,主干又在不断更新,会导致以后集成的难度变大,甚至难以集成。

>>>> 持续集成的一般流程

根据持续集成的设计,代码从提交到生产,整个过程有以下几步:

1、提交

流程的第一步,是开发者向代码仓库提交代码。所有后面的步骤都始于本地代码的一次提交。

2、测试(第一轮)

代码仓库对commit操作配置了钩子,只要提交代码或者合并进主干,就会跑自动化测试。

测试有好几种:

  • 单元测试,针对函数或模块的测试
  • 集成测试,针对整体产品的某个功能的测试,又称功能测试
  • 端对端测试,从用户界面直达数据库的全链路测试

第一轮至少要跑单元测试。

3、构建

交付后,要先进行构建,再进入第二轮测试。在该阶段我们使用的工具为Jenkins。

4、测试(第二轮)

第二轮是全面测试,单元测试和集成测试都会跑。有条件的话,也要做端对端测试。所有测试以自动化为主,少数无法自动化的测试用例,就要人工跑。

5、部署

通过了第二轮测试,当前代码就是一个可以直接部署的版本。将这个版本的所有文件打包存档,发到生产服务器。

6、回滚

一旦当前版本发生问题,就要回滚到上一个版本的构建结果。

>>>> 单元测试&集成测试用例的提交

目前的工作中,测试人员负责单元测试的自动生成以及集成测试用例的编写工作。出于代码安全方面的考虑,测试人员是不具有对应代码库的提交权限的。如果对应的测试代码不提交到代码库中,那么持续集成的第一轮测试中的单元测试阶段就不具备条件。为了解决上述的问题。我们做了一系列的尝试工作。

单元测试的初期阶段

我们在做单元测试或集成测试的初期,测试人员先本地编写、运行、调式测试用例,然后统一由研发人员来提交代码库中。这种方式在测试用例较少的初期还是可以接受的,但是随着用例数量的增加,维护成本和沟通成本也随之增大,关键是还无形中增加了研发人员的工作量。

单元测试的中期阶段

一方面为了解决无权限提交测试代码,另一方面为了减少研发人员不必要的工作。后续我们专门为了提交测试代码而在研发代码的基础上做了代码库的派生,这样测试人员就具有了派生代码库的所有权限。

代码库提前权限的问题解决后,这种方式带来的另一个问题就是如何保持派生库与原生代码库的一致性问题。现在的解决办法是手工的方式从原生代码库上拉取到提交的代码,然后再次提交到派生代码库。这样就解决了两个代码库版本不一致的问题。这种方式也存在一定的问题,那就是不能够及时的拉取到最新的代码。在我们执行单元测试的时候,被测试的版本很有可能是滞后的代码版本。

单元测试的后期阶段

目前我们正在做调研,想通过其他的方式来解决手动同步代码库的问题。想到的方案是,每次原生代码库中有代码的提交时,自动触发代码同步的操作。这样一来,就可以解决派生代码库相对滞后的问题。

>>>> 持续集成工具

市面上已有很多开源持续集成工具,例如我们熟悉的Jenkins,还有TeamCity、Travis CI、GO CD、Bamboo、Gitlab CI、CircleCI等等。

>>>> Qone

京东质量管理平台(Qone)是运营质量部自主研发的一套综合性的持续集成系统,该系统不仅可以实现项目,人员以及工时的管理,同时还可以实现持续集成,持续部署和持续交付等等功能。不仅可以做到与京东现有的项目管理与自动打包系统做到无缝对接,而且还与Jenkins做到数据同步。充分利用Jenkins现有的功能。只需要在qone系统中做简单的配置,便可以每天定时执行单元测试用例,同时也可以生成单元测试覆盖率报告。

>>>> 集成测试数据统计

>>>> 代码覆盖率统计

代码覆盖率的意义

  1. 分析未覆盖部分的代码,从而反推在前期测试设计是否充分,没有覆盖到的代码是否是测试设计的盲点,为什么没有考虑到?需求/设计不够清晰,测试设计的理解有误,工程方法应用后的造成的策略性放弃等等,之后进行补充测试用例设计;
  2. 检测出程序中的废代码,可以逆向反推在代码设计中思维混乱点,提醒设计/开发人员理清代码逻辑关系,提升代码质量;
  3. 代码覆盖率高不能说明代码质量高,但是反过来看,代码覆盖率低,代码质量不会高到哪里去,可以作为测试自我审视的重要工具之一。

代码覆盖统计工具

考虑到Jacoco是一个开源的Java代码覆盖率工具,Jacoco可以嵌入到Ant 、Maven中,并提供了EclEmma Eclipse插件,也可以使用JavaAgent技术监控Java程序。很多第三方的工具提供了对Jacoco的集成,如sonar、Jenkins等。因此在多代码覆盖率统计时,我们使用Jacoco作为我们的单元测试覆盖率统计工具。

在做统计时,需要在maven的pom文件中添加如下配置项即可。

1. <plugins>

2. ...

3. <plugin>

4. <groupId>org.jacoco</groupId>

5. <artifactId>jacoco-maven-plugin</artifactId>

6. <version>0.8.1</version>

7. <executions>

8. <execution>

9. <id>pre-test</id>

10. <goals>

11. <goal>prepare-agent</goal>

12. </goals>

13. </execution>

14. <execution>

15. <id>post-test</id>

16. <phase>test</phase>

17. <goals>

18. <goal>report</goal>

19. </goals>

20. </execution>

21. <execution>

22. <id>post-test-aggregate</id>

23. <phase>test</phase>

24. <goals>

25. <goal>report-aggregate</goal>

26. </goals>

27. </execution>

28. </executions>

29. </plugin>

30. ...

31.</plugins>

单元测试覆盖率报告

>>>> 单元测试&集成测试执行结果统计

单次执行结果统计

每次执行完单元测试,会把执行结果以邮件的形式发送给相关人员。

周期执行结果统计

同时我们会以一周为一个周期,统计单元测试的执行情况,供相关人员做参考。

详情查看

目前,测试人员可以通过物流研发部自主研发的”玲珑”系统进行查看每次单元测试执行的结果,这些结果包括了单元测试的执行结果以及代码的覆盖率结果。

>>>> 履约系统单元测试中的收益

通过单元测试和集成测试环节,在测试过程中发现了近200个有效的bug,随着单元测试涉及到的跳线逐渐增加,该方面的bug数量也在逐渐增加。因此在保证上线质量方面,单测起到了至关重要的一个环节。

>>>> 写在最后

单元与集成测试的通过率和覆盖率在实际测试中具有很强的指导意义,它可以指导我们那些代码没有做测试覆盖。但是,一味的追求较高的代码覆盖率和通过率其实就失去了代码覆盖和测试通过率的本质意义。

测试覆盖是一种学习手段,学习为什么有些代码没有被覆盖到,以及为什么有些代码变了测试却没有失败。理解“为什么”背后的原因,程序员就可以做相应的改善和提高,相比凭空想象单元测试的有效性和代码的好坏,这会更加有效。

后续在保证一定代码覆盖率的基础上,我们会把重点放在代码变异测试(Mutation Test)上。通过对代码变异测试的应用,来找到一些提高测试和代码质量的方法。

原文发布于微信公众号 - 京东技术(jingdongjishu)

原文发表时间:2018-08-01

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏玄魂工作室

不明恶意攻击致<搜狗搜索><搜索结果>跳转<百度搜索>技术原理分析

先声明一点,本文作者不是搜狗的 然后 只是从技术的角度探讨问题---- 目录 不明恶意攻击致<搜狗搜索><搜索结果>跳转<百度搜索>技术原理分析 目录 * 前...

4629
来自专栏Golang语言社区

Golang语言社区--游戏服务器端开发的一些建议(转载)

大家好,我是Golang语言社区(www.golang.ltd)主编彬哥,本篇给大家转载一篇关于游戏服务器开发的文章。

6487
来自专栏京东技术

京东价格保护高并发 | 七步走保证用户体验

2014年加入京东,负责京东财务退款及价格保护研发建设,擅长京东逆向流程场景、金额拆分计算、高并发下网站优化。

1343
来自专栏CSDN技术头条

高性能智能日志实践

本文作者是 Archanaa Panda ,从 2000 以来一直在软件开发(构架、设计和编程)团队担任 Java / JavaEE 构架师,目前立志于做一个与...

25110
来自专栏郭耀华‘s Blog

【绝对给力】Android开发免豆资料(教程+工具+源码)地址汇总

教程下载: 【免费】android界面效果全汇总.pdf http://down.51cto.com/data/209179 Android终极开发教程...

4249
来自专栏ThoughtWorks

2015.5 技术雷达 | 工具篇

(点击图片可以查看大图) 尽管依赖管理的概念并不新奇,在很多技术栈下它甚至已经被作为一种基础开发实践,但在PHP 社区却并非如此。Composer(getcom...

3695
来自专栏非著名程序员

关于Android四大组件最权威最深刻最准确的解读(绝不标题党)

这篇文章翻译自Aannie Hackborn发表在google+上的一篇post,她是google资深大牛,2005年就进入Android Framework团...

20110
来自专栏北京马哥教育

15个NoSql数据库

随着互联网web2.0网站的兴起,非关系型的数据库现在成了一个极其热门的新领域,非关系数据库产品的发展非常迅速。而传统的关系数据库在应付web2.0网站,特别是...

3998
来自专栏Java学习网

低级程序员和高级程序员的区别

低级程序员和高级程序员的区别   低级程序员认为自己与高级程序员的区别, 主要是高级程序员任何功能都能编码实现, 编码速度快, 代码无 bug. 正如一惯的那样...

23310
来自专栏腾讯大讲堂的专栏

【折腾不止】前端工程与性能优化

作者:addy(许斌),前端开发工程师,文艺青年一枚,写得了文章,编得了代码。 作为开发,不仅仅是前端,优化总是你绕不开的事,我们的目标就是要产品变得更快。优化...

2428

扫码关注云+社区

领取腾讯云代金券