使用自动化新鲜工具Evosuite给大家尝尝鲜

偶尔在群里看到卡斯提到 evosuite 这个工具,随手查了下,竟然可以自动生成单元测试,而且看官方视频还不是太复杂,赶紧尝鲜一下。

介绍

直接摘抄网上的:

EvoSuite是由Sheffield等大学联合开发的一种开源工具,用于自动生成测试用例集,生成的测试用例均符合Junit的标准,可直接在Junit中运行。

通过使用此自动测试工具能够在保证代码覆盖率的前提下极大地提高测试人员的开发效率。但是只能辅助测试,并不能完全取代人工,测试用例的正确与否还需人工判断。

核心功能:

  • Generation of JUnit 4 tests for the selected classes 生成指定类的 Junit 4
    测试用例
  • Optimization of different coverage criteria, like lines, branches,
    outputs and mutation testing通过不同的覆盖指标调整生成的用例,如行覆盖率、分支覆盖率、输出及变异测试(mutation testing)
  • Tests are minimized: only the ones contributing to achieve coverage
    are retained 测试最小化,只有能贡献覆盖指标的用例才会被保留下来
  • Generation of JUnit asserts to capture the current behavior of the
    tested classes 生成 Junit 断言来检验被测试的类的行为
  • Tests run in a sandbox to prevent potentially dangerous operations
    测试被运行在一个沙盒中,避免潜在的危险行为
  • Virtual file system 虚拟文件系统
  • Virtual network 虚拟网络

跟大家推荐一个学习资料分享群:903217991,里面大牛已经为我们整理好了许多的学习资料,有自动化,接口,性能等等的学习资料!人生是一个逆水行舟的过程,不进则退,咱们一起加油吧!

使用

官方提供了包括命令行工具、eclipse 插件、idea 插件、maven 插件 在内的数种运行方式。

其中 eclipse 插件的可以参照 自动化单元测试工具 EvoSuite 的简单使用

四种都大致看了下,其中 maven 插件的方式最为简单,所以选取它来尝鲜。

接下来的流程主要参考官方的 http://www.evosuite.org/documentation/tutorial-part-2/ ,时间关系简略了一些解释说明,有兴趣的同学欢迎阅读官方原文了解。

准备工作

既然是尝鲜,当然不能直接用官方的项目啦,找了个自己以前找到的开源 java 项目:https://github.com/chenhengjie123/JavaSpringMvcBlog

下一步,按照官方指示,调整下 junit 版本


  
    junit
    junit
    4.12
    test
  

生成测试用例

添加 evosuite 插件


      
        org.evosuite.plugins
        evosuite-maven-plugin
        1.0.6
      
...

(可选)官方提到,因为maven中央仓库没有收录这个插件,所以要加上 evosuite 自己的仓库地址。不过经过搜索,中央仓库现在已经有了,所以这步应该可以忽略。如果大家下载不了,可以把下面的配置也加到 pom 里面添加 evosuite 的仓库


  
    EvoSuite
    EvoSuite Repository
    http://www.evosuite.org/m2
  

为了执行用例,需要加入 evosuite 的运行依赖:


    org.evosuite
    evosuite-standalone-runtime
    1.0.6
    test

开始生成,只需要执行这个命令

mvn  evosuite:generate

为了加快速度一步到位,我加了不少参数:

mvn compile -DmemoryInMB=2000 -Dcores=2 -Dcuts=alexp.blog.service.PostServiceImpl -DtargetFolder=src/test/java/evosuite evosuite:generate evosuite:export

简单说明下:

  • compile 表示编译。evosuite 是基于编译后的 .class 文件生成用例的,所以需要先编译。
  • -DmemoryInMB=2000 表示使用 2000MB 的内存
  • -Dcores=2 表示用2个 cpu 来并行加快生成速度
  • -Dcuts=alexp.blog.service.PostServiceImpl 表示只针对 alexp.blog.service.PostServiceImpl 这个类生成用例。多个用例可以用英文逗号分隔
  • -DtargetFolder=src/test/java/evosuite 表示生成的用例放到 src/test/java/evosuite 。
  • evosuite:generate 表示执行生成用例
  • evosuite:export 表示导出用例到 targetFolder 的值所在的目录中

执行完毕后,在 src/test/evosuite 下会增加一个 alexp/blog/service 文件夹,里面存放生成的测试文件:

src/test/java/evosuite
└── alexp
    └── blog
        └── service
            ├── PostServiceImpl_ESTest.java
            └── PostServiceImpl_ESTest_scaffolding.java

3 directories, 2 files

PostServiceImpl_ESTest.java:测试用例文件
PostServiceImpl_ESTest_scaffolding.java:用例基类,用于在开始测试前初始化 evosuite 的沙盒机制

实际生成的部分代码会有编译错误(mock 的类型和 model 对不上),先通过注释跳过会编译出错的行,然后直接在 idea 执行 PostServiceImpl_ESTest.java ,并统计覆盖率:
使用自动化新鲜工具Evosuite给大家尝尝鲜_第1张图片
看起来覆盖率还挺高。当然,覆盖率并不代表全部,更重要的是测的内容。

摘抄一条生成的单测用例:

使用自动化新鲜工具Evosuite给大家尝尝鲜_第2张图片
对应的被测函数:

在这里插入图片描述
可以看到

  • 大量采用了 mockito 来 mock 掉外部对象。
  • 通过 mock 掉 findByHiddenIs 方法固定返回 null ,进而测试 getPostsList 是否也返回 null,逻辑上没错,结果可以做到很稳定。

但可惜:

  • 没有校验正常逻辑(看了下整个类,2个用例校验 null ,一个校验非法参数,唯独缺少正常场景)

不过总的来说,作为异常场景的补充,确实能省很多力。

完整测试代码和被测代码,可以查看:

被测代码:
https://github.com/chenhengjie123/JavaSpringMvcBlog/blob/master/src/main/java/alexp/blog/service/PostServiceImpl.java

生成的测试代码:
https://github.com/chenhengjie123/JavaSpringMvcBlog/blob/master/src/test/java/evosuite/alexp/blog/service/PostServiceImpl_ESTest.java

作者自己写的测试代码(场景不全,但覆盖了正常场景):
https://github.com/chenhengjie123/JavaSpringMvcBlog/blob/master/src/test/java/alexp/blog/service/PostServiceTest.java

结论

工具使用简单,生成的用例确实有效,推荐试用。

但比较适合用于生成一些异常场景的用例,省不少力(当然还得人工 review 下)。正常场景还是得靠人。

你可能感兴趣的:(使用自动化新鲜工具Evosuite给大家尝尝鲜)