• 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随机测试单纯使用时间作为标准来停止生成测试类不是很科学。

  • 相关阅读:
    HDU 2010 水仙花数
    HDU 2009 求数列的和
    HDU 2008 数值统计
    Nginx实现反向代理
    vue-router 实现分析
    区分slice,splice和split方法
    notify()和notifyAll()主要区别
    移动端页面兼容性问题解决方案整理
    clearfix的用法
    前端js面试题
  • 原文地址:https://www.cnblogs.com/clownice/p/5515185.html
Copyright © 2020-2023  润新知