Compare commits

...

10 commits

Author SHA1 Message Date
Sander Hautvast
345f769bc0 Merge branch 'master' of https://github.com/shautvast/autounit 2015-09-26 17:39:03 +02:00
Sander Hautvast
5659e497f8 some javadoc 2015-09-26 17:38:33 +02:00
Sander Hautvast
44cb4039ac Update README.md 2015-09-26 17:32:54 +02:00
Sander Hautvast
a86c365616 refactoring 2015-09-26 17:24:32 +02:00
Sander Hautvast
07021dd9a9 new class to contain method results 2015-09-26 10:47:16 +02:00
Sander Hautvast
c74da14533 extracted to outer class 2015-09-26 10:46:54 +02:00
Sander Hautvast
7bd69290c4 renaming and moving 2015-09-26 10:46:31 +02:00
Sander Hautvast
b85037666a Extracted to outer class 2015-09-26 10:44:36 +02:00
Sander Hautvast
d9a3df8277 multiple resultswriter implementations 2015-09-26 10:44:03 +02:00
Sander Hautvast
ed603109cc removed commented code 2015-09-11 13:00:57 +02:00
51 changed files with 1012 additions and 784 deletions

View file

@ -1,4 +1,6 @@
autounit
Autounit
========
autounit
Autounit is an attempt to make my life easier when writing code. It should provide me with unit tests for any given type.
This attempt is destined to fail, as it would require strong AI to understand the intent of a piece of code. Even for humans this is often a daunting task.
Nevertheless, let's see where this goes...

View file

@ -5,8 +5,8 @@ repositories{
mavenCentral()
}
sourceCompatibility = "1.6"
targetCompatibility = "1.6"
sourceCompatibility = "1.8"
targetCompatibility = "1.8"
sourceSets {
test {
@ -23,7 +23,7 @@ dependencies{
compile 'javassist:javassist:3.12.1.GA'
compile 'com.thoughtworks.xstream:xstream:1.4.7'
compile 'org.mockito:mockito-all:1.9.5'
testCompile 'junit:junit:4.11'
testCompile 'org.jacoco:org.jacoco.core:0.7.1.201405082137'
compile 'org.jacoco:org.jacoco.core:0.7.1.201405082137'
testCompile 'junit:junit:4.11'
}

View file

@ -1,33 +0,0 @@
package nl.jssl.autounit;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.Map;
/**
* record: records in and outputs
*
* assertUnchangedBehaviour: raises an error when recorded inputs do no lead to
* recorded outputs
*/
public class AutoTester {
ResultsWriter resultsWriter = new ResultsWriter();
public Map<String, MethodCallResults> record(Class<?> instance) {
Map<String, MethodCallResults> results = new Recorder(instance).record();
resultsWriter.write(instance.getName(), results);
return results;
}
private Map<String, MethodCallResults> load(String classname) {
try {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(classname + ".dat"));
Map<String, MethodCallResults> results = (Map<String, MethodCallResults>) objectInputStream.readObject();
objectInputStream.close();
return results;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View file

@ -4,17 +4,20 @@ import javassist.ClassPool;
import javassist.NotFoundException;
/**
* TODO make configurable
*
*/
public class Configuration {
public static ClassPool getClassPool() {
ClassPool classPool = new ClassPool();
try {
classPool.appendClassPath("c:\\workspaces\\autounit\\autounit\\bin");
classPool.appendClassPath(getClasspathSettingOrEclipseDefault());
} catch (NotFoundException e) {
throw new RuntimeException(e);
}
return classPool;
}
private static String getClasspathSettingOrEclipseDefault() {
return System.getProperty("autounit.cp", "bin");
}
}

View file

@ -1,103 +0,0 @@
package nl.jssl.autounit;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import nl.jssl.autounit.utils.MemoryClassloader;
import nl.jssl.autounit.utils.SilentObjectCreator;
import org.jacoco.core.analysis.Analyzer;
import org.jacoco.core.analysis.CoverageBuilder;
import org.jacoco.core.analysis.IClassCoverage;
import org.jacoco.core.data.ExecutionDataStore;
import org.jacoco.core.data.SessionInfoStore;
import org.jacoco.core.instr.Instrumenter;
import org.jacoco.core.runtime.IRuntime;
import org.jacoco.core.runtime.LoggerRuntime;
import org.jacoco.core.runtime.RuntimeData;
public class CoverageAnalyser {
private IRuntime runtime;
private RuntimeData data = new RuntimeData();
@SuppressWarnings("unchecked")
public <T> T instrument(Class<T> testTarget) {
try {
String targetName = testTarget.getName();
runtime = new LoggerRuntime();
Instrumenter instr = new Instrumenter(runtime);
byte[] instrumented = instr.instrument(getTargetClass(targetName), targetName);
data = new RuntimeData();
runtime.startup(data);
MemoryClassloader memoryClassLoader = new MemoryClassloader();
memoryClassLoader.addDefinition(targetName, instrumented);
Class<T> targetClass = (Class<T>) memoryClassLoader.loadClass(targetName);
return SilentObjectCreator.create(targetClass);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public <T> InvocationResult analyse(T instrumentedTestTarget, Method method, Object[] inputs) {
try {
Method instanceMethod = getInstrumentedMethod(instrumentedTestTarget, method);
Object output = invoke(instrumentedTestTarget, inputs, instanceMethod);
// jacoco stuff
ExecutionDataStore executionData = new ExecutionDataStore();
SessionInfoStore sessionInfos = new SessionInfoStore();
data.collect(executionData, sessionInfos, false);
runtime.shutdown();
CoverageBuilder coverageBuilder = new CoverageBuilder();
Analyzer analyzer = new Analyzer(executionData, coverageBuilder);
String targetName = instrumentedTestTarget.getClass().getName();
analyzer.analyzeClass(getTargetClass(targetName), targetName);
return new InvocationResult(coverageBuilder.getClasses().iterator().next(), output);
} catch (Exception e) {
throw new ExecutionException(e);
}
}
private <T> Method getInstrumentedMethod(T testTarget, Method method) throws NoSuchMethodException {
return testTarget.getClass().getDeclaredMethod(method.getName(), method.getParameterTypes());
}
private <T> Object invoke(T testTarget, Object[] inputs, Method newInstanceMethod) throws IllegalAccessException {
Object output;
try {
output = newInstanceMethod.invoke(testTarget, inputs);
} catch (InvocationTargetException i) {
StackTraceElement stacktraceElement = i.getTargetException().getStackTrace()[0];
String info = stacktraceElement.getClassName() + ":" + stacktraceElement.getLineNumber();
output = i.getTargetException().getClass().getName() + "(" + i.getTargetException().getMessage() + ") at "
+ info;
}
return output;
}
private InputStream getTargetClass(String name) {
String resource = '/' + name.replace('.', '/') + ".class";
return getClass().getResourceAsStream(resource);
}
}
class InvocationResult {
public final IClassCoverage coverage;
public final Object output;
public InvocationResult(IClassCoverage coverage, Object output) {
super();
this.coverage = coverage;
this.output = output;
}
}

View file

@ -1,25 +0,0 @@
package nl.jssl.autounit;
@SuppressWarnings("serial")
public class ExecutionException extends RuntimeException {
public ExecutionException() {
super();
}
public ExecutionException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public ExecutionException(String message, Throwable cause) {
super(message, cause);
}
public ExecutionException(String message) {
super(message);
}
public ExecutionException(Throwable cause) {
super(cause);
}
}

View file

@ -1,19 +0,0 @@
package nl.jssl.autounit;
public class InAndOutput {
private final Object input;
private final Object output;
public InAndOutput(Object input, Object output) {
this.input = input;
this.output = output;
}
public Object getInput() {
return input;
}
public Object getOutput() {
return output;
}
}

View file

@ -0,0 +1,55 @@
package nl.jssl.autounit;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import nl.jssl.autounit.classanalyser.ClassAnalyser;
import nl.jssl.autounit.classanalyser.ClassResults;
import nl.jssl.autounit.results.JUnitSourceWriter;
/**
* Creates a Junit source file
*
*/
public class JUnitTestCreator<T> {
private static final String SOURCEDIRECTORY = "src/outcome/java/";
private final Class<T> classUnderTest;
private final File packageDirectory;
public JUnitTestCreator(Class<T> type) {
this.classUnderTest = type;
packageDirectory = createPackageDirectory();
}
public void create() {
try {
writeSourceFile();
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
private void writeSourceFile() throws FileNotFoundException {
ClassResults results = new ClassAnalyser<>(classUnderTest).analyseAndGetResults();
getSourceWriter(packageDirectory).write(results);
}
private JUnitSourceWriter getSourceWriter(File packageDirectory) throws FileNotFoundException {
return new JUnitSourceWriter(new PrintStream(new FileOutputStream(getSourceFile())));
}
private File createPackageDirectory() {
File packageDirectory = new File(
SOURCEDIRECTORY + classUnderTest.getPackage().getName().replaceAll("\\.", "/"));
packageDirectory.mkdirs();
return packageDirectory;
}
private File getSourceFile() {
return new File(packageDirectory, classUnderTest.getSimpleName() + "Tests.java");
}
}

View file

@ -1,57 +0,0 @@
package nl.jssl.autounit;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import org.jacoco.core.analysis.IClassCoverage;
public class MethodCallResults {
private transient Object testinstance;
private transient Method executedMethod;
private List<InAndOutput> contents = new ArrayList<InAndOutput>();
private transient IClassCoverage coverageResult;
public MethodCallResults(Object testClass, Method m) {
super();
this.testinstance = testClass;
this.executedMethod = m;
}
public void addResult(Object input, Object output) {
contents.add(new InAndOutput(input, output));
}
public List<InAndOutput> getContents() {
return contents;
}
public Object getTestinstance() {
return testinstance;
}
public Method getExecutedMethod() {
return executedMethod;
}
@Override
public String toString() {
return getReport();
}
public void setCoverageResult(IClassCoverage coverageResult) {
this.coverageResult = coverageResult;
}
public IClassCoverage getCoverageResult() {
return coverageResult;
}
public String getReport() {
StringBuilder s = new StringBuilder();
for (InAndOutput inAndOutput : contents) {
s.append(inAndOutput.getInput() + " => " + inAndOutput.getOutput() + "\n");
}
return s.toString();
}
}

View file

@ -1,64 +0,0 @@
package nl.jssl.autounit;
import java.lang.reflect.Method;
import java.util.List;
import nl.jssl.autounit.utils.Permuter.Tuple;
/**
* voert 1 methode uit met wisselende input parameters en bewaart het resultaat.
*
*/
public class MethodcallExecutor {
private Object instrumentedTestTarget;
private Method m;
CoverageAnalyser coverageAnalyser = new CoverageAnalyser();
private MethodCallResults result;
public MethodcallExecutor(Class<?> testClass, Method m) {
super();
this.instrumentedTestTarget = coverageAnalyser.instrument(testClass);
this.m = m;
this.result = new MethodCallResults(instrumentedTestTarget, m);
}
public MethodCallResults execute(List<Tuple> inputs) {
int missedLines = Integer.MAX_VALUE;
InvocationResult lastInvocationResult = null, previous = null;
for (Tuple input : inputs) {
previous = lastInvocationResult;
lastInvocationResult = analyseMethodCall(m, input);
int missedCount = lastInvocationResult.coverage.getLineCounter().getMissedCount();
if (missedCount < missedLines) { // coverage increases, this is an
// interesting input
missedLines = missedCount;
result.addResult(input, lastInvocationResult.output);
}
if (missedCount == 0) { // coverage = 100%: done
break;
}
}
if (lastInvocationResult != null) {
if (previous == null) {
result.setCoverageResult(lastInvocationResult.coverage);
} else {
result.setCoverageResult(previous.coverage);
}
}
return result;
}
private InvocationResult analyseMethodCall(Method m, Tuple input) {
Object[] argumentarray = input.toArray();
for (int i = 0; i < argumentarray.length; i++) {
if (argumentarray[i].toString().equals("autounit:[NULL]")) {
argumentarray[i] = null;
}
}
return coverageAnalyser.analyse(instrumentedTestTarget, m, argumentarray);
}
public MethodCallResults getResult() {
return result;
}
}

View file

@ -1,27 +0,0 @@
package nl.jssl.autounit;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class Player {
final private Object testinstance;
private Player(Object testinstance) {
super();
this.testinstance = testinstance;
}
public void playback(Map<String, List<MethodCallResults>> recordedResults) {
for (Entry<String, List<MethodCallResults>> entry: recordedResults.entrySet()) {
getInputs(entry.getValue());
// new Executor(testinstance,getMethod(entry.getKey()))
}
}
private void getInputs(List<MethodCallResults> value) {
// TODO Auto-generated method stub
}
}

View file

@ -1,61 +0,0 @@
package nl.jssl.autounit;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import nl.jssl.autounit.inputs.MethodcallArgumentsFactory;
import nl.jssl.autounit.utils.Permuter.Tuple;
public class Recorder {
private Class<?> testTarget;
public Recorder(Class<?> testTarget) {
this.testTarget = testTarget;
}
public Map<String, MethodCallResults> record() {
Map<String, MethodCallResults> classresults = new HashMap<String, MethodCallResults>();
for (Method m : getPublicMethods()) {
MethodCallResults methodresults = recordMethod(m);
classresults.put(getMethodSignature(m), methodresults);
}
return classresults;
}
private String getMethodSignature(Method m) {
String signature = Modifier.toString(m.getModifiers()) + " " + m.getReturnType().getName() + " " + m.getName()
+ "(";
int index = 1;
Class<?>[] parameterTypes = m.getParameterTypes();
for (Class<?> type : parameterTypes) {
signature += type.getName() + " arg" + (index++);
if (index <= parameterTypes.length) {
signature += ",";
}
}
signature += ")";
return signature;
}
private MethodCallResults recordMethod(Method m) {
List<Tuple> inputSet = new MethodcallArgumentsFactory().getInputs(testTarget, m);
MethodcallExecutor methodcallExecutor = new MethodcallExecutor(testTarget, m);
methodcallExecutor.execute(inputSet);
return methodcallExecutor.getResult();
}
List<Method> getPublicMethods() {
List<Method> publicMethods = new ArrayList<Method>();
for (Method m : testTarget.getDeclaredMethods()) {
if (Modifier.isPublic(m.getModifiers())) {
publicMethods.add(m);
}
}
return publicMethods;
}
}

View file

@ -1,35 +0,0 @@
package nl.jssl.autounit;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.Map;
import nl.jssl.autounit.utils.Permuter.Tuple;
import nl.jssl.autounit.utils.XStreamArgumentsConverter;
import com.thoughtworks.xstream.XStream;
public class ResultsWriter {
XStream xstream = new XStream();
public ResultsWriter() {
setup();
}
private void setup() {
xstream.alias("case", InAndOutput.class);
xstream.alias("results", MethodCallResults.class);
xstream.alias("args", Tuple.class);
xstream.registerConverter(new XStreamArgumentsConverter());
}
public void write(String classname, Map<String, MethodCallResults> results) {
try {
xstream.toXML(results, new FileOutputStream(classname + ".xml"));
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
}

View file

@ -0,0 +1,25 @@
package nl.jssl.autounit.classanalyser;
@SuppressWarnings("serial")
public class AnalysisFailed extends RuntimeException {
public AnalysisFailed() {
super();
}
public AnalysisFailed(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public AnalysisFailed(String message, Throwable cause) {
super(message, cause);
}
public AnalysisFailed(String message) {
super(message);
}
public AnalysisFailed(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,50 @@
package nl.jssl.autounit.classanalyser;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import nl.jssl.autounit.inputs.MethodcallArgumentsFactory;
import nl.jssl.autounit.util.LinkedList;
/**
* Analyses the class you want to create tests for.
*/
public class ClassAnalyser<T> {
private Class<T> testTarget;
public ClassAnalyser(Class<T> testTarget) {
this.testTarget = testTarget;
}
public ClassResults analyseAndGetResults() {
List<MethodExecutionResults> classresults = new ArrayList<>();
for (Method m : getPublicMethods()) {
classresults.add(analyseMethod(m));
}
return new ClassResults(testTarget, classresults);
}
private MethodExecutionResults analyseMethod(Method method) {
List<LinkedList> inputSet = new MethodcallArgumentsFactory(testTarget).getInputs(method);
MethodcallExecutor<T> methodcallExecutor = new MethodcallExecutor<>(testTarget, method);
return methodcallExecutor.executeAndGetResults(inputSet);
}
List<Method> getPublicMethods() {
List<Method> publicMethods = new ArrayList<Method>();
for (Method m : testTarget.getDeclaredMethods()) {
if (Modifier.isPublic(m.getModifiers())) {
publicMethods.add(m);
}
}
return publicMethods;
}
}

View file

@ -0,0 +1,22 @@
package nl.jssl.autounit.classanalyser;
import java.util.List;
public class ClassResults {
private final Class<?> type;
private final List<MethodExecutionResults> methodCallResults;
public ClassResults(Class<?> type, List<MethodExecutionResults> methodCallResults) {
super();
this.type = type;
this.methodCallResults = methodCallResults;
}
public List<MethodExecutionResults> getMethodCallResults() {
return methodCallResults;
}
public Class<?> getType() {
return type;
}
}

View file

@ -0,0 +1,126 @@
package nl.jssl.autounit.classanalyser;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.jacoco.core.analysis.Analyzer;
import org.jacoco.core.analysis.CoverageBuilder;
import org.jacoco.core.data.ExecutionDataStore;
import org.jacoco.core.data.SessionInfoStore;
import org.jacoco.core.instr.Instrumenter;
import org.jacoco.core.runtime.IRuntime;
import org.jacoco.core.runtime.LoggerRuntime;
import org.jacoco.core.runtime.RuntimeData;
import nl.jssl.autounit.util.MemoryClassloader;
import nl.jssl.autounit.util.SilentObjectCreator;
/**
* When creating tests, increasing coverage indicates a good test. Hence a
* CoverageAnalyser. It uses Jacoco (http://eclemma.org/jacoco/), the java
* interface for eclemma.
*/
public class CoverageAnalyser<T> {
private final IRuntime runtime;
private final RuntimeData data;
private final Class<T> testTarget;
public CoverageAnalyser(Class<T> testTarget) {
this.testTarget = testTarget;
data = new RuntimeData();
runtime = new LoggerRuntime();
}
public T instrument() {
try {
runtime.startup(data);
return getInstrumentedObjectInstance();
} catch (Exception e) {
throw new AnalysisFailed(e);
}
}
public InvocationResult analyse(T instrumentedTestTarget, Method method, Object[] inputs) {
try {
Object output = invokeMethod(instrumentedTestTarget, inputs,
getInstrumentedMethod(instrumentedTestTarget, method));
// jacoco stuff
ExecutionDataStore executionData = executionData();
runtime.shutdown();
CoverageBuilder coverageBuilder = coverageBuilder(instrumentedTestTarget, executionData);
return new InvocationResult(coverageBuilder.getClasses().iterator().next(), output);
} catch (Exception e) {
throw new AnalysisFailed(e);
}
}
@SuppressWarnings("unchecked")
private T getInstrumentedObjectInstance() throws IOException, ClassNotFoundException {
MemoryClassloader memoryClassLoader = getMemoryClassLoaderForClass(getInstrumentedByteCode());
Class<T> targetClass = (Class<T>) memoryClassLoader.loadClass(testTarget.getName());
return SilentObjectCreator.create(targetClass);
}
private byte[] getInstrumentedByteCode() throws IOException {
return new Instrumenter(runtime).instrument(getTargetClass(), testTarget.getName());
}
private MemoryClassloader getMemoryClassLoaderForClass(byte[] instrumentedByteCode) {
MemoryClassloader memoryClassLoader = new MemoryClassloader();
memoryClassLoader.addDefinition(testTarget.getName(), instrumentedByteCode);
return memoryClassLoader;
}
private ExecutionDataStore executionData() {
ExecutionDataStore executionData = new ExecutionDataStore();
SessionInfoStore sessionInfos = new SessionInfoStore();
data.collect(executionData, sessionInfos, false);
return executionData;
}
private CoverageBuilder coverageBuilder(T instrumentedTestTarget, ExecutionDataStore executionData)
throws IOException {
CoverageBuilder coverageBuilder = new CoverageBuilder();
Analyzer analyzer = new Analyzer(executionData, coverageBuilder);
String targetName = instrumentedTestTarget.getClass().getName();
analyzer.analyzeClass(getTargetClass(), targetName);
return coverageBuilder;
}
private Method getInstrumentedMethod(T testTarget, Method method) throws NoSuchMethodException {
return testTarget.getClass().getDeclaredMethod(method.getName(), method.getParameterTypes());
}
private Object invokeMethod(T testTarget, Object[] inputs, Method newInstanceMethod) throws IllegalAccessException {
Object output;
try {
output = newInstanceMethod.invoke(testTarget, inputs);
} catch (InvocationTargetException i) {
output = createOutputFromException(i);
}
return output;
}
private Object createOutputFromException(InvocationTargetException i) {
Object output;
StackTraceElement stacktraceElement = i.getTargetException().getStackTrace()[0];
String info = stacktraceElement.getClassName() + ":" + stacktraceElement.getLineNumber();
output = i.getTargetException().getClass().getName() + "(" + i.getTargetException().getMessage() + ") at "
+ info;
return output;
}
private InputStream getTargetClass() {
String resource = '/' + testTarget.getName().replace('.', '/') + ".class";
return getClass().getResourceAsStream(resource);
}
}

View file

@ -0,0 +1,21 @@
package nl.jssl.autounit.classanalyser;
import nl.jssl.autounit.util.LinkedList;
public class InAndOutput {
private final LinkedList input;
private final Object output;
public InAndOutput(LinkedList input, Object output) {
this.input = input;
this.output = output;
}
public LinkedList getInput() {
return input;
}
public Object getOutput() {
return output;
}
}

View file

@ -0,0 +1,23 @@
package nl.jssl.autounit.classanalyser;
import org.jacoco.core.analysis.IClassCoverage;
class InvocationResult {
private final IClassCoverage coverage;
private final Object output;
public InvocationResult(IClassCoverage coverage, Object output) {
super();
this.coverage = coverage;
this.output = output;
}
public IClassCoverage getCoverage() {
return coverage;
}
public Object getOutput() {
return output;
}
}

View file

@ -0,0 +1,92 @@
package nl.jssl.autounit.classanalyser;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import org.jacoco.core.analysis.IClassCoverage;
import nl.jssl.autounit.util.LinkedList;
public class MethodExecutionResults implements Comparable<MethodExecutionResults> {
private transient Object testinstance;
private transient Method executedMethod;
private List<InAndOutput> contents = new ArrayList<InAndOutput>();
private transient IClassCoverage coverageResult;
public MethodExecutionResults(Object testClass, Method m) {
super();
this.testinstance = testClass;
this.executedMethod = m;
}
public void addResult(LinkedList input, Object output) {
contents.add(new InAndOutput(input, output));
}
public List<InAndOutput> getContents() {
return contents;
}
public Object getTestinstance() {
return testinstance;
}
public Method getExecutedMethod() {
return executedMethod;
}
@Override
public String toString() {
return getReport();
}
public void setCoverageResult(IClassCoverage coverageResult) {
this.coverageResult = coverageResult;
}
public IClassCoverage getCoverageResult() {
return coverageResult;
}
public String getReport() {
StringBuilder s = new StringBuilder();
for (InAndOutput inAndOutput : contents) {
s.append(inAndOutput.getInput() + " => " + inAndOutput.getOutput() + "\n");
}
return s.toString();
}
public String getMethodSignature() {
return getMethodSignature(executedMethod);
}
public String getMethodName() {
return executedMethod.getName();
}
private String getMethodSignature(Method m) {
String signature = Modifier.toString(m.getModifiers()) + " " + m.getReturnType().getName() + " " + m.getName()
+ "(";
int index = 1;
Class<?>[] parameterTypes = m.getParameterTypes();
for (Class<?> type : parameterTypes) {
signature += type.getName() + " arg" + (index++);
if (index <= parameterTypes.length) {
signature += ",";
}
}
signature += ")";
return signature;
}
public Class<?> getMethodReturnType() {
return executedMethod.getReturnType();
}
@Override
public int compareTo(MethodExecutionResults o) {
return getMethodName().compareTo(o.getMethodName());
}
}

View file

@ -0,0 +1,90 @@
package nl.jssl.autounit.classanalyser;
import java.lang.reflect.Method;
import java.util.List;
import nl.jssl.autounit.util.LinkedList;
/**
* Executes 1 method using alternating input parameters and yields execution
* results.
*/
public class MethodcallExecutor<T> {
private T instrumentedTestTarget;
private Method methodUnderTest;
private MethodExecutionResults result;
private final CoverageAnalyser<T> coverageAnalyser;
public MethodcallExecutor(Class<T> testClass, Method methodUnderTest) {
coverageAnalyser = new CoverageAnalyser<T>(testClass);
this.instrumentedTestTarget = coverageAnalyser.instrument();
this.methodUnderTest = methodUnderTest;
this.result = new MethodExecutionResults(instrumentedTestTarget, methodUnderTest);
}
public MethodExecutionResults executeAndGetResults(List<LinkedList> inputs) {
InvocationResult lastInvocationResult = null, previous = null;
int missedLines = Integer.MAX_VALUE;
for (LinkedList input : inputs) {
previous = lastInvocationResult;
lastInvocationResult = analyseMethodCall(methodUnderTest, input);
int missedCount = lastInvocationResult.getCoverage().getLineCounter().getMissedCount();
missedLines = addInOutputCombinationWhenCoverageIncreases(missedLines, lastInvocationResult, input,
missedCount);
if (fullyCoveraged(missedCount)) {
break;
}
}
if (lastInvocationResult != null) {
if (previous == null) {
result.setCoverageResult(lastInvocationResult.getCoverage());
} else {
result.setCoverageResult(previous.getCoverage());
}
}
return result;
}
private int addInOutputCombinationWhenCoverageIncreases(int missedLines, InvocationResult lastInvocationResult,
LinkedList input, int missedCount) {
if (coverageHasIncreased(missedLines, missedCount)) {
missedLines = missedCount;
addInterestingInAndOutput(input, lastInvocationResult);
}
return missedLines;
}
private void addInterestingInAndOutput(LinkedList input, InvocationResult lastInvocationResult) {
result.addResult(input, lastInvocationResult.getOutput());
}
private boolean fullyCoveraged(int missedCount) {
return missedCount == 0;
}
private boolean coverageHasIncreased(int missedLines, int missedCount) {
return missedCount < missedLines;
}
private InvocationResult analyseMethodCall(Method methodUnderTest, LinkedList input) {
Object[] inputs = replaceNullIndicatorWithNull(input.toArray());
return coverageAnalyser.analyse(instrumentedTestTarget, methodUnderTest, inputs);
}
private Object[] replaceNullIndicatorWithNull(Object[] argumentarray) {
for (int i = 0; i < argumentarray.length; i++) {
if (argumentarray[i].toString().equals("autounit:[NULL]")) {
argumentarray[i] = null;
}
}
return argumentarray;
}
}

View file

@ -9,28 +9,30 @@ import java.util.Map;
import nl.jssl.autounit.inputs.objects.ObjectArgumentFactory;
import nl.jssl.autounit.inputs.objects.StringArgumentFactory;
import nl.jssl.autounit.inputs.primtives.ArgumentFactory;
import nl.jssl.autounit.inputs.primtives.BooleanArgumentFactory;
import nl.jssl.autounit.inputs.primtives.ByteArgumentFactory;
import nl.jssl.autounit.inputs.primtives.DoubleArgumentFactory;
import nl.jssl.autounit.inputs.primtives.FloatArgumentFactory;
import nl.jssl.autounit.inputs.primtives.IntegerArgumentFactory;
import nl.jssl.autounit.utils.Permuter;
import nl.jssl.autounit.utils.Permuter.Tuple;
import nl.jssl.autounit.inputs.primitives.ArgumentFactory;
import nl.jssl.autounit.inputs.primitives.BooleanArgumentFactory;
import nl.jssl.autounit.inputs.primitives.ByteArgumentFactory;
import nl.jssl.autounit.inputs.primitives.DoubleArgumentFactory;
import nl.jssl.autounit.inputs.primitives.FloatArgumentFactory;
import nl.jssl.autounit.inputs.primitives.IntegerArgumentFactory;
import nl.jssl.autounit.util.LinkedList;
import nl.jssl.autounit.util.Permuter;
public class MethodcallArgumentsFactory {
private final Map<Class<?>, ArgumentFactory<?>> primitivesFactories;
private final Class<?> testTarget;
public MethodcallArgumentsFactory() {
public MethodcallArgumentsFactory(Class<?> testTarget) {
this.testTarget = testTarget;
primitivesFactories = new HashMap<Class<?>, ArgumentFactory<?>>();
populateFactories();
}
public List<Tuple> getInputs(Class<?> testTarget, Method m) {
return combine(getArgumentsForAllParameters(testTarget, m));
public List<LinkedList> getInputs(Method method) {
return combine(getArgumentsForAllParameters(method));
}
private List<Tuple> combine(List<List<?>> inputSetsForAllArguments) {
private List<LinkedList> combine(List<List<?>> inputSetsForAllArguments) {
int nrOfParameters = inputSetsForAllArguments.size();
if (nrOfParameters == 0) {
return Collections.emptyList();
@ -42,25 +44,25 @@ public class MethodcallArgumentsFactory {
}
}
private List<Tuple> makeArgumentsForSingleParameterCall(List<List<?>> generatedInputSetsForAllArguments) {
List<Tuple> allPossibleArguments = new ArrayList<Tuple>();
private List<LinkedList> makeArgumentsForSingleParameterCall(List<List<?>> generatedInputSetsForAllArguments) {
List<LinkedList> allPossibleArguments = new ArrayList<>();
List<?> generatedInputs = generatedInputSetsForAllArguments.iterator().next();
for (Object variable : generatedInputs) {
Tuple argument = new Tuple(variable);
LinkedList argument = new LinkedList(variable);
allPossibleArguments.add(argument);
}
return allPossibleArguments;
}
List<List<?>> getArgumentsForAllParameters(Class<?> testTarget, Method m) {
List<List<?>> getArgumentsForAllParameters(Method method) {
List<List<?>> singleInputSets = new ArrayList<List<?>>();
for (Class<?> parametertype : m.getParameterTypes()) {
List<?> inputs = tryPrimitives(testTarget, parametertype);
for (Class<?> parametertype : method.getParameterTypes()) {
List<?> inputs = tryPrimitives(parametertype);
if (inputs == null) {
inputs = new ObjectArgumentFactory().getObjectArgument(testTarget, parametertype);
inputs = new ObjectArgumentFactory().getObjectArgument(parametertype);
}
if (inputs != null) {
singleInputSets.add(inputs);
@ -69,7 +71,7 @@ public class MethodcallArgumentsFactory {
return singleInputSets;
}
private ArgumentsForSingleParameter<?> tryPrimitives(Class<?> testTarget, Class<?> parametertype) {
private ArgumentsForSingleParameter<?> tryPrimitives(Class<?> parametertype) {
ArgumentFactory<?> inputsFactory = primitivesFactories.get(parametertype);
if (inputsFactory != null) {
return inputsFactory.getInputs(testTarget);

View file

@ -2,21 +2,20 @@ package nl.jssl.autounit.inputs.objects;
import java.lang.reflect.Method;
import nl.jssl.autounit.inputs.ArgumentsForSingleParameter;
import nl.jssl.autounit.inputs.MethodcallArgumentsFactory;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import nl.jssl.autounit.inputs.ArgumentsForSingleParameter;
/**
* Creates arguments if they are objects. Methods that return values are populated like in regular mocking.
* Creates arguments if they are objects. Methods that return values are
* populated like in regular mocking.
*
*/
public class ObjectArgumentFactory {
private MethodcallArgumentsFactory argumentsFactory;
public ArgumentsForSingleParameter<?> getObjectArgument(Class<?> testTarget, Class<?> parametertype) {
public ArgumentsForSingleParameter<?> getObjectArgument(Class<?> parametertype) {
ArgumentsForSingleParameter<Object> inputs = new ArgumentsForSingleParameter<Object>();
Object mock = createMock(parametertype);
inputs.add(mock);
@ -44,12 +43,9 @@ public class ObjectArgumentFactory {
}
static boolean returnsVoid(Method m) {
Class<?> returnType = m.getReturnType();
static boolean returnsVoid(Method method) {
Class<?> returnType = method.getReturnType();
return returnType != Void.TYPE;
}
public void setArgumentsFactory(MethodcallArgumentsFactory argumentsFactory) {
this.argumentsFactory = argumentsFactory;
}
}

View file

@ -1,25 +1,24 @@
package nl.jssl.autounit.inputs.objects;
import javassist.ClassPool;
import nl.jssl.autounit.inputs.ArgumentsForSingleParameter;
import nl.jssl.autounit.inputs.primtives.ArgumentFactory;
import nl.jssl.autounit.utils.ConstantpoolReader;
import nl.jssl.autounit.inputs.primitives.ArgumentFactory;
import nl.jssl.autounit.util.ConstantpoolReader;
/**
* Creates Strings as arguments for a method call. Uses bytecode analysis to scan the class-under-test for "interesting"
* strings and adds them to the argument set.
* Creates Strings as arguments for a method call. Uses bytecode analysis to
* scan the class-under-test for "interesting" strings and adds them to the
* argument set.
*
* Also adds null to check for NPE. //is this feasible?
*/
public class StringArgumentFactory implements ArgumentFactory<String> {
private static ConstantpoolReader constantpoolReader = new ConstantpoolReader(ClassPool.getDefault());
@Override
public ArgumentsForSingleParameter<String> getInputs(Class<?> testTarget) {
ArgumentsForSingleParameter<String> inputs = new ArgumentsForSingleParameter<String>();
inputs.add(null);
inputs.add("some");
inputs.addAll(constantpoolReader.scanStrings(testTarget));
inputs.addAll(new ConstantpoolReader(testTarget).scanStrings());
return inputs;
}

View file

@ -1,4 +1,4 @@
package nl.jssl.autounit.inputs.primtives;
package nl.jssl.autounit.inputs.primitives;
import nl.jssl.autounit.inputs.ArgumentsForSingleParameter;

View file

@ -1,4 +1,4 @@
package nl.jssl.autounit.inputs.primtives;
package nl.jssl.autounit.inputs.primitives;
import nl.jssl.autounit.inputs.ArgumentsForSingleParameter;

View file

@ -1,4 +1,4 @@
package nl.jssl.autounit.inputs.primtives;
package nl.jssl.autounit.inputs.primitives;
import nl.jssl.autounit.inputs.ArgumentsForSingleParameter;

View file

@ -1,4 +1,4 @@
package nl.jssl.autounit.inputs.primtives;
package nl.jssl.autounit.inputs.primitives;
import nl.jssl.autounit.inputs.ArgumentsForSingleParameter;

View file

@ -1,4 +1,4 @@
package nl.jssl.autounit.inputs.primtives;
package nl.jssl.autounit.inputs.primitives;
import nl.jssl.autounit.inputs.ArgumentsForSingleParameter;

View file

@ -1,4 +1,4 @@
package nl.jssl.autounit.inputs.primtives;
package nl.jssl.autounit.inputs.primitives;
import nl.jssl.autounit.inputs.ArgumentsForSingleParameter;

View file

@ -1,4 +1,4 @@
package nl.jssl.autounit.inputs.primtives;
package nl.jssl.autounit.inputs.primitives;
import nl.jssl.autounit.inputs.ArgumentsForSingleParameter;

View file

@ -0,0 +1,92 @@
package nl.jssl.autounit.results;
import java.io.PrintStream;
import nl.jssl.autounit.classanalyser.ClassResults;
import nl.jssl.autounit.classanalyser.InAndOutput;
import nl.jssl.autounit.classanalyser.MethodExecutionResults;
public class JUnitSourceWriter extends ResultsWriter {
public JUnitSourceWriter(PrintStream out) {
super(out);
}
@Override
public void write(ClassResults results) {
writeTestClass(results);
}
private void writeTestClass(ClassResults results) {
out.println("package " + results.getType().getPackage().getName() + ";");
out.println();
out.println("import static org.junit.Assert.assertEquals;");
out.println("import org.junit.Test;");
out.println();
out.println("public class " + results.getType().getSimpleName() + "Tests {");
Count index = new Count(1);
for (MethodExecutionResults mcr : results.getMethodCallResults()) {
for (InAndOutput inout : mcr.getContents()) {
writeMethod(index, results, mcr, inout);
}
}
out.println("}");
}
private void writeMethod(Count index, ClassResults results, MethodExecutionResults mcr, InAndOutput inout) {
out.println("\t@Test");
out.println("\tpublic void " + mcr.getMethodName() + index.getValue() + "(){");
index.increment();
out.print("\t\tassertEquals(new " + results.getType().getSimpleName() + "()." + mcr.getMethodName() + "(");
int nrArguments = inout.getInput().depth();
int argumentCount = 1;
for (Object o : inout.getInput()) {
out.print(toString(o.getClass(), o));
if ((argumentCount++) < nrArguments) {
out.print(",");
}
}
out.print("), ");
out.print(toString(mcr.getMethodReturnType(), inout.getOutput()));
out.println(");");
out.println("\t}");
}
private String toString(Class<?> type, Object object) {
if (type.toString().equals("void")) {
return "void";
} else if (type == String.class) {
return "\"" + object + "\"";
} else if (type == Double.class || type == double.class) {
return object.toString() + "D";
} else if (type == Byte.class || type == byte.class) {
return "(byte)" + object.toString();
} else if (type == Integer.class || type == int.class) {
return object.toString();
} else if (type == Float.class || type == float.class) {
return object.toString() + "F";
} else if (type == Short.class || type == short.class) {
return "(short)" + object.toString();
} else if (type == Character.class || type == char.class) {
return "'" + object.toString() + "'";
} else
return object.toString();
}
static class Count {
private int value;
public Count(int value) {
this.value = value;
}
public void increment() {
value++;
}
public int getValue() {
return value;
}
}
}

View file

@ -0,0 +1,16 @@
package nl.jssl.autounit.results;
import java.io.PrintStream;
import nl.jssl.autounit.classanalyser.ClassResults;
public abstract class ResultsWriter {
protected PrintStream out;
public ResultsWriter(PrintStream out) {
super();
this.out = out;
}
public abstract void write(ClassResults classResults);
}

View file

@ -0,0 +1,56 @@
package nl.jssl.autounit.util;
import java.util.ArrayList;
import java.util.List;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import javassist.bytecode.ConstPool;
/**
* Reads the constantpool of a class (see jvm spec)
*/
public class ConstantpoolReader {
private final static ClassPool pool;
private final Class<?> classToRead;
private final List<String> strings = new ArrayList<String>();
static {
pool = ClassPool.getDefault();
}
public ConstantpoolReader(Class<?> classToRead) {
this.classToRead = classToRead;
}
public List<String> scanStrings() {
CtClass ctClass;
try {
ctClass = pool.get(classToRead.getName());
if (isScannable(ctClass)) {
ConstPool constPool = ctClass.getClassFile().getConstPool();
doScanStrings(constPool);
}
return strings;
} catch (NotFoundException e) {
throw new RuntimeException(e);
}
}
private void doScanStrings(ConstPool constPool) {
for (int i = 1; i < constPool.getSize(); i++) {
int tag = constPool.getTag(i);
if (tag == ConstPool.CONST_String) {
strings.add(constPool.getStringInfo(i));
}
}
}
private boolean isScannable(CtClass ctClass) {
return !ctClass.isFrozen();
}
}

View file

@ -0,0 +1,81 @@
package nl.jssl.autounit.util;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class LinkedList implements Iterable<Object> {
public final Object element1;
public final Object element2;
public LinkedList(Object element1) {
this.element1 = element1;
this.element2 = null;
}
public LinkedList(Object element1, Object element2) {
super();
this.element1 = element1;
this.element2 = element2;
}
public int depth() {
int d = 0;
if (element2 != null) {
if (element2 instanceof LinkedList) {
d += 1 + ((LinkedList) element2).depth();
} else {
d += 1;
}
}
if (element1 != null) {
if (element1 instanceof LinkedList) {
d += 1 + ((LinkedList) element1).depth();
} else {
d += 1;
}
}
return d;
}
@Override
public Iterator<Object> iterator() {
return asList().iterator();
}
private List<Object> asList() {
List<Object> list = new ArrayList<Object>();
if (element1 != null) {
add(element1, list);
} else {
add("autounit:[NULL]", list);
}
if (element2 != null) {
add(element2, list);
}
return list;
}
private void add(Object element, List<Object> list) {
if (element instanceof LinkedList) {
LinkedList pair = (LinkedList) element;
add(pair.element1, list);
add(pair.element2, list);
} else {
list.add(element);
}
}
@Override
public String toString() {
String string = "";
for (Object o : this) {
string += o.toString() + "-";
}
return string;
}
public Object[] toArray() {
return asList().toArray();
}
}

View file

@ -1,4 +1,4 @@
package nl.jssl.autounit.utils;
package nl.jssl.autounit.util;
import java.util.HashMap;
import java.util.Map;

View file

@ -0,0 +1,42 @@
package nl.jssl.autounit.util;
import java.util.ArrayList;
import java.util.List;
/**
* Makes permutations of n lists of m elements, ie:
*
* [A,B], [1,2] => [A,1], [A,2], [B,1], [B,2]
*/
public class Permuter {
public static List<LinkedList> permute(List<List<?>> elements) {
if (elements.size() >= 2) {
List<LinkedList> result = permutePairs(elements.remove(0), elements.remove(0));
result = permuteRest(elements, result);
return result;
} else {
throw new IllegalArgumentException("need at least 2");
}
}
private static List<LinkedList> permuteRest(List<List<?>> elements, List<LinkedList> result) {
for (List<?> element : elements) {
result = permutePairs(element, result);
}
return result;
}
private static List<LinkedList> permutePairs(List<?> list1, List<?> list2) {
List<LinkedList> pairs = new ArrayList<LinkedList>();
for (Object element1 : list1) {
for (Object element2 : list2) {
pairs.add(new LinkedList(element1, element2));
}
}
return pairs;
}
}

View file

@ -0,0 +1,37 @@
package nl.jssl.autounit.util;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import nl.jssl.autounit.classanalyser.AnalysisFailed;
import sun.reflect.ReflectionFactory;
/**
* Creates Objects from any class.
*
* Kindly copied from http://www.javaspecialists.eu/archive/Issue175.html
*/
public class SilentObjectCreator {
public static <T> T create(Class<T> clazz) {
return create(clazz, Object.class);
}
public static <T> T create(Class<T> clazz, Class<? super T> parent) {
try {
return tryCreateInstance(clazz, parent);
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException
| InvocationTargetException e) {
throw new AnalysisFailed("Cannot create object", e);
}
}
@SuppressWarnings("unchecked")
private static <T> T tryCreateInstance(Class<T> clazz, Class<? super T> parent)
throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();
Constructor<?> objDef = parent.getDeclaredConstructor();
Constructor<T> intConstr = (Constructor<T>) reflectionFactory.newConstructorForSerialization(clazz, objDef);
return clazz.cast(intConstr.newInstance());
}
}

View file

@ -1,46 +0,0 @@
package nl.jssl.autounit.utils;
import java.util.ArrayList;
import java.util.List;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import javassist.bytecode.ConstPool;
/**
*/
public class ConstantpoolReader {
private ClassPool pool;
public ConstantpoolReader(ClassPool pool) {
this.pool = pool;
}
public List<String> scanStrings(Class<?> target) {
CtClass ctClass;
try {
ctClass = pool.get(target.getName());
List<String> strings = new ArrayList<String>();
if (isScannable(ctClass)) {
ConstPool constPool = ctClass.getClassFile().getConstPool();
int size = constPool.getSize();
for (int i = 1; i < size; i++) {
int tag = constPool.getTag(i);
if (tag == ConstPool.CONST_String) {
strings.add(constPool.getStringInfo(i));
}
}
}
return strings;
} catch (NotFoundException e) {
throw new RuntimeException(e);
}
}
private boolean isScannable(CtClass ctClass) {
return !ctClass.isFrozen();
}
}

View file

@ -1,93 +0,0 @@
package nl.jssl.autounit.utils;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Makes permutations of n lists of m elements, ie:
*
* [A,B], [1,2] => [A,1], [A,2], [B,1], [B,2]
*/
public class Permuter {
public static List<Tuple> permute(List<List<?>> elements) {
if (elements.size() >= 2) {
List<Tuple> result = permutePairs(elements.remove(0), elements.remove(0));
for (List<?> element : elements) {
result = permutePairs(element, result);
}
return result;
} else {
throw new IllegalArgumentException("need at least 2");
}
}
private static List<Tuple> permutePairs(List<?> list1, List<?> list2) {
List<Tuple> pairs = new ArrayList<Tuple>();
for (Object element1 : list1) {
for (Object element2 : list2) {
pairs.add(new Tuple(element1, element2));
}
}
return pairs;
}
public static class Tuple implements Iterable<Object> {
public final Object element1;
public final Object element2;
public Tuple(Object element1) {
this.element1 = element1;
this.element2 = null;
}
public Tuple(Object element1, Object element2) {
super();
this.element1 = element1;
this.element2 = element2;
}
@Override
public Iterator<Object> iterator() {
return asList().iterator();
}
private List<Object> asList() {
List<Object> list = new ArrayList<Object>();
if (element1 != null) {
add(element1, list);
} else {
add("autounit:[NULL]", list);
}
if (element2 != null) {
add(element2, list);
}
return list;
}
private void add(Object element, List<Object> list) {
if (!(element instanceof Tuple)) {
list.add(element);
} else {
Tuple pair = (Tuple) element;
add(pair.element1, list);
add(pair.element2, list);
}
}
@Override
public String toString() {
String string = "";
for (Object o : this) {
string += o.toString() + "-";
}
return string;
}
public Object[] toArray() {
return asList().toArray();
}
}
}

View file

@ -1,29 +0,0 @@
package nl.jssl.autounit.utils;
import java.lang.reflect.Constructor;
import sun.reflect.ReflectionFactory;
/**
* Creates Objects from any class.
*
* Kindly copied from http://www.javaspecialists.eu/archive/Issue175.html
*/
public class SilentObjectCreator {
public static <T> T create(Class<T> clazz) {
return create(clazz, Object.class);
}
public static <T> T create(Class<T> clazz, Class<? super T> parent) {
try {
ReflectionFactory rf = ReflectionFactory.getReflectionFactory();
Constructor<?> objDef = parent.getDeclaredConstructor();
Constructor<T> intConstr = (Constructor<T>) rf.newConstructorForSerialization(clazz, objDef);
return clazz.cast(intConstr.newInstance());
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new IllegalStateException("Cannot create object", e);
}
}
}

View file

@ -1,33 +0,0 @@
package nl.jssl.autounit.utils;
import nl.jssl.autounit.utils.Permuter.Tuple;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
public class XStreamArgumentsConverter implements Converter {
@SuppressWarnings("rawtypes")
public boolean canConvert(Class clazz) {
return (clazz == Tuple.class);
}
public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
Tuple arguments = (Tuple) value;
int index = 1;
for (Object arg : arguments) {
writer.startNode("arg" + index);
writer.setValue(arg.toString());
writer.endNode();
}
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
return null;
}
}

View file

@ -1,66 +0,0 @@
package nl.jssl.autounit;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.Set;
import nl.jssl.autounit.testclasses.BooleanArguments;
import nl.jssl.autounit.testclasses.ByteArguments;
import nl.jssl.autounit.testclasses.FloatArguments;
import nl.jssl.autounit.testclasses.IntArguments;
import org.junit.Test;
public class PrimtiveTypeTests {
@Test
public void testGetPublicMethods() throws NoSuchMethodException, SecurityException {
List<Method> publicMethods = new Recorder(IntArguments.class).getPublicMethods();
assertEquals(2, publicMethods.size());
}
@Test
public void testIntegerArgument() {
Map<String, MethodCallResults> results = new AutoTester().record(IntArguments.class);
Set<String> keys = results.keySet();
assertTrue(keys.contains("public java.lang.String evenOrUneven(int arg1,int arg2)"));
MethodCallResults mcr = results.values().iterator().next();
System.out.println(mcr.getCoverageResult().getLineCounter().getMissedCount() + " missed lines");
System.out.println(mcr.getReport());
}
@Test
public void testBooleanArgument() {
Map<String, MethodCallResults> results = new AutoTester().record(BooleanArguments.class);
Set<String> keys = results.keySet();
assertTrue(keys.contains("public java.lang.String getText(boolean arg1,boolean arg2)"));
MethodCallResults mcr = results.values().iterator().next();
System.out.println(mcr.getCoverageResult().getLineCounter().getMissedCount() + " missed lines");
System.out.println(mcr.getReport());
}
@Test
public void testByteArgument() {
Map<String, MethodCallResults> results = new AutoTester().record(ByteArguments.class);
Set<String> keys = results.keySet();
assertTrue(keys.contains("public int getDouble(byte arg1)"));
MethodCallResults mcr = results.values().iterator().next();
System.out.println(mcr.getCoverageResult().getLineCounter().getMissedCount() + " missed lines");
System.out.println(mcr.getReport());
}
@Test
public void testFloatArgument() {
Map<String, MethodCallResults> results = new AutoTester().record(FloatArguments.class);
Set<String> keys = results.keySet();
assertTrue(keys.contains("public int round(float arg1)"));
MethodCallResults mcr = results.values().iterator().next();
System.out.println(mcr.getCoverageResult().getLineCounter().getMissedCount() + " missed lines");
System.out.println(mcr.getReport());
}
}

View file

@ -0,0 +1,56 @@
package nl.jssl.autounit.classanalyser;
import static org.junit.Assert.assertEquals;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.List;
import java.util.TreeSet;
import org.junit.Test;
import nl.jssl.autounit.testclasses.BooleanArguments;
import nl.jssl.autounit.testclasses.ByteArguments;
import nl.jssl.autounit.testclasses.FloatArguments;
import nl.jssl.autounit.testclasses.IntArguments;
public class PrimtiveTypeTests {
@Test
public void testGetPublicMethods() throws NoSuchMethodException, SecurityException {
List<Method> publicMethods = new ClassAnalyser<>(IntArguments.class).getPublicMethods();
assertEquals(2, publicMethods.size());
}
@Test
public void testIntegerArgument() {
Iterator<MethodExecutionResults> methodCallResults = new TreeSet<>(
new ClassAnalyser<>(IntArguments.class).analyseAndGetResults().getMethodCallResults()).iterator();
assertEquals("public java.lang.String evenOrUneven(int arg1,int arg2)",
methodCallResults.next().getMethodSignature());
assertEquals("public int randomOther(int arg1)", methodCallResults.next().getMethodSignature());
}
@Test
public void testBooleanArgument() {
MethodExecutionResults mcr = new ClassAnalyser<>(BooleanArguments.class).analyseAndGetResults()
.getMethodCallResults().get(0);
assertEquals(mcr.getMethodSignature(), "public java.lang.String getText(boolean arg1,boolean arg2)");
}
@Test
public void testByteArgument() {
MethodExecutionResults mcr = new ClassAnalyser<>(ByteArguments.class).analyseAndGetResults().getMethodCallResults()
.get(0);
assertEquals(mcr.getMethodSignature(), "public int getDouble(byte arg1)");
}
@Test
public void testFloatArgument() {
MethodExecutionResults mcr = new ClassAnalyser<>(FloatArguments.class).analyseAndGetResults().getMethodCallResults()
.get(0);
assertEquals(mcr.getMethodSignature(), "public int round(float arg1)");
}
}

View file

@ -1,23 +1,22 @@
package nl.jssl.autounit;
package nl.jssl.autounit.classanalyser;
import static org.junit.Assert.assertEquals;
import java.util.Map;
import java.util.Set;
import nl.jssl.autounit.testclasses.StringArguments;
import java.util.List;
import org.junit.Test;
import nl.jssl.autounit.testclasses.StringArguments;
public class StringTypeTests {
@Test
public void testStringArgumentShouldBeTjeempie() {
Map<String, MethodCallResults> results = new AutoTester().record(StringArguments.class);
Set<String> keys = results.keySet();
String methodSignature = keys.iterator().next();
List<MethodExecutionResults> results = new ClassAnalyser<>(StringArguments.class).analyseAndGetResults()
.getMethodCallResults();
MethodExecutionResults mcr = results.get(0);
String methodSignature = mcr.getMethodSignature();
assertEquals("public boolean getBar(java.lang.String arg1)", methodSignature);
MethodCallResults mcr = results.values().iterator().next();
System.out.println(mcr.getCoverageResult().getLineCounter().getMissedCount() + " missed lines");
System.out.println(mcr.getReport());
}
@ -28,7 +27,8 @@ public class StringTypeTests {
// Map<String, MethodCallResults> results = new
// AutoTester().record(MethodSignatureMaker.class);
// Set<String> keys = results.keySet();
// assertTrue(keys.contains("public java.lang.String getMethodSignature(java.lang.reflect.Method arg1)"));
// assertTrue(keys.contains("public java.lang.String
// getMethodSignature(java.lang.reflect.Method arg1)"));
// MethodCallResults mcr = results.values().iterator().next();
// System.out.println(mcr.getCoverageResult().getLineCounter().getMissedCount()
// + " missed lines");

View file

@ -1,23 +1,34 @@
package nl.jssl.autounit.inputs.objects;
import java.util.Map;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import nl.jssl.autounit.AutoTester;
import nl.jssl.autounit.MethodCallResults;
import nl.jssl.autounit.testclasses.SomeBean;
import java.util.Iterator;
import java.util.TreeSet;
import org.junit.Assert;
import org.junit.Test;
import nl.jssl.autounit.JUnitTestCreator;
import nl.jssl.autounit.classanalyser.ClassAnalyser;
import nl.jssl.autounit.classanalyser.MethodExecutionResults;
import nl.jssl.autounit.testclasses.SomeBean;
public class JavaBeanTests {
@Test
public void testJavaBeanArgument() {
Map<String, MethodCallResults> results = new AutoTester().record(SomeBean.class);
Set<String> keys = results.keySet();
Assert.assertTrue(keys.contains("public void setFoo(java.lang.String arg1)"));
MethodCallResults mcr = results.values().iterator().next();
System.out.println(mcr.getCoverageResult().getLineCounter().getMissedCount() + " missed lines");
System.out.println(mcr.getReport());
Iterator<MethodExecutionResults> results = getSortedAnalysisResults().iterator();
assertEquals("public int getBar()", results.next().getMethodSignature());
assertEquals("public java.lang.String getFoo()", results.next().getMethodSignature());
assertEquals("public void setBar(int arg1)", results.next().getMethodSignature());
assertEquals("public void setFoo(java.lang.String arg1)", results.next().getMethodSignature());
}
private TreeSet<MethodExecutionResults> getSortedAnalysisResults() {
return new TreeSet<>(new ClassAnalyser<>(SomeBean.class).analyseAndGetResults().getMethodCallResults());
}
@Test
public void getUnittest() {
new JUnitTestCreator<>(SomeBean.class).create();
}
}

View file

@ -1,5 +1,6 @@
package nl.jssl.autounit.inputs.objects;
import static nl.jssl.autounit.inputs.objects.ObjectArgumentFactory.returnsVoid;
import static org.junit.Assert.assertEquals;
import java.lang.reflect.Method;
@ -9,12 +10,11 @@ import org.junit.Test;
public class ObjectArgumentFactoryTests {
@Test
public void testVoidReturn() throws NoSuchMethodException, SecurityException {
ObjectArgumentFactory o = new ObjectArgumentFactory();
Method testVoidReturnMethod = ObjectArgumentFactoryTests.class.getMethod("testVoidReturn", new Class<?>[] {});
assertEquals(false, o.returnsVoid(testVoidReturnMethod));
assertEquals(false, returnsVoid(testVoidReturnMethod));
Method getBarMethod = ObjectArgumentFactoryTests.class.getMethod("getBar", new Class<?>[] {});
assertEquals(true, o.returnsVoid(getBarMethod));
assertEquals(true, returnsVoid(getBarMethod));
}
public String getBar() {

View file

@ -2,20 +2,17 @@ package nl.jssl.autounit.inspect;
import java.util.List;
import javassist.ClassPool;
import org.junit.Test;
import javassist.NotFoundException;
import nl.jssl.autounit.testclasses.IntArguments;
import nl.jssl.autounit.utils.ConstantpoolReader;
import org.junit.Test;
import nl.jssl.autounit.util.ConstantpoolReader;
public class ConstantpoolReaderTest {
@Test
public void test() throws NotFoundException {
ClassPool classPool = new ClassPool();
classPool.appendClassPath("c:\\workspaces\\autounit\\autounit\\bin");
ConstantpoolReader reader = new ConstantpoolReader(classPool);
List<String> strings = reader.scanStrings(IntArguments.class);
ConstantpoolReader reader = new ConstantpoolReader(IntArguments.class);
List<String> strings = reader.scanStrings();
for (String string : strings) {
System.out.println(string);
}

View file

@ -0,0 +1,25 @@
package nl.jssl.autounit.util;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class PairTests {
@Test
public void testDepth1() {
LinkedList p = new LinkedList("1");
assertEquals(1, p.depth());
}
@Test
public void testDepth2() {
LinkedList p = new LinkedList(new LinkedList("1"));
assertEquals(2, p.depth());
}
@Test
public void testDepth3() {
LinkedList p = new LinkedList(new LinkedList(new LinkedList("1")));
assertEquals(3, p.depth());
}
}

View file

@ -5,9 +5,6 @@ import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.List;
import nl.jssl.autounit.utils.Permuter;
import nl.jssl.autounit.utils.Permuter.Tuple;
import org.junit.Test;
public class PermuterTests {
@ -16,13 +13,16 @@ public class PermuterTests {
List<Integer> integers = new ArrayList<Integer>();
integers.add(1);
integers.add(2);
List<String> strings = new ArrayList<String>();
strings.add("A");
strings.add("B");
List<List<?>> outer = new ArrayList<List<?>>();
outer.add(integers);
outer.add(strings);
List<Tuple> permuted = Permuter.permute(outer);
List<LinkedList> permuted = Permuter.permute(outer);
assertEquals("1-A-", permuted.get(0).toString());
assertEquals("1-B-", permuted.get(1).toString());
assertEquals("2-A-", permuted.get(2).toString());
@ -46,7 +46,7 @@ public class PermuterTests {
outer.add(strings);
outer.add(vogons);
List<Tuple> permuted = Permuter.permute(outer);
List<LinkedList> permuted = Permuter.permute(outer);
assertEquals("Vogon Jeltz-1-A-", permuted.get(0).toString());
assertEquals("Vogon Jeltz-1-B-", permuted.get(1).toString());
assertEquals("Vogon Jeltz-2-A-", permuted.get(2).toString());

View file

@ -6,7 +6,7 @@ public class MyMethod {
return 0;
}
public Class getReturnType() {
public Class<?> getReturnType() {
return Void.class;
}