package org.argeo.util.test; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.TreeMap; /** A generic tester based on Java assertions and functional programming. */ public class Test { private Map results = Collections.synchronizedSortedMap(new TreeMap<>()); protected void execute(String className) throws Throwable { ClassLoader classLoader = Test.class.getClassLoader(); Class clss = classLoader.loadClass(className); boolean assertionsEnabled = clss.desiredAssertionStatus(); if (!assertionsEnabled) throw new IllegalStateException("Test runner " + getClass().getName() + " requires Java assertions to be enabled. Call the JVM with the -ea argument."); Object obj = clss.getDeclaredConstructor().newInstance(); List methods = findMethods(clss); if (methods.size() == 0) throw new IllegalArgumentException("No test method found in " + clss); // TODO make order more predictable? for (Method method : methods) { String uid = method.getDeclaringClass().getName() + "#" + method.getName(); TestStatus testStatus = new TestStatus(uid); try { method.invoke(obj); testStatus.setPassed(); } catch (Exception e) { testStatus.setFailed(e); } finally { results.put(uid, testStatus); } } } protected List findMethods(Class clss) { List methods = new ArrayList(); // Method call = getMethod(clss, "call"); // if (call != null) // methods.add(call); // for (Method method : clss.getMethods()) { if (method.getName().startsWith("test")) { methods.add(method); } } return methods; } protected Method getMethod(Class clss, String name, Class... parameterTypes) { try { return clss.getMethod(name, parameterTypes); } catch (NoSuchMethodException e) { return null; } catch (SecurityException e) { throw new IllegalStateException(e); } } public static void main(String[] args) { // deal with arguments String className; if (args.length < 1) { System.err.println(usage()); System.exit(1); throw new IllegalArgumentException(); } else { className = args[0]; } Test test = new Test(); try { test.execute(className); } catch (Throwable e) { e.printStackTrace(); } Map r = test.results; for (String uid : r.keySet()) { TestStatus testStatus = r.get(uid); System.out.println(testStatus); } } public static String usage() { return "java " + Test.class.getName() + " [test class name]"; } }