Skip to content

Writing a Filter

Aaron Ong edited this page Jan 27, 2021 · 2 revisions
  1. Create your method filter class file under the evosuite.shell.listmethod package. Ensure your filter class extends MethodFlagCondFilter and overrides the checkMethod() method. Below is an example method filter:
package evosuite.shell.listmethod;

public class ExampleMethodFilter extends MethodFlagCondFilter {
    private static Logger log = LoggerUtils.getLogger(ExampleMethodFilter.class);
	
    @Override
    protected boolean checkMethod(ClassLoader classLoader, String className, String methodName, MethodNode node,
            ClassNode cn) throws AnalyzerException, IOException, ClassNotFoundException {
        log.debug(String.format("#Method %s#%s", className, methodName));

        // Get actual CFG for target method
        ActualControlFlowGraph cfg = GraphPool.getInstance(classLoader).getActualCFG(className,
                methodName);
        if (cfg == null) {
            BytecodeAnalyzer bytecodeAnalyzer = new BytecodeAnalyzer();
            bytecodeAnalyzer.analyze(classLoader, className, methodName, node);
            bytecodeAnalyzer.retrieveCFGGenerator().registerCFGs();
            cfg = GraphPool.getInstance(classLoader).getActualCFG(className, methodName);
        }
        
        // Get instructions for target method
        BytecodeInstructionPool insPool = BytecodeInstructionPool.getInstance(classLoader);
        List<BytecodeInstruction> instructions = insPool.getAllInstructionsAtMethod(className, methodName);
        
        // Write your filter logic here
        // Return true if the method passes your filter
        
	return false;
    }
}
  • MethodFlagCondFilter overrides a method listTestableMethods() that filters out the following unwanted methods by default:
    • Abstract methods
    • Class constructors
    • Methods that do not contain any branches
  • If you would like to analyze these methods, override the listTestableMethods() method in your own method filter.
  • Your method filter should override the checkMethod() method, as seen in the example above. checkMethod() is called for each target method. If the target method passes your filter, checkMethod() should return true; else return false.
  1. Edit the enum class evosuite.shell.listmethod.MethodFilterOption, to create the option for using your filter. The class should look something like this:
public enum MethodFilterOption {

    FLAG_PROCEDURE_METHOD ("flagProc"),
    FLAG_PROCEDURE_METHOD_WITH_SIMPLE_RETURN ("flagProcSimplRet"),
    HAS_BRANCH ("hasBranch"),
    ...
    EXAMPLE_METHOD("exampleMethod"); // (1) Add your new filter here

    ...

    public IMethodFilter getCorrespondingFilter() {
        switch(this) {
        case FLAG_PROCEDURE_METHOD:
            return new MethodFlagCondFilter();
        case FLAG_PROCEDURE_METHOD_WITH_SIMPLE_RETURN:
            return new MethodFlagCondWithSimpleReturnFilter();
        case HAS_BRANCH:
            return new MethodHasBranchFilter();
        ...
        // (2) Add your new filter here
        case EXAMPLE_METHOD:
            return new ExampleMethodFilter();
        }
        return null;
    }
    ...
}
  • (1) Firstly, add a new enum for your filter. You can name it anything, preferably something related to your filter.
  • (2) Secondly, add a new case for your filter in the getCorrespondingFilter() method which should return your created method filter class.
  1. To run your filter, edit the evosuite.shell.batch.ListMethodsBatch class. Inside the justRun() method, runListMethod() is called. Ensure the argument provided is the MethodFilterOption enum for your desired filter. An example is shown below:
public class ListMethodsBatch {
    @Test
    public void justRun() throws IOException {
        org.evosuite.Properties.ALWAYS_REGISTER_BRANCH = true;
        runListMethod(MethodFilterOption.EXAMPLE_METHOD); // Ensure argument is the enum for your filter
    }
    ...
}
  • To run the filter, run the justRun() method as a JUnit Test.