Randoop隨機測試&自動生成測試用例


什么是Randoop:

Randoop是一個為JAVA單元測試生成測試用例的框架(生成器),它基於Junit格式為編譯后JAVA字節碼(classes)自動生成測試用例.

Randoop通過反饋式的隨機測試來生成測試用例,由於測試數據的隨機性,隨機測試往往很難有較高的覆蓋率。

Randoop地址:http://randoop.github.io/randoop/

使用Randoop准備:

  下載Randoop的jar包,如randoop-2.1.4.jar

  這篇文章不把Randoop加入到環境變量中,只是將.jar包放在和待處理類相同的位置(之后詳細說明)。

作為隨機測試,首先看看測試的輸入集:

在Randoop中的測試數據有默認的原始值做為測試的輸入

  • byte-10110100
  • short-10110100
  • int-10110100
  • long-10110100
  • float-10110100
  • double-10110100
  • char'#'' ''4''a'
  • java.lang.String"""hi!"

如圖是實際生成的測試用例部分,我們可以看到生成的回歸測試用例中大多數變量的值為隨機的-1,0,1,10,100等

當然,這些值可以重新指定,方法有兩個:

  1.Command line: 通過命令行的“-literals-file”來指定數據來源的文件

  2.編程方式:你可以聲明一個類來存儲原始值,使用 @TestValue來注釋

  

 1   package example;
 2   import randoop.*;
 3 
 4   public class TestValueExamples {
 5 
 6     @TestValue
 7     public static int i = 0;
 8 
 9     @TestValue
10     public static boolean b = false;
11 
12     @TestValue
13     public static byte by = 3;
14 
15     @TestValue
16     public static char c = 'c';
17 
18     @TestValue
19     public static long l = 3L;
20 
21     @TestValue
22     public static float f = (float) 1.3;
23 
24     @TestValue
25     public static double d = 1.4;
26 
27     @TestValue
28     public static String s1 = null;
29 
30     @TestValue
31     public static String s2 = "hi";
32 
33     @TestValue
34     public static int[] a1 = new int[] { 1, 2, 3 };
35 
36   }

  為了應用這個原始值,需要把這個類加入到待測試的類中,即在“-testclass="加這個類,當然建議把要測試的類寫到.txt文件中然后通過“-classslist=YourFilename.txt"來加入多個待測試類。

說完了測試的輸入,接下來看看Randoop的使用方法:

  如果不依賴IDE,清楚在命令行中如何編譯,運行java的,只需進入待測試類的文件夾下,並將randoop-2.1.4.jar放在這個目錄下,輸入以下命令,A是待測試類,即可成功

1 java -ea -classpath .;randoop-2.1.4.jar;A randoop.main.Main gentests --testclass=A --timelimit=60

  如果不清楚的,以下為詳細步驟:

    1.首先在命令行中進入待測試的類目錄下

      項目文件結構

        

    2.進入Triangle目錄下后,cd bin

      bin內容

        

      TriangleClass和testTriangle是包名,若類名為Triangle,則類全名是TriangleClass.Triangle

    3.所以輸入的命令為

1 java -ea -classpath .;randoop-2.1.4.jar;TriangleClass.Triangle randoop.main.Main gentests --testclass=TriangleClass.Triangle --timelimit=15

結果為

 

Randoop過程分析,進階了解:

  Randoop創建測試用例,然后將測試用例分為三類:

    1.檢測到你現有代碼錯誤的測試用例

    2.用來檢測未來變更的回歸測試用例

    3.運行時無效和被丟棄的測試用例

  那么我們就需要知道Randoop能檢測出什么錯誤

  目前,Randoop檢測如下的協議(Contracts)來判斷程序中是否有錯

    基於Object.equals()的協議

      自反性:o.equals(o) == true

      對稱性:o1.equals(o2) == o2.equals(o1)

      傳遞性:o1.equals(o2) && o2.equals(o3) ⇒ o1.equals(o3)

      等於空: o.equals(null) == false

      不拋出異常

    基於Object.hashCode()的協議

      Equals和hashCode的等價性: If o1.equals(o2)==true, then o1.hashCode() == o2.hashCode()

      不拋出異常

    基於Object.clone()的協議

      不拋出異常

    基於Object.toString()的協議

      不拋出異常

    基於 Comparable.compareTo() and Comparator.compare()的協議

      自反性:o.compareTo(o) == 0

 

      反-對稱性:sgn(o1.compareTo(o2)) == -sgn(o2.compareTo(o1))

 

      傳遞性:o1.compareTo(o2)>0 && o2.compareTo(o3)>0 ⇒ o1.compareTo(o3)>0

 

      相等的可替代性:  x.compareTo(y)==0 ⇒ sgn(x.compareTo(z)) == sgn(y.compareTo(z))

 

      和Equal的一致性: (x.compareTo(y)==0) == x.equals(y) )

      不拋出異常

    基於checkRep() (用@checkRep注釋的方法)

      如果函數的返回類型為boolean行,則必須return True

      不拋出異常

    任何異常拋出都是錯誤(可以通過命令行參數修改)

  知道了Randoop的協議,我們大概知道Randoop可以檢測哪些類型的錯誤,可以推斷出,Randoop適合檢測的是自定義的數據類型類而不是純功能類,所以Randoop能檢測出Java.util的一些錯誤,而對於類似加減乘除的功能類則不是很有效,可以說基本無用。

  最后不得不提的是,Randoop隨機測試單純使用時間作為標准來停止生成測試類不是很科學。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM