Search code examples
javaantpitest

How do I run a pitest ant script


I'm trying to create an ant script to run pitest to be able to automate my mutation testing. I am getting the error:

Could not find or load main class org.pitest.mutationtest.commandline.MutationCoverageReport

This is my MutationTest.xml ant script

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="mutationCoverage" name="PhoneBook">
    <property name="ECLIPSE_HOME" value="C:/Program Files/eclipse/"/>
    <path id="JUnit 4.libraryclasspath">
        <pathelement location="${ECLIPSE_HOME}plugins/org.junit_4.11.0.v201303080030/junit.jar"/>
        <pathelement location="${ECLIPSE_HOME}plugins/org.hamcrest.core_1.3.0.v201303031735.jar"/>
    </path>
    <path id="PhoneBook.classpath">
        <pathelement location="bin"/>
        <path refid="JUnit 4.libraryclasspath"/>
    </path>
    <path id="pit.path">
        <pathelement location="lib/pitest-1.1.4.jar" />
        <pathelement location="lib/pitest-ant-1.1.4.jar" />
    </path>

    <taskdef name="pitest" classname="org.pitest.ant.PitestTask" classpathref="pit.path" />

    <target name="mutationCoverage">
        <pitest
            pitClasspath="PhoneBook.path"
            classPath="PhoneBook.path"
            targetClasses="pbook.*"
            targetTests="pbook.*"
            reportDir="MutationReports"
            sourceDir="src"/>
    </target>
</project>

What is causing this error, and how can I fix it?

Edit: I changed pitClasspath="PhoneBook.path" to pitClasspath="pit.path" and now I have a new error:

[pitest] Exception in thread "main" org.pitest.util.PitError: Unable to load class content for org.pitest.boot.HotSwapAgent
[pitest] Please copy and paste the information and the complete stacktrace below when reporting an issue
[pitest] VM : Java HotSpot(TM) 64-Bit Server VM
[pitest] Vendor : Oracle Corporation
[pitest] Version : 25.25-b02
[pitest] Uptime : 370
[pitest] Input -> 
[pitest] BootClassPathSupported : true
[pitest]    at org.pitest.mutationtest.tooling.JarCreatingJarFinder.classBytes(JarCreatingJarFinder.java:124)
[pitest]    at org.pitest.mutationtest.tooling.JarCreatingJarFinder.addClass(JarCreatingJarFinder.java:113)
[pitest]    at org.pitest.mutationtest.tooling.JarCreatingJarFinder.createJarFromClassPathResources(JarCreatingJarFinder.java:98)
[pitest]    at org.pitest.mutationtest.tooling.JarCreatingJarFinder.createJar(JarCreatingJarFinder.java:74)
[pitest]    at org.pitest.mutationtest.tooling.JarCreatingJarFinder.getJarLocation(JarCreatingJarFinder.java:63)
[pitest]    at org.pitest.mutationtest.tooling.EntryPoint.execute(EntryPoint.java:70)
[pitest]    at org.pitest.mutationtest.tooling.EntryPoint.execute(EntryPoint.java:43)
[pitest]    at org.pitest.mutationtest.commandline.MutationCoverageReport.runReport(MutationCoverageReport.java:72)
[pitest]    at org.pitest.mutationtest.commandline.MutationCoverageReport.main(MutationCoverageReport.java:43)

I don't know if that is better or worse, but hopefully it will be helpful in finding the problem.


Solution

  • I believe much of your problem is that you're trying to use the Eclipse generated build.xml file, which doesn't contain the mutation testing target, and the target which you've added to remedy this has some errors.

    I would suggest starting with the project here and attempting to understand how it works, and then changing their build.xml file to fit your needs. However if this doesn't work, judging from your other question, the following build.xml should work if:

    1. You divide your files into two source directories "src" and "test"
    2. Both src and test folders contain the package "pbook"
    3. You change the name of your tests to end in "Test" rather than begin in it

    <?xml version="1.0" encoding="UTF-8"?>
    
    <project name="Phonebook">
    
        <property name="classOutputDir" value="build" />
    
            <!-- classpath for pitest and any plugins -->
        <path id="pitest.path">
                    <!-- must currently include the test library on the tool classpath. this will be fixed in a future version-->
               <pathelement location="lib/junit-4.9.jar" />
            <pathelement location="lib/pitest-0.33.jar" />
            <pathelement location="lib/pitest-ant-0.33.jar" />
        </path>
    
        <taskdef name="pitest" classname="org.pitest.ant.PitestTask" classpathref="pitest.path" />
    
        <target name="clean">
            <delete dir="${classOutputDir}" />
        </target>
    
        <target name="compile" depends="clean">
            <mkdir dir="${classOutputDir}/classes" />
            <!-- Essential that line numbers and filenames are included in order for PIT to work -->
            <javac srcdir="src" includeantruntime="false" debug="true" debuglevel="source,lines" destdir="${classOutputDir}/classes" />
        </target>
    
       <!-- classpath for compiling and testing the code. Note it does not include pitest and it's dependencies -->
        <path id="test.path">
            <pathelement location="${classOutputDir}/classes" />
            <pathelement location="${classOutputDir}/test-classes" />
            <pathelement location="lib/junit-4.9.jar" />
        </path>
    
        <target name="test" depends="compile">
            <mkdir dir="${classOutputDir}/test-result" />
            <mkdir dir="${classOutputDir}/test-classes" />
            <javac includeantruntime="false" srcdir="test" destdir="${classOutputDir}/test-classes">
                <classpath refid="test.path" />
            </javac>
    
            <junit>
                <classpath refid="test.path" />
                <batchtest todir="${classOutputDir}/test-result">
                    <!-- set test classes -->
                    <fileset dir="test">
                        <include name="**/*Test.java" />
                    </fileset>
                    <formatter type="xml" />
                </batchtest>
            </junit>
    
            <junitreport todir="${classOutputDir}/test-result">
                <fileset dir="${classOutputDir}/test-result">
                    <include name="TEST-*.xml" />
                </fileset>
                <report format="frames" todir="${classOutputDir}/test-result/report" />
            </junitreport>
    
        </target>
        
        <!-- run pitest. note that the filters for tests and classes refer to package/class names, not source file named -->
        <target name="pit" depends="test">
            <path id="mutation.path">
                <path refid="pitest.path"/>
                <path refid="test.path"/>
            </path>
            <pitest pitClasspath="pitest.path" threads="2" classPath="mutation.path" targetTests="pbook.*" targetClasses="pbook.*" reportDir="pitReports" sourceDir="src" />
        </target>
    
    </project>