美文网首页
MAJOR 使用教程

MAJOR 使用教程

作者: 慎独墨写 | 来源:发表于2021-04-27 19:21 被阅读0次

    简介

    Major 是一个轻量级变异测试工具,其工作原理主要分为两步:

    1. 在编译过程中生成+嵌入变异体
    2. 执行变异体进行变异分析

    安装

    官网:http://mutation-testing.org/
    官方教程:http://mutation-testing.org/doc/major.pdf
    参考论文:https://homes.cs.washington.edu/~rjust/publ/major_issta_2014.pdf

    1. 下载
      前往 http://mutation-testing.org/downloads/
      下载新版本的MAJOR, 1.3.0以上的版本已经适配Java8

    2. 环境配置
      安装OpenJDK-8 (Ubuntun 16.04 安装JDK-7会比较繁琐,建议JDK-8;如果想不开想要安装的话,请参考https://segmentfault.com/a/1190000014979994

    # 编辑环境变量文件:
    sudo gedit /etc/profile
    # 在文件末尾输入以下内容
    export MAJOR_HOME=MAJOR_PATH
    export PATH=${MAJOR_HOME}/bin:$PATH
    # 输入以下命令使设置生效:
    source /etc/profile
    # 验证 Javac 版本:
    javac -version
    # 输出内容如下:
    javac 1.7.0-Major-v1.3.5
    # 验证 Ant 版本:
    ant -version
    # 输出内容应类似于此:
    Apache Ant(TM) version 1.8.4-Major-v1.3.5 compiled on July 18 2019
    

    3.编写MML脚本【可选步骤】
    为你的类编写MML脚本,在脚本中指定变化文法,变异算子生成方法,和希望被测试的类别;
    以程序中自带的作为例子;
    当然,你也可以使用自带的“all.mml.bin”甚至利用命令$javac -XMutator:ALL MyFile.java生成更多的变异体,这个步骤是一个optional的一步,这一步在现实中可以用于对MAJOR的变异算子进行复写或者选择,因项目和个人选择而异。

    targetOp{
        // Define the replacements for ROR
        BIN(>)->{>=,!=,FALSE};
        BIN(<)->{<=,!=,FALSE};
        BIN(>=)->{>,==,TRUE};
        BIN(<=)->{<,==,TRUE};
        BIN(==)->{<=,>=,FALSE,LHS,RHS};
        BIN(!=)->{<,>,TRUE,LHS,RHS};
        // Define the replacements for COR
        BIN(&&)->{==,LHS,RHS,FALSE};
        BIN(||)->{!=,LHS,RHS,TRUE};
        // Define the type of statement that STD should delete
        DEL(RETURN);
    
        // Enable the STD, COR, and ROR mutation operators
        STD;
        COR;
        ROR;
    }
    // Call the defined operator group for the target method
    targetOp<"BubbleSort::BubbleSort(int[])">;
    

    之后利用如下命令

    $ mmlc BubbleSort.mml BubbleSort.mml.bin
    

    生成编译好的文件。

    4.生成变异体
    javac -XMutator=BubbleSort.mml.bin -d bin BubbleSort.java
    可以从mutants.log文件中读取变异体生成的结果

    1:ROR:<(int,int):!=(int,int):BubbleSort@BubbleSort(int[]):6:i < arr.length - 1 |==> i != arr.length - 1
    2:ROR:<(int,int):<=(int,int):BubbleSort@BubbleSort(int[]):6:i < arr.length - 1 |==> i <= arr.length - 1
    3:ROR:<(int,int):FALSE(int,int):BubbleSort@BubbleSort(int[]):6:i < arr.length - 1 |==> false
    

    如果你想要查看代码,你可以用
    $javac -J-Dmajor.export.mutants=true -XMutator:ALL MyFile.java
    导出所有的变异体;

    5.执行变异体
    执行变异体要使用ant,方便起见,我们按照他的目录格式创建文档

    BubbleSort -- ant -- src  -- BubbleSort.java
                      -- test -- testBubbleSort.java
                      -- build.xml
                      -- run.sh
                           
    

    src:放入你的待测代码
    test:放入你的junit代码
    build.xml ant的build配置文件,建议你不要随便修改它。
    run.sh 用来执行ant compile以及后续过程的一个脚本文件
    你可以利用$MAJOR_HOME\example\ant\build.xml 以及同目录下的run.sh的文件;
    【请注意,如果你出现了错误,80%的错误都出在这一步;几乎都是因为你的.java和test.java文件没有放对位置,如果你的.java和test.java文件是在同一个package里面,请自行建一个package文件夹套在外面,并且保证你的package之类的名字都写对】
    你只需修改第一行<project name="Triangle" default="compile" basedir=".">
    将name改成你的项目名,对本示例而言是BubbleSort, 剩下的不要改。

    在build.xml中,援引example的例子,下列三个target最重要,不要随便改动;

    <!-- Target to compile the project -->
        <target name="compile" depends="init" description="Compile">
            <javac includeantruntime="true" 
                   srcdir="src"
                  destdir="bin"
                    debug="yes"
                     fork="yes"
               executable="${major}">
                <compilerarg value="${mutator}"/>
            </javac>
        </target>
    
    <!-- Target to compile the test suite -->
        <target name="compile.tests" depends="compile" description="Compile all tests">
            <javac includeantruntime="true" 
                   srcdir="test"
                  destdir="bin"
                    debug="yes">
            </javac>
        </target>
    
    <!-- The adapted mutation test target -->
        <target name="mutation.test" description="Run mutation analysis for all unit test cases">
            <echo message="Running mutation analysis ..."/>
            <junit  printsummary="false" 
                    showoutput="false" 
                    mutationAnalysis="true"
                    resultFile="results.csv" 
                    killDetailsFile="killed.csv">
                    
                <classpath path="bin"/>
                <batchtest fork="false">
                    <fileset dir="test">
                        <include name="**/*Test*.java"/>
                    </fileset>
                </batchtest>
            </junit>
        </target>
    

    执行run.sh
    会得到类似于如下的report

    mutation.test:
         [echo] Running mutation analysis ...
        [junit] MAJOR: Mutation analysis enabled
        [junit] MAJOR: ------------------------------------------------------------
        [junit] MAJOR: Run 1 ordered test to verify independence
        [junit] MAJOR: ------------------------------------------------------------
        [junit] MAJOR: Preprocessing time: 0.07 seconds
        [junit] MAJOR: ------------------------------------------------------------
        [junit] MAJOR: Mutants generated: 35
        [junit] MAJOR: Mutants covered:   35 (100.00%)
        [junit] MAJOR: ------------------------------------------------------------
        [junit] MAJOR: Export test map to testMap.csv
        [junit] MAJOR: ------------------------------------------------------------
        [junit] MAJOR: Run mutation analysis with 1 individual test
        [junit] MAJOR: ------------------------------------------------------------
        [junit] MAJOR: 1/1 - BubbleSortTest (14ms / 35):
        [junit] MAJOR: 250 (28 / 35 / 35) -> AVG-RTPM: 7ms
        [junit] MAJOR: Mutants killed / live: 28 (18-10-0) / 7
        [junit] MAJOR: ------------------------------------------------------------
        [junit] MAJOR: Summary:
        [junit] MAJOR: 
        [junit] MAJOR: Analysis time:  0.3 seconds
        [junit] MAJOR: Mutation score: 80.00% (80.00%)
        [junit] MAJOR: Mutants killed / live: 28 (18-10-0) / 7
        [junit] MAJOR: Mutant executions: 35
        [junit] MAJOR: ------------------------------------------------------------
        [junit] MAJOR: Export summary of results to summary.csv
        [junit] MAJOR: Export run-time results to results.csv
        [junit] MAJOR: Export mutant kill details to killed.csv
    

    当然,如果你现在执行成功了,你就被允许对build.xml进行魔改了;


    一些Major-Ant的新功能

    你可以尝试使用更多的功能;

    【如果你出现了如下错误】
    1.我的mutants covered = 0
    一个变异体都没有杀死,
    要么是你写出了惊世骇俗的测试用例【显然很难】
    要么是你的mutation.log在ant compile tests过程中遭到了覆盖;
    要么是你的两个.java文件的package出了错,导致编译失败;
    要么是你魔改了你的build.xml,或者你的.java命名不带Test,或者.java位置放的不对,导致找文件都没找到;
    请你将run.sh的每一步分别来debug;
    2.如果你的Java文件不在major的路径下, 不要忘记做一下修改:
    run.sh中的:

    MAJOR_HOME="../../" 改为 MAJOR_HOME="MAJOR_PATH"
    

    还要修改 build.xml 文件中的 major 属性:

    <property name="major" value="../../bin/javac"/> 改为
    <property name="major" value="MAJOR_PATH/bin/javac"/>
    

    MAJOR_PATH按照你的实际情况调整;

    相关文章

      网友评论

          本文标题:MAJOR 使用教程

          本文链接:https://www.haomeiwen.com/subject/otyprltx.html