Evosuite用maven構建(內附詳細過程)

Evosuite用maven構建

【參考來源】http://www.evosuite.org/documentation/tutorial-part-2/

!如果在照着做出現找不到文件的情況,請翻到本文最後看最終的pom.xml配置以及文件結構

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>groupId</groupId>
    <artifactId>JdbcDemo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>6.0.6</version>
        </dependency>
        <dependency>
            <groupId>org.evosuite</groupId>
            <artifactId>evosuite-standalone-runtime</artifactId>
            <version>${evosuiteVersion}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>


   <build>
       <pluginManagement>
           <plugins>
               <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>
               <plugin>
                   <groupId>org.apache.maven.plugins</groupId>
                   <artifactId>maven-surefire-plugin</artifactId>
                   <version>2.17</version>
                   <configuration>
                       <properties>
                           <property>
                               <name>listener</name>
                               <value>org.evosuite.runtime.InitializingListener</value>
                           </property>
                       </properties>
                   </configuration>
               </plugin>
               <plugin>
                   <groupId>org.codehaus.mojo</groupId>
                   <artifactId>build-helper-maven-plugin</artifactId>
                   <version>1.8</version>
                   <executions>
                       <execution>
                           <id>add-test-source</id>
                           <phase>generate-test-sources</phase>
                           <goals>
                               <goal>add-test-source</goal>
                           </goals>
                           <configuration>
                               <sources>
                                   <source>${customFolder}</source>
                               </sources>
                           </configuration>
                       </execution>
                   </executions>
               </plugin>
           </plugins>
       </pluginManagement>
   </build>


    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <evosuiteVersion>1.0.6</evosuiteVersion>
        <customFolder>src/test/java</customFolder>
    </properties>
</project>

The EvoSuite Maven plugin命令簡介

1)generate

這用於通過EvoSuite生成測試用例。 將爲所有子模塊中的所有類生成測試。 您需要確保代碼已編譯。

mvn compile evosuite:generate

可以跟的參數

memoryInMB:EvoSuite允許分配的總兆字節數(默認爲800)

cores:EvoSuite可以使用的CPU內核總數(默認爲1)

timeInMinutesPerClass:EvoSuite可以花多少分鐘爲每個類生成測試(默認2)

2)info:提供到目前爲止所有已生成測試的信息

3)export: 默認情況下,EvoSuite在“ .evosuite”文件夾中創建測試。 通過使用“導出”,將生成的測試複製到另一個文件夾,該文件夾可以使用“ targetFolder”選項設置(默認值爲“ src / test / java”)。

如果不使用“ mvn evosuite:export”將測試導出到“ src / test / java”,則“ mvn test”之類的命令將不會執行這些測試,因爲它們的源代碼不在構建路徑中。 您可以使用“ build-helper-maven-plugin”插件添加自定義源文件夾.

4)clean:刪除“ .evosuite”文件夾中的所有數據,該文件夾用於存儲到目前爲止生成的所有最佳測試.

5)prepare:需要同時運行EvoSuite測試和現有測試.

mvn evosuite:prepare test

最好僅將evosuite插件配置爲始終運行,如前所述。

eg.

mvn -DmemoryInMB=2000 -Dcores=2 evosuite:generate evosuite:export  test

這將使用2個內核和2GB內存爲所有類生成測試,將生成的測試複製到“ src / test / java”,然後執行它們。 注意:如果項目已經進行了一些測試,那麼這些測試將作爲常規“測試”階段的一部分執行。

maven集成

準備被測項目

下載被測項目

wget http://evosuite.org/files/tutorial/Tutorial_Maven.zip
unzip Tutorial_Maven.zip
cd Tutorial_Maven

和以前一樣,我們可以使用以下命令來編譯項目中的類

mvn compile

目錄如下
在這裏插入圖片描述
然後這個項目本身有測試,位於JdbcDemo/src/test/java/StackTest.java

這個屬於已有測試,可以使用命令

mvn test

在這裏插入圖片描述
更近一步看pom.xml

如果您已經非常熟悉Maven,那麼本節可能不會告訴您任何新內容。 但是,瞭解如何配置Maven項目以配置項目以使用EvoSuite至關重要。 因此,我們現在將仔細研究示例項目的主要Maven配置文件,即文件pom.xml。

我們的示例項目中的pom.xml基於使用mvn archetype:generate生成的基本版本。 它從有關該項目的一些基本元信息開始

查看help命令

mvn evosuite:help
[INFO] Maven Plugin for EvoSuite 1.0.6
  Plugin used to run EvoSuite to automatically generate high coverage JUnit
  tests

This plugin has 7 goals:

evosuite:clean
  Remove all local files created by EvoSuite so far

evosuite:coverage
  Execute the manually written test suites (usually located under src/test/java)
  and return the coverage of each class.

evosuite:export
  When run, EvoSuite generate tests in a specific folder. New runs of EvoSuite
  can exploit the tests in such folder, and/or modify them.
  
  So, with 'export' we can copy all generated tests to a specific folder, which
  by default points to where Maven searches for tests. If another folder is
  rather used (or if we want to run with Maven the tests in the default EvoSuite
  folder), then Maven plugins like build-helper-maven-plugin are needed

evosuite:generate
  Generate JUnit tests

evosuite:help
  Display help information on evosuite-maven-plugin.
  Call mvn evosuite:help -Ddetail=true -Dgoal=<goal-name> to display parameter
  details.

evosuite:info
  Obtain info of generated tests so far

evosuite:prepare
  Mojo needed to prepare the EvoSuite tests for execution. This is needed to
  make sure that bytecode is properly instrumented.

我們可以使用-Dproperty = value語法爲插件目標設置屬性,就像爲任何Java進程設置屬性一樣。 例如,要獲取有關在執行幫助插件目標時生成插件目標的更多詳細信息,我們可以運行以下命令

mvn evosuite:help -Ddetail=true -Dgoal=generate

如果運行此命令,應該會看到可以爲生成插件目標設置的所有屬性的列表。這個是顯示generate參數

evosuite:generate
  Generate JUnit tests

  Available parameters:

    criterion (Default:
    LINE:BRANCH:EXCEPTION:WEAKMUTATION:OUTPUT:METHOD:METHODNOEXCEPTION:CBRANCH)
    //行:語句:異常:弱變異:輸出:方法:方法異常:分支結構
      Coverage criterion. Can define more than one criterion by using a ':'
      separated list
      User property: criterion
   // 覆蓋準則,可以定義不止一個覆蓋準則,使用:隔開

    cuts
      Comma ',' separated list of CUTs to use in CTG. If none specified, then
      test all classes
      User property: cuts
		// 用逗號“,”分隔CTG中要使用的CUT(被測類)列表。 如果未指定,則測試所有類
    cutsFile
      Absolute path to a file having the list of CUTs specified. This is needed
      for operating systems like Windows that have constraints on the size of
      input parameters and so could not use 'cuts' parameter instead if too many
      CUTs are specified
      User property: cutsFile
		// 指定了CUT列表的文件的絕對路徑。 對於Windows等大小受限制的操作系統,這是必需的
輸入參數,因此如果指定了太多的CUT,則不能使用“ cuts”參數
    extraArgs (Default: )
      
      User property: extraArgs

    memoryInMB (Default: 800)
      Total Memory (in MB) that CTG will use
      User property: memoryInMB

    numberOfCores (Default: 1)
      Number of cores CTG will use
      User property: cores

    schedule (Default: BUDGET)
      Schedule used to run CTG (SIMPLE, BUDGET, SEEDING, BUDGET_AND_SEEDING,
      HISTORY)
      User property: schedule

    spawnManagerPort (Default: )
      
      User property: spawnManagerPort

    timeInMinutesPerClass (Default: 2)
      How many minutes to allocate for each class
      User property: timeInMinutesPerClass
	//每個類分配多少分鐘
    timeInMinutesPerProject (Default: 0)
      How many minutes to allocate for each project/module. If this parameter is
      not set, then the total time will be timeInMinutesPerClass x
      number_of_classes
      User property: timeInMinutesPerProject
	//爲每個項目/模塊分配多少分鐘。 如果未設置此參數,則總時間爲timeInMinutesPerClass x

現在讓我們使用evosuite生成些測試

mvn evosuite:generate
[INFO] * EvoSuite 1.0.6
[INFO] Registered remote process from /127.0.0.1:59667
[INFO] Going to execute 10 jobs
[INFO] Estimated completion time: 20 minutes, by 2019-10-10T09:46:48.318
[INFO] Going to start job for: jdbc.Demo04. Expected to end in 179 seconds, by 2019-10-10T09:29:47.340
[INFO] Registered remote process from /127.0.0.1:59671
[INFO] Registered remote process from /127.0.0.1:59677
[INFO] Completed job. Left: 9
[INFO] Going to start job for: jdbc.Demo06. Expected to end in 170 seconds, by 2019-10-10T09:31:21.353
[INFO] Registered remote process from /127.0.0.1:59730
[INFO] Registered remote process from /127.0.0.1:59737
[INFO] Completed job. Left: 8
[INFO] Going to start job for: jdbc.Demo05. Expected to end in 143 seconds, by 2019-10-10T09:32:28.330
[INFO] Registered remote process from /127.0.0.1:59780
[INFO] Registered remote process from /127.0.0.1:59786
[INFO] Completed job. Left: 7
[INFO] Going to start job for: jdbc.Demo03. Expected to end in 133 seconds, by 2019-10-10T09:33:43.435
[INFO] Registered remote process from /127.0.0.1:59819
[INFO] Registered remote process from /127.0.0.1:59825
[INFO] Completed job. Left: 6
[INFO] Going to start job for: jdbc.Demo02. Expected to end in 133 seconds, by 2019-10-10T09:34:58.170
[INFO] Registered remote process from /127.0.0.1:59863
[INFO] Registered remote process from /127.0.0.1:59869
[INFO] Completed job. Left: 5
[INFO] Going to start job for: Tutorial_Maven.LinkedList. Expected to end in 115 seconds, by 2019-10-10T09:35:55.028
[INFO] Registered remote process from /127.0.0.1:59906
[INFO] Registered remote process from /127.0.0.1:59912
[INFO] Completed job. Left: 4
[INFO] Going to start job for: jdbc.Demo01. Expected to end in 96 seconds, by 2019-10-10T09:36:43.878
[INFO] Registered remote process from /127.0.0.1:59946
[INFO] Registered remote process from /127.0.0.1:59953
[INFO] Completed job. Left: 3
[INFO] Going to start job for: Tutorial_Maven.Stack. Expected to end in 87 seconds, by 2019-10-10T09:37:30.592
[INFO] Registered remote process from /127.0.0.1:59981
[INFO] Registered remote process from /127.0.0.1:59987
[INFO] Completed job. Left: 2
[INFO] Going to start job for: Tutorial_Maven.LinkedListIterator. Expected to end in 78 seconds, by 2019-10-10T09:38:13.216
[INFO] Registered remote process from /127.0.0.1:60005
[INFO] Registered remote process from /127.0.0.1:60011
[INFO] Completed job. Left: 1
[INFO] Going to start job for: Tutorial_Maven.Node. Expected to end in 60 seconds, by 2019-10-10T09:38:43.341
[INFO] Registered remote process from /127.0.0.1:60043
[INFO] Registered remote process from /127.0.0.1:60049
[INFO] Completed job. Left: 0
[INFO] * Updating database to Tutorial_Maven.Node
[INFO] * Updating database to Tutorial_Maven.LinkedListIterator
[INFO] * Updating database to jdbc.Demo01
[INFO] * Updating database to Tutorial_Maven.LinkedList
[INFO] * Updating database to jdbc.Demo05
[INFO] * Updating database to jdbc.Demo04
[INFO] * Updating database to Tutorial_Maven.Stack
[INFO] * Updating database to jdbc.Demo03
[INFO] * Updating database to jdbc.Demo02
[INFO] * Updating database to jdbc.Demo06
[INFO] === CTG run results ===
[INFO] Removed test suites: 0
[INFO] New test suites: 10
[INFO] Stopping spawn process manager
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  11:10 min
[INFO] Finished at: 2019-10-10T09:37:49+08:00
[INFO] ------------------------------------------------------------------------

我的電腦燙的。。。,讓我們來看看這個優秀的工具生成的測試用例,生成的沒有成功導出到src/main/test/java,暫時先在目錄~/IdeaProjects/JdbcDemo/.evosuite/best-tests下看

在這裏插入圖片描述

爲了對比人工和自動生成的,我們就看一下Stack的測試類ba

/*
 * This file was automatically generated by EvoSuite
 * Thu Oct 10 01:36:54 GMT 2019
 */

package Tutorial_Maven;

import org.junit.Test;
import static org.junit.Assert.*;
import static org.evosuite.runtime.EvoAssertions.*;
import Tutorial_Maven.Stack;
import org.evosuite.runtime.EvoRunner;
import org.evosuite.runtime.EvoRunnerParameters;
import org.junit.runner.RunWith;

@RunWith(EvoRunner.class) @EvoRunnerParameters(mockJVMNonDeterminism = true, useVFS = true, useVNET = true, resetStaticState = true, separateClassLoader = true, useJEE = true) 
public class Stack_ESTest extends Stack_ESTest_scaffolding {

  /**判斷棧空測試-1*/
  @Test(timeout = 4000)
  public void test0()  throws Throwable  {
      Stack<Object> stack0 = new Stack<Object>();
      assertTrue(stack0.isEmpty());
      
      stack0.push(stack0);
      stack0.push(stack0);
      stack0.pop();
      assertFalse(stack0.isEmpty());
  }

  /**判斷棧空測試-2*/
  @Test(timeout = 4000)
  public void test1()  throws Throwable  {
      Stack<Object> stack0 = new Stack<Object>();
      stack0.push((Object) null);
      assertFalse(stack0.isEmpty());
      
      stack0.pop();
      assertTrue(stack0.isEmpty());
  }

  @Test(timeout = 4000)
  public void test2()  throws Throwable  {
      Stack<String> stack0 = new Stack<String>();
      boolean boolean0 = stack0.isEmpty();
      assertTrue(boolean0);
  }

  @Test(timeout = 4000)
  public void test3()  throws Throwable  {
      Stack<Object> stack0 = new Stack<Object>();
      assertTrue(stack0.isEmpty());
      
      Integer integer0 = new Integer(724);
      stack0.push(integer0);
      boolean boolean0 = stack0.isEmpty();
      assertFalse(boolean0);
  }

  /**測試異常*/
  @Test(timeout = 4000)
  public void test4()  throws Throwable  {
      Stack<Object> stack0 = new Stack<Object>();
      // Undeclared exception!
      try { 
        stack0.pop();
        fail("Expecting exception: IllegalArgumentException");
      
      } catch(IllegalArgumentException e) {
         //
         // Stack empty
         //
         verifyException("Tutorial_Maven.Stack", e);
      }
  }

  /**測試入棧和出棧*/
  @Test(timeout = 4000)
  public void test5()  throws Throwable  {
      Stack<Object> stack0 = new Stack<Object>();
      Integer integer0 = new Integer(724);
      stack0.push(integer0);
      stack0.push(stack0);
      stack0.push(stack0);
      Object object0 = new Object();
      stack0.push(stack0);
      stack0.push(object0);
      stack0.push(object0);
      stack0.push(object0);
      stack0.push(object0);
      stack0.push(object0);
      stack0.push("");
      // Undeclared exception!
      try { 
        stack0.push("");
        fail("Expecting exception: IllegalArgumentException");
      
      } catch(IllegalArgumentException e) {
         //
         // Stack exceeded capacity!
         //
         verifyException("Tutorial_Maven.Stack", e);
      }
  }
}

手工測試類只有一個判斷棧空操作。假設您對這些測試套件感到滿意,我們可以將它們集成到源代碼樹中。 默認情況下,JUnit測試應該位於Maven項目的src / test / java中,因此EvoSuite將在其中放置測試套件。 爲此,請調用以下命令

mvn evosuite:export

現在,您應該將測試套件複製到src / test / java-確保它們在那裏

o天,我文件路徑寫錯了。。。。我就說,既然已經產生了測試,那就先註釋掉pom文件,開始導出

執行evos在這裏插入圖片描述uite產生的測試

現在我們在源代碼樹中有了這些測試,執行它們將是很棒的。 使用Maven,可以通過調用測試生命週期階段來完成

mvn test

jdbc那部分測試報錯先不看,先看官方那個例子

在這裏插入圖片描述

請注意,測試的數量不可避免地會有所不同– EvoSuite使用隨機算法生成測試,因此每次調用它時,您都會得到不同的結果。

將EvoSuite測試與開發人員編寫的測試分開

當我們使用mvn evosuite:export導出測試時,它們被複制到src / test / java中,這是Maven希望所有測試都在的位置。 有時,開發人員可能更願意將自己的測試與生成的測試分開。

假設我們不希望在src / test / java中生成測試。 刪除我們已經在那裏導出的測試

~/IdeaProjects/JdbcDemo » rm -r src/test/java/jdbc src/test/java/Tutorial_Maven
-r是因爲刪除的是文件夾

導出目標提供了一個屬性,用於指定將測試導出到的位置–回想一下,我們可以使用以下命令來獲取有關此目標的詳細信息,有兩種方式可以導出到指定位置

mvn evosuite:export -DtargetFolder=src/test/evosuite

或者在pom中配置

<properties>
      <targetFolder>src/test/evosuite</targetFolder>
</properties>

與開發人員書寫測試一起執行EvoSuite測試

爲了確保該工具僅對EvoSuite測試有效,我們需要爲EvoSuite測試添加初始化偵聽器。 爲此,將以下部分添加到pom.xml文件的<build>部分的<plugins>部分中

<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-surefire-plugin</artifactId>
   <version>2.17</version>
   <configuration>
     <properties>
       <property>
          <name>listener</name>
          <value>org.evosuite.runtime.InitializingListener</value>
      </property>
     </properties>
  </configuration>
</plugin>

運行實驗

【參考來源】http://www.evosuite.org/documentation/tutorial-part-3/

收集有關測試生成結果的數據

選擇輸出變量進行數據收集

生成數據的基本分析

使用EvoSuite運行大型實驗

實驗前準備-當然是下載官方提供的項目咯

對於本教程的第三部分,我們將研究如何收集有關測試生成的數據,這是在測試生成上運行實驗時通常需要的。 我們將使用一個簡單的示例場景:默認情況下,EvoSuite使用不同覆蓋標準的組合。 與僅將分支覆蓋範圍用作目標條件相比,這種組合有什麼影響? 一個合理的假設是,這種組合會導致更多的測試和更好的測試套件。 但這是真的嗎? 讓我們做一些實驗來找出答案!

實驗將涉及在多個類中使用其默認配置運行EvoSuite,並將其配置爲僅使用分支覆蓋率,然後對所得測試套件進行不同的測量。 在進行此類實驗時,類別的選擇會影響我們得出的結論的概括程度:如果我們使用非常具體且很小的類別選擇,那麼無論我們的發現如何,它們可能僅與特定類型的類別相關。 因此,我們通常希望選擇儘可能多的,儘可能多樣的並且具有代表性的類,以便獲得概括的結果。

wget http://evosuite.org/files/tutorial/Tutorial_Experiments.zip
unzip Tutorial_Experiments.zip
cd Tutorial_Experiments
mvn compile
//下載依賴項
mvn dependency:copy-dependencies -DincludeScope=runtime

此命令下載所有依賴項jar文件,並將它們放入target / dependency目錄。 使用-DincludeScope = runtime將範圍指定爲運行時的原因是,該項目具有對JUnit和EvoSuite的測試依賴關係-但是這些依賴關係都不是爲了爲被測類生成一些測試所必需的,我們只需要 編譯和運行時依賴項。因此,完整的項目類路徑由target / classes中的類和jar文件target / dependency / commons-collections-3.2.2.jar組成。 要創建保存此類路徑的evosuite.properties文件,請使用以下命令:

$EVOSUITE -setup target/classes target/dependency/commons-collections-3.2.2.jar

然後在evosuite.properties文件內的頂部指定路徑

CP=target/classes:target/dependency/commons-collections-3.2.2.jar

首先下載jar包,地址http://www.evosuite.org/downloads/

java -jar evosuite-1.0.6.jar -setup target/classes target/dependency/commons-collections-3.2.2.jar 

在這裏插入圖片描述
使用Evosuite收集數據

一定要記住更改POM文件後,要導入依賴

mvn dependency:copy-dependencies -DincludeScope=runtime

然後編譯

mvn compile
~/IdeaProjects/JdbcDemo » java -jar evosuite-1.0.6.jar -class Tutorial_Experiments.Person                                                              zhengjiani@zhengjianideMacBook-Pro
* EvoSuite 1.0.6
* Going to generate test cases for class: Tutorial_Experiments.Person
* Starting client
* Properties loaded from /Users/zhengjiani/IdeaProjects/JdbcDemo/evosuite-files/evosuite.properties
* Connecting to master process on port 10356
* Analyzing classpath: 
  - target/classes
  - target/dependency/commons-collections-3.2.2.jar
* Finished analyzing classpath
* Generating tests for class Tutorial_Experiments.Person
* Test criteria:
  - Line Coverage
  - Branch Coverage
  - Exception
  - Mutation testing (weak)
  - Method-Output Coverage
  - Top-Level Method Coverage
  - No-Exception Top-Level Method Coverage
  - Context Branch Coverage
* Setting up search algorithm for whole suite generation
* Total number of test goals: 
  - Line 6
  - Branch 3
  - Exception 0
  - MutationFactory 0
  - Output 6
  - Method 3
  - MethodNoException 3
  - CBranchFitnessFactory 3
[Progress:>                             0%] [Cov:>                                  0%]* Using seed 1570678542089
* Starting evolution
[Progress:>                             0%] [Cov:===================================100%]
* Search finished after 0s and 0 generations, 5315 statements, best individual has fitness: 1.0
* Minimizing test suite
* Going to analyze the coverage criteria
* Coverage analysis for criterion LINE
* Coverage of criterion LINE: 100%
* Total number of goals: 6
* Number of covered goals: 6
* Coverage analysis for criterion BRANCH
* Coverage of criterion BRANCH: 100%
* Total number of goals: 3
* Number of covered goals: 3
* Coverage analysis for criterion EXCEPTION
* Coverage of criterion EXCEPTION: 100% (no goals)
* Coverage analysis for criterion WEAKMUTATION
* Coverage of criterion WEAKMUTATION: 100% (no goals)
* Coverage analysis for criterion OUTPUT
* Coverage of criterion OUTPUT: 100%
* Total number of goals: 6
* Number of covered goals: 6
* Coverage analysis for criterion METHOD
* Coverage of criterion METHOD: 100%
* Total number of goals: 3
* Number of covered goals: 3
* Coverage analysis for criterion METHODNOEXCEPTION
* Coverage of criterion METHODNOEXCEPTION: 100%
* Total number of goals: 3
* Number of covered goals: 3
* Coverage analysis for criterion CBRANCH
* Coverage of criterion CBRANCH: 100%
* Total number of goals: 3
* Number of covered goals: 3
* Generated 6 tests with total length 12
* Resulting test suite's coverage: 100% (average coverage for all fitness functions)
* Generating assertions
* Resulting test suite's mutation score: 100%
* Compiling and checking tests
* Writing JUnit test case 'Person_ESTest' to evosuite-tests
* Done!

* Computation finished

查看文件evosuite-report/statistics.csv

該文件爲逗號分隔值格式。 第一行包含顯示各個列所包含內容的標題,然後各行包含實際數據。 第一列包含我們測試的類的名稱(tutorial.Person)。 第二列向我們顯示了我們使用的覆蓋標準–在這種情況下,我們將看到EvoSuite默認使用的標準的完整列表,以分號分隔。 第三列告訴我們已實現的覆蓋率–在這種情況下爲1.0,這意味着我們有100%的覆蓋率(是的!),這是根據覆蓋率目標與總目標的比率計算得出的(最後兩列)。

TARGET_CLASS,criterion,Coverage,Total_Goals,Covered_Goals
Tutorial_Experiments.Person,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,1.0,24,24

讓我們再測試一些類,使用分支覆蓋率

~/IdeaProjects/JdbcDemo » java -jar evosuite-1.0.6.jar -class Tutorial_Experiments.Person -criterion branch                    zhengjiani@zhengjianideMacBook-Pro
* EvoSuite 1.0.6
* Going to generate test cases for class: Tutorial_Experiments.Person
* Starting client
* Properties loaded from /Users/zhengjiani/IdeaProjects/JdbcDemo/evosuite-files/evosuite.properties
* Connecting to master process on port 9487
* Analyzing classpath: 
  - target/classes
  - target/dependency/commons-collections-3.2.2.jar
* Finished analyzing classpath
* Generating tests for class Tutorial_Experiments.Person
* Test criterion:
  - Branch Coverage
* Setting up search algorithm for whole suite generation
[Progress:>                             0%] [Cov:>                                  0%]* Total number of test goals: 3
* Using seed 1570678801008
* Starting evolution
[Progress:>                             0%] [Cov:===================================100%]
* Search finished after 1s and 0 generations, 5395 statements, best individual has fitness: 0.0
* Minimizing test suite
* Going to analyze the coverage criteria
* Coverage analysis for criterion BRANCH
* Coverage of criterion BRANCH: 100%
* Total number of goals: 3
* Number of covered goals: 3
* Generated 2 tests with total length 4
* Resulting test suite's coverage: 100%
* Generating assertions
* Resulting test suite's mutation score: 100%
* Compiling and checking tests
* Writing JUnit test case 'Person_ESTest' to evosuite-tests
* Done!

* Computation finished

然後evosuite-report/statistics.csv文件更新

TARGET_CLASS,criterion,Coverage,Total_Goals,Covered_Goals
Tutorial_Experiments.Person,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,1.0,24,24
Tutorial_Experiments.Person,BRANCH,1.0,3,3
Tutorial_Experiments.Person,BRANCH,1.0,3,3

設置輸出變量

我們可以生成的數據不僅僅是數據文件到目前爲止向我們顯示的列。 EvoSuite具有屬性output_variables,該屬性確定應將哪些值寫入statistics.csv文件。在做這件事之前先刪除舊的.csv文件。

rm evosuite-report/statistics.csv

輸出變量主要有兩種類型1)運行時變量,即爲計算的結果(coverage)。2)而屬性是我們可以設置的輸入屬性。 例如,TARGET_CRITERION和coverage是屬性,而Total_Goals和Covered_Goals是運行時變量。

總而言之,對於我們的實驗,我們希望獲得以下數據

Class under test (TARGET_CLASS)

  • Criteria (criterion) 覆蓋準則
  • Size (Size) 規模
  • Length (Length) 語句長度
  • Mutation score (MutationScore) 變異評分

變量列表以逗號分隔的形式傳遞給output_varibles屬性。 讓我們嘗試一下

~/IdeaProjects/JdbcDemo » java -jar evosuite-1.0.6.jar -class Tutorial_Experiments.Company -criterion branch -Doutput_variables=TARGET_CLASS,criterion,Size,Length,MutationScore
* EvoSuite 1.0.6
* Going to generate test cases for class: Tutorial_Experiments.Company
* Starting client
* Properties loaded from /Users/zhengjiani/IdeaProjects/JdbcDemo/evosuite-files/evosuite.properties
* Connecting to master process on port 13621
* Analyzing classpath: 
  - target/classes
  - target/dependency/commons-collections-3.2.2.jar
* Finished analyzing classpath
* Generating tests for class Tutorial_Experiments.Company
* Test criterion:
  - Branch Coverage
* Setting up search algorithm for whole suite generation
[Progress:>                             0%] [Cov:>                                  0%]* Total number of test goals: 2
* Using seed 1570688573084
* Starting evolution
[Progress:>                             0%] [Cov:===================================100%]
* Search finished after 1s and 0 generations, 4923 statements, best individual has fitness: 0.0
* Minimizing test suite
* Going to analyze the coverage criteria
* Coverage analysis for criterion BRANCH
* Coverage of criterion BRANCH: 100%
* Total number of goals: 2
* Number of covered goals: 2
* Generated 1 tests with total length 2
* Resulting test suite's coverage: 100%
* Generating assertions
* Resulting test suite's mutation score: 100%
* Compiling and checking tests
* Writing JUnit test case 'Company_ESTest' to evosuite-tests
* Done!

* Computation finished

在這裏插入圖片描述

因此,我們剛剛生成了一個包含兩個語句的測試,該測試殺死了爲EvoSuite該類生成的所有突變體。

請注意,該斷言不包括在EvoSuite的語句計數中。 這是因爲斷言不是作爲基於搜索的測試生成的一部分而生成的,而是在後處理步驟中添加的。

在這裏插入圖片描述
運行一個實驗

EvoSuite是隨機的:如果連續運行兩次,您將獲得不同的結果。 這也意味着,如果您在一次運行中得到一個非常大的測試套件,那麼在下一輪中您可能會獲得一個具有不同大小的測試套件。 通常,當我們使用隨機算法時,我們需要進行重複操作,並對統計數據進行統計分析。 因此,我們將對所有類進行測試,並重復10次。 此外,我們需要重複兩次,一次僅使用分支覆蓋,一次使用默認條件。

在開始實驗前,還是要刪除舊的.csv文件

使用-prefix表示測試包前綴,我實驗無效。。。

~/IdeaProjects/JdbcDemo » java -jar evosuite-1.0.6.jar -criterion branch -prefix Tutorial_ -Doutput_variables=TARGET_CLASS,criterion,Size,Length,MutationScore

在這裏插入圖片描述

我們可以使用-Dconfiguration_id = <name>語法告訴EvoSuite爲正在運行的特定配置添加名稱,然後將該屬性包含在輸出變量中。 因此,要運行實驗,我們需要以下兩個命令,一個用於分支覆蓋,一個用於默認組合

~/IdeaProjects/JdbcDemo » java -jar evosuite-1.0.6.jar -criterion branch -prefix Tutorial_Experiments -Doutput_variables=TARGET_CLASS,criterion,Size,Length,MutationScore

~/IdeaProjects/JdbcDemo » java -jar evosuite-1.0.6.jar -Dconfiguration_id=Default -criterion branch -prefix Tutorial_Experiments -Doutput_variables=configuration_id,TARGET_CLASS,criterion,Size,Length,MutationScore

現在輸出中有configuration_id了
在這裏插入圖片描述

我們需要確定的不是在一種特定的運行中一種配置是否優於另一種配置,而是平均而言。 因此,我們需要重複幾次實驗,並做一些更嚴格的分析。

一種簡單的重複方法是將調用簡單地包裝在bash循環中以運行它,例如5次

~/IdeaProjects/JdbcDemo » for I in {1..5}; do java -jar evosuite-1.0.6.jar -Dconfiguration_id=Branch -criterion branch -prefix Tutorial_Experiments -Doutput_variables=TARGET_CLASS,criterion,Size,Length,MutationScore ; done 
-------------------------兩條命令啊,分兩次執行-------------------------------------------
for I in {1..5}; do java -jar evosuite-1.0.6.jar -Dconfiguration_id=Default  -prefix Tutorial_Experiments -Doutput_variables=configuration_id,TARGET_CLASS,criterion,Size,Length,MutationScore ; done

後期還是用腳本寫吧。。。在控制檯裏太造孽了

這將需要一段時間。 實際上,對於嚴肅的實驗而言,重複5次甚至不是一個合適的數目,理想情況下,您希望重複30次或更多次才能獲得代表性的結果。 稍後我們將討論如何進行較大的實驗。

您可能會注意到分支覆蓋範圍的運行速度更快–這是因爲EvoSuite一旦達到100%的分支覆蓋範圍,就會停止生成測試。 默認配置將包括一些不可行的測試目標,即沒有測試的測試目標,在這種情況下,EvoSuite將嘗試生成測試,直到用盡整個時間預算。

第一行命令的執行結果

TARGET_CLASS,criterion,Size,Length,MutationScore
Tutorial_Experiments.SavingsAccount,BRANCH,3,8,0.7058823529411765
Tutorial_Experiments.BankAccount,BRANCH,2,6,0.8
Tutorial_Experiments.Company,BRANCH,1,2,1.0
Tutorial_Experiments.Owner,BRANCH,1,1,1.0
Tutorial_Experiments.CurrentAccount,BRANCH,2,7,0.6739130434782609
Tutorial_Experiments.Bank,BRANCH,4,15,0.8
Tutorial_Experiments.ATMCard,BRANCH,8,40,0.6666666666666666
Tutorial_Experiments.Person,BRANCH,2,4,0.0
Tutorial_Experiments.ATM,BRANCH,10,72,0.3888888888888889
Tutorial_Experiments.SavingsAccount,BRANCH,3,9,0.7058823529411765
Tutorial_Experiments.BankAccount,BRANCH,2,6,0.8
Tutorial_Experiments.Company,BRANCH,1,2,1.0
Tutorial_Experiments.Owner,BRANCH,1,1,1.0
Tutorial_Experiments.CurrentAccount,BRANCH,2,7,0.6956521739130435
Tutorial_Experiments.Bank,BRANCH,4,11,0.8
Tutorial_Experiments.ATMCard,BRANCH,8,48,0.6666666666666666
Tutorial_Experiments.Person,BRANCH,2,4,0.0
Tutorial_Experiments.ATM,BRANCH,10,74,0.4166666666666667
Tutorial_Experiments.SavingsAccount,BRANCH,2,7,0.8529411764705882
Tutorial_Experiments.BankAccount,BRANCH,2,6,0.8
Tutorial_Experiments.Company,BRANCH,1,2,1.0
Tutorial_Experiments.Owner,BRANCH,1,1,1.0
Tutorial_Experiments.CurrentAccount,BRANCH,2,7,0.6304347826086957
Tutorial_Experiments.Bank,BRANCH,4,13,0.8
Tutorial_Experiments.ATMCard,BRANCH,8,40,0.6666666666666666
Tutorial_Experiments.Person,BRANCH,2,4,0.0
Tutorial_Experiments.ATM,BRANCH,9,70,0.5277777777777778
Tutorial_Experiments.SavingsAccount,BRANCH,3,9,0.7352941176470589
Tutorial_Experiments.BankAccount,BRANCH,2,6,0.8
Tutorial_Experiments.Company,BRANCH,1,2,1.0
Tutorial_Experiments.Owner,BRANCH,1,1,1.0
Tutorial_Experiments.CurrentAccount,BRANCH,3,9,0.5652173913043478
Tutorial_Experiments.Bank,BRANCH,4,15,0.8
Tutorial_Experiments.ATMCard,BRANCH,8,43,0.6666666666666666
Tutorial_Experiments.Person,BRANCH,2,4,0.0
Tutorial_Experiments.ATM,BRANCH,9,68,0.5555555555555556
Tutorial_Experiments.SavingsAccount,BRANCH,3,9,0.6176470588235294
Tutorial_Experiments.BankAccount,BRANCH,2,6,0.8
Tutorial_Experiments.Company,BRANCH,1,2,1.0
Tutorial_Experiments.Owner,BRANCH,1,1,1.0
Tutorial_Experiments.CurrentAccount,BRANCH,2,9,0.7391304347826086
Tutorial_Experiments.Bank,BRANCH,4,9,0.8
Tutorial_Experiments.ATMCard,BRANCH,8,24,0.6666666666666666
Tutorial_Experiments.Person,BRANCH,2,4,0.0
Tutorial_Experiments.ATM,BRANCH,10,76,0.3333333333333333

第二行命令的執行結果

configuration_id,TARGET_CLASS,criterion,Size,Length,MutationScore
Default,Tutorial_Experiments.BankAccount,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,7,23,1.0
Default,Tutorial_Experiments.Company,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,3,6,1.0
Default,Tutorial_Experiments.Owner,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,1,1,1.0
Default,Tutorial_Experiments.CurrentAccount,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,3,13,0.9130434782608695
Default,Tutorial_Experiments.Bank,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,4,9,0.8
Default,Tutorial_Experiments.ATMCard,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,14,77,0.6666666666666666
Default,Tutorial_Experiments.Person,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,6,12,1.0
Default,Tutorial_Experiments.ATM,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,16,123,0.4166666666666667
Default,Tutorial_Experiments.SavingsAccount,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,4,13,0.9411764705882353
Default,Tutorial_Experiments.BankAccount,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,7,22,1.0
Default,Tutorial_Experiments.Company,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,3,6,1.0
Default,Tutorial_Experiments.Owner,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,1,1,1.0
Default,Tutorial_Experiments.CurrentAccount,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,4,12,0.9130434782608695
Default,Tutorial_Experiments.Bank,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,4,15,0.8
Default,Tutorial_Experiments.ATMCard,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,13,63,0.6666666666666666
Default,Tutorial_Experiments.Person,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,6,12,1.0
Default,Tutorial_Experiments.ATM,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,16,118,0.4166666666666667
Default,Tutorial_Experiments.SavingsAccount,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,4,10,0.9411764705882353
Default,Tutorial_Experiments.BankAccount,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,8,23,1.0
Default,Tutorial_Experiments.Company,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,3,6,1.0
Default,Tutorial_Experiments.Owner,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,1,1,1.0
Default,Tutorial_Experiments.CurrentAccount,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,3,12,0.8043478260869565
Default,Tutorial_Experiments.Bank,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,4,11,0.8
Default,Tutorial_Experiments.ATMCard,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,14,70,0.6666666666666666
Default,Tutorial_Experiments.Person,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,6,12,1.0
Default,Tutorial_Experiments.ATM,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,15,111,0.4166666666666667
Default,Tutorial_Experiments.SavingsAccount,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,3,11,0.9411764705882353
Default,Tutorial_Experiments.BankAccount,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,8,24,1.0
Default,Tutorial_Experiments.Company,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,3,6,1.0
Default,Tutorial_Experiments.Owner,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,1,1,1.0
Default,Tutorial_Experiments.CurrentAccount,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,3,10,0.8695652173913043
Default,Tutorial_Experiments.Bank,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,4,9,0.8
Default,Tutorial_Experiments.ATMCard,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,14,68,0.6666666666666666
Default,Tutorial_Experiments.Person,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,6,12,0.0
Default,Tutorial_Experiments.ATM,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,14,105,0.5277777777777778
Default,Tutorial_Experiments.SavingsAccount,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,4,13,0.9411764705882353
Default,Tutorial_Experiments.BankAccount,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,7,21,1.0
Default,Tutorial_Experiments.Company,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,3,6,1.0
Default,Tutorial_Experiments.Owner,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,1,1,1.0
Default,Tutorial_Experiments.CurrentAccount,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,3,8,0.8695652173913043
Default,Tutorial_Experiments.Bank,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,4,12,0.8
Default,Tutorial_Experiments.ATMCard,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,14,66,0.6666666666666666
Default,Tutorial_Experiments.Person,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,6,12,0.0
Default,Tutorial_Experiments.ATM,LINE;BRANCH;EXCEPTION;WEAKMUTATION;OUTPUT;METHOD;METHODNOEXCEPTION;CBRANCH,17,131,0.3611111111111111

分析結果

easy_install numpy
easy_install matplotlib
easy_install pandas

上面結果太亂,我們用python寫個腳本來分析一下,腳本應該和statistics.csv文件放在一起並且命名爲analy-data.py

#!/usr/bin/python

import matplotlib.pyplot as plt
import pandas as pd

df = pd.read_csv('statistics.csv') # Make sure the path is correct
bp = df.boxplot(column='Size', by='configuration_id')
bp = df.boxplot(column='Length', by='configuration_id')
bp = df.boxplot(column='MutationScore', by='configuration_id')
plt.show()

最後一條命令(plt.show())將使用matplotlib打開三個圖的三個窗口。在所有圖中,我們可以清楚地看到,分支覆蓋範圍平均產生的測試更少,語句更少,並且這些測試的突變得分更低。

執行python3 analy-data.py
在這裏插入圖片描述

儘管在箱圖中可以看到這種差異,但是在科學的背景下,最好還是使用統計分析來證明這種差異。特別是,我們通常希望量化效果的大小,並且希望量化對差異的信心。對於這些值中的第一個,可以使用不同的效果大小測量。讓我們使用[Cohen’s-d(https://en.wikiversity.org/wiki/Cohen%27s_d)],它是[-1,1]範圍內的值。爲了量化我們對結果的信心,我們將使用衆所周知的[p值(https://en.wikipedia.org/wiki/P-value)],這是觀察到的結果無效的可能性我們實際測試的內容。要計算p值,我們需要選擇適當的統計檢驗。讓我們使用Wilcoxon等級檢驗,但統計檢驗的選擇實際上超出了本教程。幸運的是,統計測試可以作爲SciPy的一部分使用,因此請確保已安裝.

pip install scipy

我們執行統計測試所需要做的就是創建值數組,並將其作爲參數傳遞給scipy.stats.wilcoxon函數,該函數隨後將爲我們提供p值。 通常,小於0.05的p值被視爲具有統計意義的結果的證據,因此這就是我們所希望的。

爲了產生用於統計檢驗的輸入數組,我們可以再次使用pandas庫; 我們只需要選擇數據的子集。 例如,要選擇屬於默認配置的所有數據,我們將使用df [df ['configuration_id] ==‘Default’]過濾數據集。 在結果數據中,我們可以選擇列,例如 尺寸。 要計算Cohen的d,我們只需從Stackoverflow中提取一個片段:

#!/usr/bin/python

import pandas as pd
from scipy.stats import wilcoxon
from numpy import mean, std # version >= 1.7.1 && <= 1.9.1
from math import sqrt

# From http://stackoverflow.com/questions/21532471/how-to-calculate-cohens-d-in-python
def cohen_d(x,y):
  return (mean(x) - mean(y)) / sqrt((std(x, ddof=1) ** 2 + std(y, ddof=1) ** 2) / 2.0)


df = pd.read_csv('statistics.csv')

cat1 = df[df['configuration_id']=='Default']
cat2 = df[df['configuration_id']=='Branch']

for column in ['Size', 'Length', 'MutationScore']:
  print "%s: %.2f (%f)" % (column, cohen_d(cat1[column], cat2[column]), wilcoxon(cat1[column], cat2[column]).pvalue)

這個代碼我運行後報錯。。。有知道的小夥伴可以告訴我。。。

~/IdeaProjects/JdbcDemo/evosuite-report » python3 analy-data1.py                                                              zhengjiani@zhengjianideMacBook-Pro
Traceback (most recent call last):
  File "analy-data1.py", line 15, in <module>
    print(column, cohen_d(cat1[column], cat2[column]), wilcoxon(cat1[column], cat2[column]).pvalue)
  File "/usr/local/lib/python3.7/site-packages/scipy/stats/morestats.py", line 2848, in wilcoxon
    raise ValueError('The samples x and y must have the same length.')
ValueError: The samples x and y must have the same length.

其他有用的變量【這個實驗我沒有做,感興趣的可以看哈】

要獲得可用輸出變量的完整概述,當前最好的地方是源代碼,尤其是文件[RuntimeVariable.java(https://github.com/EvoSuite/evosuite/blob/master/client/src/main/java/org/evosuite/statistics/RuntimeVariable.java)]。

例如,如果您想知道某些值隨時間變化的方式,可以使用時間軸變量爲您捕獲這些數據。 假設我們想了解分支覆蓋範圍在搜索的前30秒如何演變,並且我們想每秒採樣一次。 爲此,我們將添加一個輸出變量“ CoverageTimeline”,並使用-Dtimeline_interval = 1000指定採樣間隔:

當我們指定總共30秒的時間預算(-Dsearch_budget = 30)時,statistics.csv文件現在將具有30列標記爲CoverageTimeline_T1的列,直到CoverageTimeline_T30,並分別顯示搜索的每一秒的值。

再舉一個有趣的例子,BranchCoverageBitString變量將產生一個字符串“ 0”和“ 1”,其中每個數字代表程序中的一個分支,而1則表示該分支已被覆蓋。 該位串使我們能夠比較特定分支是否被特定配置覆蓋。

運行大型實驗《並行化》

運行大型實驗時,EvoSuite在命令行上顯示的進度條將浪費日誌文件中的空間。通過添加-Dshow_progress = false禁用它。
當並行運行多個EvoSuite作業時,請確保它們不要嘗試寫入同一evosuite-report / statistics.csv,因爲同時訪問會破壞該文件。而是使用屬性-Dreport_dir = <目錄>爲不同的作業設置不同的目錄。實驗完成後,您將需要再次將單個結果文件聚合到一個大數據文件中。

擴展EvoSuite(以下大部分內容爲翻譯)

主要從下面4個方面擴展

  • Building EvoSuite
  • Modifying the search algorithm 改變搜索算法
  • Adding new fitness functions 增加新的適應度函數
  • Adding new runtime variables 增加新的運行時變量

預先準備

  • A git client to check out the EvoSuite source code
  • JDK (version 8)
  • Apache Maven (version 3.1 or newer)
  • An IDE (e.g., IntelliJ or Eclipse) in order to edit the source code

獲取Evosuite的源碼

git clone https://github.com/EvoSuite/evosuite.git

源代碼被組織成幾個Maven子模塊。 也就是說,剛簽出的源代碼的主目錄中有一個父pom.xml,然後在子目錄中有幾個單獨的子項目。 讓我們仔細看一下主要的子模塊

master:EvoSuite使用主客戶端架構,因爲執行隨機生成的測試時可能會出錯(例如,我們可能會耗盡內存)。 客戶端會不時地將當前的搜索結果發送到主進程,這樣即使出現問題,最終我們仍然會進行一些測試。 主模塊處理命令行上的用戶輸入(例如,解析命令行選項),然後生成客戶端進程以進行實際的測試生成。

client:客戶端承擔了所有繁重的工作。 遺傳算法位於此處,它是算法使用的測試用例和測試套件的內部表示形式,搜索運算符,執行測試用例的機制,生成跟蹤信息以從中計算適用性值所需的所有字節碼工具。

runtime:這是運行時庫,即確定測試執行確定性所需的所有工具,模擬的Java API等。

plugins:這裏有幾個子項目,它們是各種第三方工具(如Maven,IntelliJ,Eclipse或Jenkins)的插件。

除了這些Maven模塊之外,還有其他幾個模塊或子目錄。 通常,您將不需要訪問其中任何一個,但是如果您好奇它們是什麼,則可以

standalone_runtime:該庫中沒有源代碼,這只是一個Maven子模塊,它生成一個獨立的jar文件,即,其中包含運行時庫的所有依賴項

shaded:這裏也沒有源代碼。 這是一個Maven模塊,它生成EvoSuite的版本,其中,包名稱從org.evosuite重命名爲其他名稱。 這是爲了允許將EvoSuite應用於自身(否則將無法正常運行,因爲EvoSuite拒絕使用其自己的代碼)。

generated:這是一個子模塊,我們在其中放置EvoSuite生成的測試以測試EvoSuite。 這項工作仍在進行中。

release_results:這不是Maven子模塊,它只是代表我們每次執行發佈時在SF110數據集上進行的實驗結果的數據集合。

src:這裏沒有Java源代碼,只有一些與Maven相關的元數據。

removed:一些源代碼文件未在主源代碼樹中使用,但對於保留作爲參考很有用。

構建EvoSuite

mvn compile

IDE很可能會自動爲您執行此操作。 但是,重要的是您的IDE支持Maven,並且已將項目配置爲Maven項目。 如果您尚未執行此操作,則會收到錯誤消息,提示編譯器無法在org.evosuite.xsd包中找到類。 jaxb會基於XML模式自動生成這些類,只有在您使用Maven正確編譯了項目的情況下,才能完成這些類。

回顧本教程的第1部分,EvoSuite發行版包含兩個jar文件-一個具有獨立的運行時依賴項,另一個用於測試生成。 您可以通過調用以下命令生成它們:

mvn package

EvoSuite jar文件主要由以下主子模塊生成:master / target / evosuite-master-1.0.4-SNAPSHOT.jar。 您可以通過使用Java調用可執行文件來驗證這種情況。(這一步我就不做了。。)

java -jar master/target/evosuite-master-1.0.4-SNAPSHOT.jar

省略一部分,直接看擴展遺傳算法

擴展遺傳算法

現在,讓我們對EvoSuite進行一些更改。 我們將考慮的第一個示例場景是實際的搜索算法。 您可能知道,EvoSuite使用遺傳算法來驅動測試生成。 簡而言之,這意味着存在大量候選解決方案(染色體,在這種情況下爲測試套件),並且這些測試套件是使用旨在模擬自然進化的搜索運算符進行進化的。 適應度函數估計每個候選解決方案的質量。 優勝劣汰的個體繁殖的可能性最高,如果選擇繁殖的個體,那麼兩個母體個體將使用交叉算子組合在一起以產生兩個新的子孫個體,然後突變對這些子代進行較小的改變。

所有這些都在org.evosuite.ga軟件包的客戶端模塊中實現。 有一個抽象的超類org.evosuite.ga.metaheuristics,然後有幾個具體的實現,例如StandardGA,SteadyStateGA或EvoSuite的默認值MonotonicGA。 如果查看GeneticAlgorithm類,您將看到搜索算法具有很多成員,例如選擇運算符selectionFunction,交叉運算符crossoverFunction和總體(種羣)。 種羣是一個列表,因爲根據其適合度對個人進行排名; 該值由FitnessFunctions計算。 反過來,這是一個列表,因爲EvoSuite通常同時使用多個適應功能,並且每個適應功能都有一個適應值。

如果您想了解有關遺傳算法如何工作的更多詳細信息,可以閱讀[https://www.cs.colostate.edu/~genitor/MiscPubs/tutorial.pdf(或網絡上無數的一些教程)。

如您所見,默認情況下,GeneticAlgorithm類使用SinglePointCrossOver實例化。 讓我們仔細看看該類的外觀–在編輯器中打開org.evosuite.ga.operators.crossover.SinglePointCrossover類。 該類擴展了抽象類CrossOverFunction,並實現了crossOver方法。 該方法接收兩個個體作爲父級,並隨機選擇兩個交叉點point1和point2,兩個個體中的每一個。 然後,它克隆了父母,並在生成的個體上調用了交叉方法來完成實際工作。 這就是元啓發式搜索算法的優點:該算法與染色體代表的無關。

假設我們要實現一個替代的交叉算子,該算子總是在中間切掉染色體,而現有的交叉算子全都選擇隨機的交換點。 讓我們在客戶端模塊(文件client / src / main / java / org / evosuite / ga / operators / crossover / MiddleCrossOver.java)中創建一個新的Java類org.evosuite.ga.operators.crossover.MiddleCrossOver。 該類應擴展抽象類CrossOverFunction,這意味着它必須實現方法crossOver。 因此,骨架看起來像這樣
文件所在位置evosuite/client/src/main/java/org/evosuite/ga/operators/crossover/MiddleCrossOver

package org.evosuite.ga.operators.crossover;
import org.evosuite.ga.Chromosome;
import org.evosuite.ga.ConstructionFailedException;

public class MiddleCrossOver extends CrossOverFunction {
    @Override
    public void crossOver(Chromosome parent1, Chromosome parent2) throws ConstructionFailedException {
        // TODO
        // 檢查個體是否有多個測試用例
        if (parent1.size()<2||parent2.size()<2){
            return;
        }
        // 計算兩個親本染色體各自的中間值
        int middle1 = (int)Math.round(parent1.size() / 2.0);
        int middle2 = (int)Math.round(parent2.size() / 2.0);
        // Evosuite的交叉算子會在原處更改染色體,因此創建父母的副本給子代
        Chromosome t1 = parent1.clone();
        Chromosome t2 = parent2.clone();
        // 使用crossover方法更改後代,1,使用與之相交的另一條染色體作爲參數。2,調用該方法的染色體中的交點。3,與該方法相交的交點
        parent1.crossOver(t2,middle1,middle2);
        parent2.crossOver(t1,middle2,middle1);
    }
}

爲了實現這種交叉功能,我們需要了解一個重要方面:遺傳算法的教科書示例通常會假設染色體中固定數量的基因。 但是,與遺傳算法的許多其他標準應用程序不同,EvoSuite中的個體大小可能會有所不同,因爲我們甚至在開始搜索之前就無法知道正確數量的測試用例。 因此,每個個體的“中間”是不同的

它行得通嗎? 讓我們寫一個測試案例來找出答案。 讓我們添加一個新文件client / src / test / java / org / evosuite / ga / operators / crossover / MiddleCrossOverTest.java

package org.evosuite.ga.operators;

import static org.junit.Assert.*;

import org.evosuite.Properties;
import org.junit.Test;
public class MiddleCrossOverTest{
    @Test
    public void testSinglePointCrossOver() throws ConstructionFailedException {
        DummyChromosome parent1 = new DummyChromosome(1,2,3,4);
        Dummychromosome parent2 = new DummyChromosome(5,6);

        MiddleCrossOver xover = new MiddleCrossOver();

        DummyChromosome offspring1 = new DummyChromosome(parent1);
        DummyChromosome offspring2 = new DummyChromosome(parent2);

        xover.crossOver(offspring1,offspring2);

        assertEquals(Arrays.asList(1,2,6),offspring1.getGenes());
        assertEquals(Arrays.asList(5,3,4),offspring2.getGenes());
    }
}

客戶端模塊中的測試具有用於測試的DummyChromosome實現。 DummyChromosome需要一個整數列表,並進行突變和交叉。 例如,我們可以爲不同大小(例如4和2)的父母創建,然後檢查生成的個體是否具有正確的基因。 例如,測試可能如下所示

添加新的覆蓋率標準和適應度函數

例如正交測試(pairwise testing)中我們要覆蓋所有的方法調用對。

public class Foo {
    public void bar() { ... }
    public void foo() { ... }
    public void zoo() { ... }
}

根據默認的覆蓋標準,EvoSuite的目標是儘可能全面覆蓋這三種方法。 有了成對方法覆蓋的新思想,我們希望EvoSuite還可以創建對象,這些對象依次調用bar和foo,bar和zoo以及foo和zoo。

EvoSuite中的覆蓋標準作爲適應性函數實現。 對於每個覆蓋標準,有三個主要類別

  • Test suite適應度函數,該準則指導在測試套件空間中進行搜索,以實現對準則的完全覆蓋。
  • Test case適應度函數,它指導在測試用例空間中進行搜索,以實現單個覆蓋目標。 這也可用於確定測試套件是否涵蓋單個覆蓋目標。
  • Test goal factory,產生一組測試用例的適應度函數,當測試套件覆蓋了每個測試用例的適應度函數時,同時,這些測試套件也有最佳適應度函數。

您可以在org.evosuite.coverage包的客戶端模塊中找到大量示例。

讓我們添加一個新包:org.evosuite.coverage.methodpair。 我們將從爲單個測試添加適應度函數開始。 儘管EvoSuite的默認設置是演化測試套件而不是單個測試,但是EvoSuite也可以演化包含個體的種羣,例如,使用基線方法-generateTests,或使用新的多目標“ MOSA”方法-generateMOSuite。 此外,即使EvoSuite開發了測試套件,所有後處理都要求將覆蓋標準表示爲一組測試適用性函數。 創建類org.evosuite.coverage.methodpair.MethodPairTestFitness。 此類將從org.evosuite.testcase.TestFitnessFunction繼承

文件所在位置evosuite/client/src/main/java/org/evosuite/coverage/mehodpair/MethodPairTestFitness

public class MethodPairTestFitness extends TestFitnessFunction {
    private final String className;
    private final String methodName1;
    private final String methodName2;

    public MethodPairTestFitness(String className, String methodName1, String methodName2) {
        this.className = className;
        this.methodName1 = methodName1;
        this.methodName2 = methodName2;
    }

    public String getClassName() {
        return className;
    }

    public String getMethodName1() {
        return methodName1;
    }

    public String getMethodName2() {
        return methodName2;
    }
    @Override
    public double getFitness(TestChromosome individual, ExecutionResult result) {

        double fitness = 1.0;
        Set<Integer> exceptionPositions = result.getPositionsWhereExceptionsWereThrown();
        for (Statement stmt : result.test) {
            // TODO: check if we have hit a pair
            if ((stmt instanceof MethodStatement || stmt instanceof ConstructorStatement)) {
                // TODO: Handle name of method
                EntityWithParametersStatement ps = (EntityWithParametersStatement)stmt;
                String className  = ps.getDeclaringClassName();
                String methodName = ps.getMethodName() + ps.getDescriptor();

                if(haveSeenMethod1) {
                    if (this.className.equals(className) && this.methodName2.equals(methodName)) {
                        fitness = 0.0;
                        break;
                    }
                } else if (this.className.equals(className) && this.methodName1.equals(methodName)) {
                    haveSeenMethod1 = true;
                    fitness = 0.5;
                } else {
                    haveSeenMethod1 = false;
                }
            }
            if(exceptionPositions.contains(stmt.getPosition()))
                break;


        }

        updateIndividual(this, individual, fitness);
        return fitness;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        MethodPairTestFitness that = (MethodPairTestFitness) o;

        if (className != null ? !className.equals(that.className) : that.className != null) return false;
        if (methodName1 != null ? !methodName1.equals(that.methodName1) : that.methodName1 != null) return false;
        return methodName2 != null ? methodName2.equals(that.methodName2) : that.methodName2 == null;

    }

    @Override
    public int hashCode() {
        int result = className != null ? className.hashCode() : 0;
        result = 31 * result + (methodName1 != null ? methodName1.hashCode() : 0);
        result = 31 * result + (methodName2 != null ? methodName2.hashCode() : 0);
        return result;
    }

    @Override
    public int compareTo(TestFitnessFunction other) {
        if (other instanceof MethodPairTestFitness) {
            MethodPairTestFitness otherMethodFitness = (MethodPairTestFitness) other;
            if (className.equals(otherMethodFitness.getClassName())) {
                if(methodName1.equals(otherMethodFitness.getMethodName1()))
                    return methodName2.compareTo(otherMethodFitness.getMethodName2());
                else
                    return methodName1.compareTo(otherMethodFitness.getMethodName1());
            }
            else
                return className.compareTo(otherMethodFitness.getClassName());
        }
        return compareClassName(other);
    }
}

到目前爲止,這很容易。適應度函數功能的主要部分是getFitness方法,我們必須重寫該方法。

這是重載的方法;有一個版本將TestChromosome作爲輸入,而另一個版本將TestChromosomeExecutionResult作爲輸入。

org.evosuite.testcase.TestChromosome類是方法調用序列的遺傳編碼。

如果查看該類,將看到它包含類org.evosuite.testcase.TestCase的測試用例,然後TestChromosome的主要功能在於mutate和crossover方法。

反過來,TestCase接口由org.evosuite.testcase.DefaultTestCase類實現,該類由org.evosuite.testcase.Statement實現的列表組成。在org.evosuite.testcase.statements包中實現了各種不同類型的語句,最好再仔細研究一下該包。對於每個語句類,最關鍵的功能可能是execute方法的實現,這是Java Reflectionon用於執行測試的地方。每個語句類還利用許多VariableReference實例-這些是測試中使用的變量,並指向由測試的語句創建的對象。在EvoSuite中,每個語句都創建一個這樣的VariableReference-無效方法調用除外。

爲了創建method-pair覆蓋率,我們需要看的兩個語句是ConstructorStatementMethodStatement。顧名思義,它們分別調用構造函數和方法。此信息由以下三種方法提供:getDeclaringClassgetMethodNamegetDescriptor。什麼是描述符?描述符表示方法所採用的參數及其返回的值(請參閱[StackOverflow說明(http://stackoverflow.com/questions/7526483/what-is-the-difference-between-descriptor-and-signature)]] )。例如,如果我們有一個方法將兩個整數作爲輸入並返回一個布爾值,則描述符將爲“(II)Z”,其中I代表一個整數,Z則爲布爾值。對我們而言,最重要的是描述符使我們能夠區分重載方法。由於這通常需要在EvoSuite中完成,因此在大多數情況下,EvoSuite實際上使用方法名稱和描述符的串聯,而不僅僅是普通方法名稱。

org.evosuite.coverage.methodpair.MethodPairFactory

public class MethodPairFactory extends AbstractFitnessFactory<MethodPairTestFitness> {

    // 該方法是創建TestFitnessFunctions列表的工廠方法。
    @Override
    public List<MethodPairTestFitness> getCoverageGoals() {
        List<MethodPairTestFitness> goals = new ArrayList<>();

        // pair each constructor with each method and add to goals

        // pair each method with each other method and add to goals

        return goals;
    }

    // 假設我們有一個輔助方法getUsableConstructors,該方法返回給定類的所有公共構造函數,以及一個getUsableMethods使用Java反射返回給定類的所有公共方法的方法。
    // 通過訪問我們可以獲取正在測試的類Properties.getTargetClass(),其名稱存儲在中Properties.TARGET_CLASS。
    @Override
    public List<MethodPairTestFitness> getCoverageGoals() {
        List<MethodPairTestFitness> goals = new ArrayList<>();

        String className = Properties.TARGET_CLASS;
        Class<?> clazz = Properties.getTargetClass();
        Set<String> constructors = getUsableConstructors(clazz);
        Set<String> methods      = getUsableMethods(clazz);

        for(String constructor : constructors)
            for(String method : methods)
                goals.add(new MethodPairTestFitness(className, constructor, method));

        for(String method1 : methods)
            for(String method2 : methods)
                goals.add(new MethodPairTestFitness(className, method1, method2));

        return goals;
    }

    protected Set<String> getUsableConstructors(Class<?> clazz) {
        Set<String> constructors = new LinkedHashSet<>();
        Constructor<?>[] allConstructors = clazz.getDeclaredConstructors();
        for (Constructor<?> c : allConstructors) {
            if (TestUsageChecker.canUse(c)) {
                String methodName = "<init>" + Type.getConstructorDescriptor(c);
                constructors.add(methodName);
            }
        }
        return constructors;
    }

    protected Set<String> getUsableMethods(Class<?> clazz) {
        Set<String> methods = new LinkedHashSet<>();
        Method[] allMethods= clazz.getDeclaredMethods();
        for (Method m : allMethods) {
            if (TestUsageChecker.canUse(m)) {
                String methodName = m.getName()+ Type.getMethodDescriptor(m);
                methods.add(methodName);
            }
        }
        return methods;
    }
}

MethodPairSuiteFitness

public class MethodPairSuiteFitness extends TestSuiteFitnessFunction {

    private final Set<MethodPairTestFitness> allMethodPairs = new HashSet<>();
    @Override
    public double getFitness(AbstractTestSuiteChromosome<? extends ExecutableChromosome> suite) {
        double fitness = 0.0;

        // TODO: calculate fitness value
        List<ExecutionResult> results = runTestSuite(suite);
        Set<MethodPairTestFitness> coveredMethodPairs = new HashSet<>();
        for(MethodPairTestFitness goal : allMethodPairs) {
            for(ExecutionResult result : results) {
                if(goal.isCovered(result)) {
                    coveredMethodPairs.add(goal);
                    break;
                }
                if (result.hasTimeout() || result.hasTestException()) {
                    fitness = allMethodPairs.size();
                    break;
                }
            }
        }
        fitness = methodPairGoals.size() - coveredMethodPairs.size();


        updateIndividual(this, suite, fitness);
        suite.setNumOfCoveredGoals(this, coveredMethodPairs.size());
        if (!allGoals.isEmpty())
            suite.setCoverage(this, (double) calledMethodPairs.size() / (double) methodPairGoals.size());
        else
            suite.setCoverage(this, 1.0);
        return fitness;
    }

    public MethodPairSuiteFitness() {
        methodPairGoals.addAll(new MethodPairFactory().getCoverageGoals());
    }
}

master / src / test / java / org / evosuite / coverage / methodpair / MethodPairCoverageSystemTest進行測試

public class MethodPairCoverageSystemTest extends SystemTestBase {

    // TODO
    public class SingleMethod {     
    public String foo(){
        return "foo";
    }
	}
	@Test
	public void testMethodFitnessSimpleExample() {
    EvoSuite evosuite = new EvoSuite();

    String targetClass = SingleMethod.class.getCanonicalName();
    Properties.TARGET_CLASS = targetClass;
    Properties.CRITERION = new Properties.Criterion[]{Properties.Criterion.METHODPAIR};
    String[] command = new String[] { "-generateSuite", "-class", targetClass };
    Object result = evosuite.parseCommandLine(command);
    GeneticAlgorithm<?> ga = getGAFromResult(result);
    TestSuiteChromosome best = (TestSuiteChromosome) ga.getBestIndividual();   
    System.out.println("EvolvedTestSuite:\n" + best);
    for(TestFitnessFunction goal : 		  TestGenerationStrategy.getFitnessFactories().get(0).getCoverageGoals()) {
        System.out.println("Goal: "+goal);
    }
    int goals = TestGenerationStrategy.getFitnessFactories().get(0).getCoverageGoals().size(); // assuming single fitness function
    Assert.assertEquals(2, goals );
    Assert.assertEquals("Non-optimal coverage: ", 1d, best.getCoverage(), 0.001);

}

具體參考官網哦,十分詳細的http://www.evosuite.org/documentation/tutorial-part-4/

我也正在研究這部分,有興趣的可以一起交流~

最後附上我的pom.xml文件的最終配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>groupId</groupId>
    <artifactId>JdbcDemo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>6.0.6</version>
        </dependency>
        <dependency>
            <groupId>org.evosuite</groupId>
            <artifactId>evosuite-standalone-runtime</artifactId>
            <version>${evosuiteVersion}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency> <!-- For the sake of having a dependency -->
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2.2</version>
        </dependency>
    </dependencies>


   <build>
       <pluginManagement>
           <plugins>
               <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>
               <plugin>
                   <groupId>org.apache.maven.plugins</groupId>
                   <artifactId>maven-surefire-plugin</artifactId>
                   <version>2.17</version>
                   <configuration>
                       <properties>
                           <property>
                               <name>listener</name>
                               <value>org.evosuite.runtime.InitializingListener</value>
                           </property>
                       </properties>
                   </configuration>
               </plugin>
               <plugin>
                   <groupId>org.codehaus.mojo</groupId>
                   <artifactId>build-helper-maven-plugin</artifactId>
                   <version>1.8</version>
                   <executions>
                       <execution>
                           <id>add-test-source</id>
                           <phase>generate-test-sources</phase>
                           <goals>
                               <goal>add-test-source</goal>
                           </goals>
                           <configuration>
                               <sources>
                                   <source>${customFolder}</source>
                               </sources>
                           </configuration>
                       </execution>
                   </executions>
               </plugin>
               <plugin>
                   <groupId>org.apache.maven.plugins</groupId>
                   <artifactId>maven-surefire-plugin</artifactId>
                   <version>2.17</version>
                   <configuration>
                       <properties>
                           <property>
                               <name>listener</name>
                               <value>org.evosuite.runtime.InitializingListener</value>
                           </property>
                       </properties>
                   </configuration>
               </plugin>
           </plugins>
       </pluginManagement>
       <plugins>
           <plugin>
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-compiler-plugin</artifactId>
               <configuration>
                   <source>6</source>
                   <target>6</target>
               </configuration>
           </plugin>
       </plugins>
   </build>


    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <evosuiteVersion>1.0.6</evosuiteVersion>
        <customFolder>src/test/evosuite</customFolder>
    </properties>

    <pluginRepositories>
        <pluginRepository>
            <id>EvoSuite</id>
            <name>EvoSuite Repository</name>
            <url>http://www.evosuite.org/m2</url>
        </pluginRepository>
    </pluginRepositories>
</project>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章