龙空技术网

EvoSuite:一分钟生成覆盖率90%以上的TestCase

令狐冲学Java 98

前言:

目前各位老铁们对“java的case”大体比较珍视,同学们都需要分析一些“java的case”的相关文章。那么小编同时在网上搜集了一些有关“java的case””的相关内容,希望看官们能喜欢,看官们快快来了解一下吧!

开发人员有两件事不愿意干:一是写文档,二是写测试。今天介绍一个框架,帮你自动生成90%以上的测试用例。它会自动构建入参、判断If、循环,Mock接口,总之,对于有大量单元测试要写的同学,这就是一个解救你的工具。

1. EvoSuite是什么

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

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

EvoSuite官网为

EvoSuite GitHub

EvoSuite问题及解答

2. EvoSuite能做什么?

EvoSuite最新版本是1.0.6,Main features如下:

Generation of JUnit 4 tests for the selected classesOptimization of different coverage criteria, like lines, branches, outputs and mutation testingTests are minimized: only the ones contributing to achieve coverage are retainedGeneration of JUnit asserts to capture the current behavior of the tested classesTests run in a sandbox to prevent potentially dangerous operationsVirtual file systemVirtual network2.1. 举个例子:自动生成入参,覆盖分支

public void printC(int a){    if(a > 10){        System.out.println("Test Evo C a > 10");    }else{        System.out.println("Test Evo C " + a);    }}

对于上面的方法的单侧,Evo会生成下面几个方法,包含了边界条件,正常参数等:

@Test(timeout = 4000)public void test0()  throws Throwable  {    TestA testA0 = new TestA();    testA0.printC(10);} @Test(timeout = 4000)public void test1()  throws Throwable  {    TestA testA0 = new TestA();    testA0.printC(2291);} @Test(timeout = 4000)public void test2()  throws Throwable  {    TestA testA0 = new TestA();    testA0.printC(0);}
2.2. 举个例子:Mock
public Person getByName(String name){   Person p = demoMapper.getByName(name);   if("John".equals(p.getName())){       return p;   }   return null;}

针对这个例子,EvoSuite会mock出mapper的不同返回值,对Service进行测试:

DemoService demoService0 = new DemoService();Person person0 = mock(Person.class, new ViolatedAssumptionAnswer());doReturn("John").when(person0).getName();doReturn((String) null).when(person0).toString();DemoMapper demoMapper0 = mock(DemoMapper.class, new ViolatedAssumptionAnswer());doReturn(person0, (Person) null).when(demoMapper0).getByName(anyString());Injector.inject(demoService0, (Class<?>) DemoService.class, "demoMapper", (Object) demoMapper0);Injector.validateBean(demoService0, (Class<?>) DemoService.class);demoService0.getByName("John");// Undeclared exception!try {  demoService0.getByName("5vOP6EQ-fG3'E2)k");  fail("Expecting exception: NullPointerException"); } catch(NullPointerException e) {   //   // no message in exception (getMessage() returned null)   //   verifyException("com.example.demo.service.DemoService", e);}
3. EvoSuite怎么用

EvoSuite既支持多种方式:命令行、maven plugin、eclipse plugin、idea plugin。以idea plugin为例:

3.1. install plugin

在idea的Setting-Plugins中搜索“Evosuite”即可,install 之后 restart idea。

3.2. pom中增加配置:

<properties>   <java.version>1.8</java.version>   <evosuiteVersion>1.0.6</evosuiteVersion></properties>  <dependency>   <groupId>junit</groupId>   <artifactId>junit</artifactId>   <version>4.12</version>   <scope>test</scope></dependency> <dependency>   <groupId>org.evosuite</groupId>   <artifactId>evosuite-standalone-runtime</artifactId>   <version>${evosuiteVersion}</version>   <scope>test</scope></dependency>  <plugin>   <groupId>org.evosuite.plugins</groupId>   <artifactId>evosuite-maven-plugin</artifactId>   <version>${evosuiteVersion}</version>   <executions><execution>      <goals> <goal> prepare </goal> </goals>      <phase> process-test-classes </phase>   </execution></executions></plugin>
3.3. 使用EvoSuite

右键单击要测试的java类,点击Run EvoSuite,可以看到弹出的界面,点击OK可以生成测试用例。

4. 常见问题EvoSuite maven依赖下载,可以通过添加阿里云的仓库来解决。EvoSuite目前版本是1.0.65.劣势

1.只支持Junit4,不支持Junit5、testng等

2.没有扩展性,JUnit 5 的一个核心原则是扩展点优于特性,对于开源产品来说,这个没有扩展性是致命的

3.EvoSuite做的太重了,它在Junit外包了一层;在我看来,这个产品的卖点,在于利用asm生成testcase,所以它做到这一步就行了,而不应该把junit做的事再做一次

4.整体的架构设计、代码设计都一般

标签: #java的case