evosuite的安装与使用

2019.9.19 目前evosuite的官网已经恢复正常。这篇文章就当作是时代的眼泪吧……同时也是我的眼泪。

目前因为evosuite的官网不可用,只能用jar包凑合一下了。反正jar包也是完整可运行的不是吗(笑)。

先到evosuite的github仓库里下载jar包:https://github.com/EvoSuite/evosuite/releases

先编译或者运行一下项目(如果不编译,是不会有/target/classes的),然后进入项目根目录/target/classes/

这一步请在操作系统的文件资源管理器里进行,比如我用的是Windows系统,路径是C:\mooctest\projects\3419\47795\Triangle;如果直接在IDE里打开,可能会看不到上述的目录。此外,可以顺便把evosuite的jar包复制过来,就不用绝对路径了。

然后,执行以下命令:

java -jar evosuite-1.0.6.jar -projectCP ./ -class net.mooctest.Triangle 

-projectCP是为了指定生成的路径。这一步用可以用-help来显示可用的选项,中间还可以加上-criterion指定生成的标准,比如line、branch、cbranch、mutation 、exception,等等。

如果需要生成某个包里所有文件的测试用例,可以使用-prefix命令。比如:

java -jar evosuite-1.0.6.jar -projectCP ./ -prefix net.mooctest

这一步在运行evosuite的时候,可能会出现类似于这样的错误:

ERROR EvoSuite - Fatal crash on main EvoSuite process. Class using seed 1428172877144. Configuration id : null

这个有可能是JDK版本导致的报错,因为evosuite的稳定版本只支持JDK1.8。据说开发版本已经支持Java 9了,但是毕竟不太稳定,使用的时候还是要慎重,用稳定版的会比较保险。

如果一切顺利,这里会生成两个文件夹:evosuite-report/evosuite-tests/。因为maven插件不可用,所以就手动把evosuite-tests里的测试文件(可能会有嵌套的目录,我这里是Triangle_ESTest.javaTriangle_ESTest_scaffolding.java)复制到对应maven项目的test/目录下运行JUnit测试。

也许你会发现生成的测试用例覆盖率很低,而且低得有点奇怪。我们可以打开生成的测试文件看一下:

@Test(timeout = 4000)
public void test0()  throws Throwable  {
    Triangle triangle0 = null;
    try {
        triangle0 = new Triangle((-1794L), (-1794L), (-1794L));
        fail("Expecting exception: NoClassDefFoundError");
    } catch(NoClassDefFoundError e) {
        //
        // com/sun/tdk/jcov/runtime/Collect
        //
        verifyException("net.mooctest.Triangle", e);
    }
}

可以发现只有这一个用例,而且报的是这个NoClassDefFoundError:com/sun/tdk/jcov/runtime/Collect。相信用过mooctest插件的人都见过这个报错,解决方法也很简单,就是maven-update。如果用的是eclipse,右击当前项目,选择
Maven – Update Project…(我相信看到这篇文章的人用的都是eclipse,笑),然后再次运行上面的命令,就可以看到完整的测试用例了。

但是生成的测试文件其实是直接不能运行的,因为缺少evosuite的运行环境,根本过不了编译。

如果只是为了补充测试用例,可以直接把生成的测试用例(主要是Triangle_ESTest.java)复制到原有的测试文件里,因为mooctest似乎只能识别原有的测试文件。

这一点不确定,可能是我的打开方式不对。

需要强调的是,在复制生成的用例的时候,需要将evosuite的辅助方法换成JUnit的异常捕获机制。以前文为例,以下的代码是无法运行的,因为缺少verifyException方法:

@Test(timeout = 4000)
public void test0()  throws Throwable  {
    Triangle triangle0 = null;
    try {
        triangle0 = new Triangle((-1794L), (-1794L), (-1794L));
        fail("Expecting exception: NoClassDefFoundError");
    } catch(NoClassDefFoundError e) {
        //
        // com/sun/tdk/jcov/runtime/Collect
        //
        verifyException("net.mooctest.Triangle", e);
    }
}

所以,我们应该把代码改成这样:

@Test(timeout = 4000, expect = NoClassDefFoundError.class)
public void test0()  throws Throwable  {
    Triangle triangle0 = null;
    triangle0 = new Triangle((-1794L), (-1794L), (-1794L));
}

这样就能运行了。当然,这只是一个例子,实际生成的代码可能不是这样,JUnit捕获异常的方式也不止这一种,可以按照自己习惯的方式去写。

如果需要本地运行,就需要进一步在pom.xml里增加依赖配置:

<dependency>
    <groupId>org.evosuite.pluginsgroupId>
    <artifactId>evosuite-maven-pluginartifactId>
    <version>1.0.6version>
dependency>

这一步可能时间会比较长(具体原因就不说了,大家都知道)。配置完成之后再次运行就可以了。

这一步可能会报错Missing artifact com.sun:tools:jar:1.0.0。解决方法也很简单,引入JDK里的tools.jar就好了(记得把这里的版本改成你自己的JDK版本,我的版本是1.8.0_191):

<dependency>
    <groupId>com.sungroupId>
    <artifactId>toolsartifactId>
    <version>1.8.0_191version>
    <scope>systemscope>
    <systemPath>D:\Java\jdk1.8.0_191\lib\tools.jarsystemPath>
dependency>

另外,据说加上这一段以后可以用mvn evosuite:help来下载和运行插件:

<pluginRepositories>
    <pluginRepository>
        <id>EvoSuiteid>
        <name>EvoSuite Repositoryname>
        <url>http://www.evosuite.org/m2url>
    pluginRepository>
pluginRepositories>

但是因为evosuite的官网炸了(502,不知道他们干了什么),这个方法的真实性无法验证。而且,就算这个方法可用,只要evosuite的官网是正常的,我为什么不用eclipse自带的插件呢?

参考资料

  1. EVOSUITE使用方法入门
  2. evosuite 对单个 .class 生成测试用例
  3. maven项目内配置evosuite插件来自动生成test suite
  4. Missing artifact com.sun:tools:jar:1.x.x解决办法

你可能感兴趣的:(配置踩坑,大概是测试)