FileDocCategorySizeDatePackage
TestRunner.javaAPI DocAndroid 1.5 API24397Wed May 06 22:42:02 BST 2009android.test

TestRunner

public class TestRunner extends Object implements PerformanceTestCase.Intermediates
Support class that actually runs a test. Android uses this class, and you probably will not need to instantiate, extend, or call this class yourself. See the full {@link android.test} package description to learn more about testing Android applications. {@hide} Not needed for 1.0 SDK.

Fields Summary
public static final int
REGRESSION
public static final int
PERFORMANCE
public static final int
PROFILING
public static final int
CLEARSCREEN
private static final String
TAG
private android.content.Context
mContext
private int
mMode
private List
mListeners
private int
mPassed
private int
mFailed
private int
mInternalIterations
private long
mStartTime
private long
mEndTime
private String
mClassName
List
mIntermediates
private static Class
mRunnableClass
private static Class
mJUnitClass
Constructors Summary
public TestRunner(android.content.Context context)

        mContext = context;
    
Methods Summary
public voidaddIntermediate(java.lang.String name)

        addIntermediate(name, (System.currentTimeMillis() - mStartTime) * 1000000);
    
public voidaddIntermediate(java.lang.String name, long timeInNS)

        mIntermediates.add(new IntermediateTime(name, timeInNS));
    
public voidaddListener(android.test.TestRunner$Listener listener)

        mListeners.add(listener);
    
public static intcountJunitTests(java.lang.Class clazz)

        Method[] allTestMethods = getAllTestMethods(clazz);
        int numberofMethods = allTestMethods.length;

        return numberofMethods;
    
public static intcountTests(android.content.Context c, java.lang.String className)
Returns the number of tests that will be run if you try to do this.

        try {
            Class clazz = c.getClassLoader().loadClass(className);
            Method method = getChildrenMethod(clazz);
            if (method != null) {

                String[] children = getChildren(method);
                int rv = 0;
                for (String child : children) {
                    rv += countTests(c, child);
                }
                return rv;
            } else if (mRunnableClass.isAssignableFrom(clazz)) {
                return 1;
            } else if (mJUnitClass.isAssignableFrom(clazz)) {
                return countJunitTests(clazz);
            }
        } catch (ClassNotFoundException e) {
            return 1; // this gets the count right, because either this test
            // is missing, and it will fail when run or it is a single Junit test to be run. 
        }
        return 0;
    
public voidfailed(java.lang.String className, java.lang.Throwable exception)

        mFailed++;
        int count = mListeners.size();
        for (int i = 0; i < count; i++) {
            mListeners.get(i).failed(className, exception);
        }
    
public intfailedCount()

        return mFailed;
    
public voidfinishProfiling()

        Debug.stopMethodTracing();
    
public voidfinishTiming(boolean realTime)

        if (realTime) {
            mEndTime = System.currentTimeMillis();
        } else {
            mEndTime = SystemClock.currentThreadTimeMillis();
        }
    
private voidfinished(java.lang.String className)

        int count = mListeners.size();
        for (int i = 0; i < count; i++) {
            mListeners.get(i).finished(className);
        }
    
public static java.lang.reflect.Method[]getAllTestMethods(java.lang.Class clazz)

        Method[] allMethods = clazz.getDeclaredMethods();
        int numOfMethods = 0;
        for (Method m : allMethods) {
            boolean mTrue = isTestMethod(m);
            if (mTrue) {
                numOfMethods++;
            }
        }
        int index = 0;
        Method[] testMethods = new Method[numOfMethods];
        for (Method m : allMethods) {
            boolean mTrue = isTestMethod(m);
            if (mTrue) {
                testMethods[index] = m;
                index++;
            }
        }
        return testMethods;
    
public static java.lang.String[]getChildren(android.content.Context c, java.lang.String className)

        Method m = getChildrenMethod(c, className);
        String[] testChildren = getTestChildren(c, className);
        if (m == null & testChildren == null) {
            throw new RuntimeException("couldn't get children method for "
                    + className);
        }
        if (m != null) {
            String[] children = getChildren(m);
            if (testChildren != null) {
                String[] allChildren = new String[testChildren.length + children.length];
                System.arraycopy(children, 0, allChildren, 0, children.length);
                System.arraycopy(testChildren, 0, allChildren, children.length, testChildren.length);
                return allChildren;
            } else {
                return children;
            }
        } else {
            if (testChildren != null) {
                return testChildren;
            }
        }
        return null;
    
public static java.lang.String[]getChildren(java.lang.reflect.Method m)

        try {
            if (!Modifier.isStatic(m.getModifiers())) {
                throw new RuntimeException("children method is not static");
            }
            return (String[]) m.invoke(null, (Object[]) null);
        } catch (IllegalAccessException e) {
        } catch (InvocationTargetException e) {
        }
        return new String[0];
    
public static java.lang.reflect.MethodgetChildrenMethod(java.lang.Class clazz)

        try {
            return clazz.getMethod("children", (Class[]) null);
        } catch (NoSuchMethodException e) {
        }

        return null;
    
public static java.lang.reflect.MethodgetChildrenMethod(android.content.Context c, java.lang.String className)

        try {
            return getChildrenMethod(c.getClassLoader().loadClass(className));
        } catch (ClassNotFoundException e) {
        }
        return null;
    
public static java.lang.String[]getTestChildren(android.content.Context c, java.lang.String className)

        try {
            Class clazz = c.getClassLoader().loadClass(className);

            if (mJUnitClass.isAssignableFrom(clazz)) {
                return getTestChildren(clazz);
            }
        } catch (ClassNotFoundException e) {
            Log.e("TestHarness", "No class found", e);
        }
        return null;
    
public static java.lang.String[]getTestChildren(java.lang.Class clazz)

        Method[] methods = getAllTestMethods(clazz);

        String[] onScreenTestNames = new String[methods.length];
        int index = 0;
        for (Method m : methods) {
            onScreenTestNames[index] = clazz.getName() + "$" + m.getName();
            index++;
        }
        return onScreenTestNames;
    
public static java.lang.StringgetTitle(java.lang.String className)
Returns a title to display given the className of a test.

Currently this function just returns the portion of the class name after the last '.'

        int indexDot = className.lastIndexOf('.");
        int indexDollar = className.lastIndexOf('$");
        int index = indexDot > indexDollar ? indexDot : indexDollar;
        if (index >= 0) {
            className = className.substring(index + 1);
        }
        return className;
    
public booleanisJunitTest(java.lang.String className)

        int index = className.lastIndexOf('$");
        if (index >= 0) {
            className = className.substring(0, index);
        }
        try {
            Class clazz = mContext.getClassLoader().loadClass(className);
            if (mJUnitClass.isAssignableFrom(clazz)) {
                return true;
            }
        } catch (ClassNotFoundException e) {
        }
        return false;
    
private static booleanisTestMethod(java.lang.reflect.Method m)

        return m.getName().startsWith("test") &&
                m.getReturnType() == void.class &&
                m.getParameterTypes().length == 0;
    
public static booleanisTestSuite(android.content.Context c, java.lang.String className)

        boolean childrenMethods = getChildrenMethod(c, className) != null;

        try {
            Class clazz = c.getClassLoader().loadClass(className);
            if (mJUnitClass.isAssignableFrom(clazz)) {
                int numTests = countJunitTests(clazz);
                if (numTests > 0)
                    childrenMethods = true;
            }
        } catch (ClassNotFoundException e) {
        }
        return childrenMethods;
    
private voidmissingTest(java.lang.String className, java.lang.Throwable e)

        started(className);
        finished(className);
        failed(className, e);
    
public voidpassed(java.lang.String className)

        mPassed++;
        int count = mListeners.size();
        for (int i = 0; i < count; i++) {
            mListeners.get(i).passed(className);
        }
    
public intpassedCount()

        return mPassed;
    
private voidperformance(java.lang.String className, long itemTimeNS, int iterations, java.util.List intermediates)

        int count = mListeners.size();
        for (int i = 0; i < count; i++) {
            mListeners.get(i).performance(className,
                    itemTimeNS,
                    iterations,
                    intermediates);
        }
    
public voidrun(java.lang.String[] classes)

        for (String cl : classes) {
            run(cl);
        }
    
public voidrun(java.lang.String className)

        try {
            mClassName = className;
            Class clazz = mContext.getClassLoader().loadClass(className);
            Method method = getChildrenMethod(clazz);
            if (method != null) {
                String[] children = getChildren(method);
                run(children);
            } else if (mRunnableClass.isAssignableFrom(clazz)) {
                Runnable test = (Runnable) clazz.newInstance();
                TestCase testcase = null;
                if (test instanceof TestCase) {
                    testcase = (TestCase) test;
                }
                Throwable e = null;
                boolean didSetup = false;
                started(className);
                try {
                    if (testcase != null) {
                        testcase.setUp(mContext);
                        didSetup = true;
                    }
                    if (mMode == PERFORMANCE) {
                        runInPerformanceMode(test, className, false, className);
                    } else if (mMode == PROFILING) {
                        //Need a way to mark a test to be run in profiling mode or not. 
                        startProfiling();
                        test.run();
                        finishProfiling();
                    } else {
                        test.run();
                    }
                } catch (Throwable ex) {
                    e = ex;
                }
                if (testcase != null && didSetup) {
                    try {
                        testcase.tearDown();
                    } catch (Throwable ex) {
                        e = ex;
                    }
                }
                finished(className);
                if (e == null) {
                    passed(className);
                } else {
                    failed(className, e);
                }
            } else if (mJUnitClass.isAssignableFrom(clazz)) {
                Throwable e = null;
                //Create a Junit Suite.
                JunitTestSuite suite = new JunitTestSuite();
                Method[] methods = getAllTestMethods(clazz);
                for (Method m : methods) {
                    junit.framework.TestCase test = (junit.framework.TestCase) clazz.newInstance();
                    test.setName(m.getName());

                    if (test instanceof AndroidTestCase) {
                        AndroidTestCase testcase = (AndroidTestCase) test;
                        try {
                            testcase.setContext(mContext);
                        } catch (Exception ex) {
                            Log.i("TestHarness", ex.toString());
                        }
                    }
                    suite.addTest(test);
                }
                if (mMode == PERFORMANCE) {
                    final int testCount = suite.testCount();

                    for (int j = 0; j < testCount; j++) {
                        Test test = suite.testAt(j);
                        started(test.toString());
                        try {
                            runInPerformanceMode(test, className, true, test.toString());
                        } catch (Throwable ex) {
                            e = ex;
                        }
                        finished(test.toString());
                        if (e == null) {
                            passed(test.toString());
                        } else {
                            failed(test.toString(), e);
                        }
                    }
                } else if (mMode == PROFILING) {
                    //Need a way to mark a test to be run in profiling mode or not.
                    startProfiling();
                    junit.textui.TestRunner.run(suite);
                    finishProfiling();
                } else {
                    junit.textui.TestRunner.run(suite);
                }
            } else {
                System.out.println("Test wasn't Runnable and didn't have a"
                        + " children method: " + className);
            }
        } catch (ClassNotFoundException e) {
            Log.e("ClassNotFoundException for " + className, e.toString());
            if (isJunitTest(className)) {
                runSingleJunitTest(className);
            } else {
                missingTest(className, e);
            }
        } catch (InstantiationException e) {
            System.out.println("InstantiationException for " + className);
            missingTest(className, e);
        } catch (IllegalAccessException e) {
            System.out.println("IllegalAccessException for " + className);
            missingTest(className, e);
        }
    
public voidrunInPerformanceMode(java.lang.Object testCase, java.lang.String className, boolean junitTest, java.lang.String testNameInDb)

        boolean increaseIterations = true;
        int iterations = 1;
        long duration = 0;
        mIntermediates = null;

        mInternalIterations = 1;
        Class clazz = mContext.getClassLoader().loadClass(className);
        Object perftest = clazz.newInstance();

        PerformanceTestCase perftestcase = null;
        if (perftest instanceof PerformanceTestCase) {
            perftestcase = (PerformanceTestCase) perftest;
            // only run the test if it is not marked as a performance only test
            if (mMode == REGRESSION && perftestcase.isPerformanceOnly()) return;
        }

        // First force GCs, to avoid GCs happening during out
        // test and skewing its time.
        Runtime.getRuntime().runFinalization();
        Runtime.getRuntime().gc();

        if (perftestcase != null) {
            mIntermediates = new ArrayList<IntermediateTime>();
            iterations = perftestcase.startPerformance(this);
            if (iterations > 0) {
                increaseIterations = false;
            } else {
                iterations = 1;
            }
        }

        // Pause briefly to let things settle down...
        Thread.sleep(1000);
        do {
            mEndTime = 0;
            if (increaseIterations) {
                // Test case does not implement
                // PerformanceTestCase or returned 0 iterations,
                // so we take care of measure the whole test time.
                mStartTime = SystemClock.currentThreadTimeMillis();
            } else {
                // Try to make it obvious if the test case
                // doesn't call startTiming().
                mStartTime = 0;
            }

            if (junitTest) {
                for (int i = 0; i < iterations; i++) {
                    junit.textui.TestRunner.run((junit.framework.Test) testCase);
                }
            } else {
                Runnable test = (Runnable) testCase;
                for (int i = 0; i < iterations; i++) {
                    test.run();
                }
            }

            long endTime = mEndTime;
            if (endTime == 0) {
                endTime = SystemClock.currentThreadTimeMillis();
            }

            duration = endTime - mStartTime;
            if (!increaseIterations) {
                break;
            }
            if (duration <= 1) {
                iterations *= 1000;
            } else if (duration <= 10) {
                iterations *= 100;
            } else if (duration < 100) {
                iterations *= 10;
            } else if (duration < 1000) {
                iterations *= (int) ((1000 / duration) + 2);
            } else {
                break;
            }
        } while (true);

        if (duration != 0) {
            iterations *= mInternalIterations;
            performance(testNameInDb, (duration * 1000000) / iterations,
                    iterations, mIntermediates);
        }
    
public voidrunSingleJunitTest(java.lang.String className)

        Throwable excep = null;
        int index = className.lastIndexOf('$");
        String testName = "";
        String originalClassName = className;
        if (index >= 0) {
            className = className.substring(0, index);
            testName = originalClassName.substring(index + 1);
        }
        try {
            Class clazz = mContext.getClassLoader().loadClass(className);
            if (mJUnitClass.isAssignableFrom(clazz)) {
                junit.framework.TestCase test = (junit.framework.TestCase) clazz.newInstance();
                JunitTestSuite newSuite = new JunitTestSuite();
                test.setName(testName);

                if (test instanceof AndroidTestCase) {
                    AndroidTestCase testcase = (AndroidTestCase) test;
                    try {
                        testcase.setContext(mContext);
                    } catch (Exception ex) {
                        Log.w(TAG, "Exception encountered while trying to set the context.", ex);
                    }
                }
                newSuite.addTest(test);

                if (mMode == PERFORMANCE) {
                    try {
                        started(test.toString());
                        runInPerformanceMode(test, className, true, test.toString());
                        finished(test.toString());
                        if (excep == null) {
                            passed(test.toString());
                        } else {
                            failed(test.toString(), excep);
                        }
                    } catch (Throwable ex) {
                        excep = ex;
                    }

                } else if (mMode == PROFILING) {
                    startProfiling();
                    junit.textui.TestRunner.run(newSuite);
                    finishProfiling();
                } else {
                    junit.textui.TestRunner.run(newSuite);
                }
            }
        } catch (ClassNotFoundException e) {
            Log.e("TestHarness", "No test case to run", e);
        } catch (IllegalAccessException e) {
            Log.e("TestHarness", "Illegal Access Exception", e);
        } catch (InstantiationException e) {
            Log.e("TestHarness", "Instantiation Exception", e);
        }
    
public voidsetInternalIterations(int count)

        mInternalIterations = count;
    
public voidsetPerformanceMode(int mode)

        mMode = mode;
    
public voidstartProfiling()

        File file = new File("/tmp/trace");
        file.mkdir();
        String base = "/tmp/trace/" + mClassName + ".dmtrace";
        Debug.startMethodTracing(base, 8 * 1024 * 1024);
    
public voidstartTiming(boolean realTime)

        if (realTime) {
            mStartTime = System.currentTimeMillis();
        } else {
            mStartTime = SystemClock.currentThreadTimeMillis();
        }
    
private voidstarted(java.lang.String className)


        int count = mListeners.size();
        for (int i = 0; i < count; i++) {
            mListeners.get(i).started(className);
        }