724 lines
24 KiB
Java
724 lines
24 KiB
Java
|
/*
|
||
|
* Copyright (C) 2006 The Android Open Source Project
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*/
|
||
|
|
||
|
package android.test;
|
||
|
|
||
|
import android.content.Context;
|
||
|
import android.util.Log;
|
||
|
import android.os.Debug;
|
||
|
import android.os.SystemClock;
|
||
|
|
||
|
import java.io.File;
|
||
|
import java.lang.reflect.InvocationTargetException;
|
||
|
import java.lang.reflect.Method;
|
||
|
import java.lang.reflect.Modifier;
|
||
|
import java.util.ArrayList;
|
||
|
import java.util.List;
|
||
|
|
||
|
import junit.framework.TestSuite;
|
||
|
import junit.framework.TestListener;
|
||
|
import junit.framework.Test;
|
||
|
import junit.framework.TestResult;
|
||
|
import com.google.android.collect.Lists;
|
||
|
|
||
|
/**
|
||
|
* 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.
|
||
|
*/
|
||
|
public class TestRunner implements PerformanceTestCase.Intermediates {
|
||
|
public static final int REGRESSION = 0;
|
||
|
public static final int PERFORMANCE = 1;
|
||
|
public static final int PROFILING = 2;
|
||
|
|
||
|
public static final int CLEARSCREEN = 0;
|
||
|
private static final String TAG = "TestHarness";
|
||
|
private Context mContext;
|
||
|
|
||
|
private int mMode = REGRESSION;
|
||
|
|
||
|
private List<Listener> mListeners = Lists.newArrayList();
|
||
|
private int mPassed;
|
||
|
private int mFailed;
|
||
|
|
||
|
private int mInternalIterations;
|
||
|
private long mStartTime;
|
||
|
private long mEndTime;
|
||
|
|
||
|
private String mClassName;
|
||
|
|
||
|
List<IntermediateTime> mIntermediates = null;
|
||
|
|
||
|
private static Class mRunnableClass;
|
||
|
private static Class mJUnitClass;
|
||
|
|
||
|
static {
|
||
|
try {
|
||
|
mRunnableClass = Class.forName("java.lang.Runnable", false, null);
|
||
|
mJUnitClass = Class.forName("junit.framework.TestCase", false, null);
|
||
|
} catch (ClassNotFoundException ex) {
|
||
|
throw new RuntimeException("shouldn't happen", ex);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public class JunitTestSuite extends TestSuite implements TestListener {
|
||
|
boolean mError = false;
|
||
|
|
||
|
public JunitTestSuite() {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
public void run(TestResult result) {
|
||
|
result.addListener(this);
|
||
|
super.run(result);
|
||
|
result.removeListener(this);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Implemented method of the interface TestListener which will listen for the
|
||
|
* start of a test.
|
||
|
*
|
||
|
* @param test
|
||
|
*/
|
||
|
public void startTest(Test test) {
|
||
|
started(test.toString());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Implemented method of the interface TestListener which will listen for the
|
||
|
* end of the test.
|
||
|
*
|
||
|
* @param test
|
||
|
*/
|
||
|
public void endTest(Test test) {
|
||
|
finished(test.toString());
|
||
|
if (!mError) {
|
||
|
passed(test.toString());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Implemented method of the interface TestListener which will listen for an
|
||
|
* mError while running the test.
|
||
|
*
|
||
|
* @param test
|
||
|
*/
|
||
|
public void addError(Test test, Throwable t) {
|
||
|
mError = true;
|
||
|
failed(test.toString(), t);
|
||
|
}
|
||
|
|
||
|
public void addFailure(Test test, junit.framework.AssertionFailedError t) {
|
||
|
mError = true;
|
||
|
failed(test.toString(), t);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Listener.performance() 'intermediates' argument is a list of these.
|
||
|
*/
|
||
|
public static class IntermediateTime {
|
||
|
public IntermediateTime(String name, long timeInNS) {
|
||
|
this.name = name;
|
||
|
this.timeInNS = timeInNS;
|
||
|
}
|
||
|
|
||
|
public String name;
|
||
|
public long timeInNS;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Support class that receives status on test progress. You should not need to
|
||
|
* extend this interface yourself.
|
||
|
*/
|
||
|
public interface Listener {
|
||
|
void started(String className);
|
||
|
void finished(String className);
|
||
|
void performance(String className,
|
||
|
long itemTimeNS, int iterations,
|
||
|
List<IntermediateTime> itermediates);
|
||
|
void passed(String className);
|
||
|
void failed(String className, Throwable execption);
|
||
|
}
|
||
|
|
||
|
public TestRunner(Context context) {
|
||
|
mContext = context;
|
||
|
}
|
||
|
|
||
|
public void addListener(Listener listener) {
|
||
|
mListeners.add(listener);
|
||
|
}
|
||
|
|
||
|
public void startProfiling() {
|
||
|
File file = new File("/tmp/trace");
|
||
|
file.mkdir();
|
||
|
String base = "/tmp/trace/" + mClassName + ".dmtrace";
|
||
|
Debug.startMethodTracing(base, 8 * 1024 * 1024);
|
||
|
}
|
||
|
|
||
|
public void finishProfiling() {
|
||
|
Debug.stopMethodTracing();
|
||
|
}
|
||
|
|
||
|
private void started(String className) {
|
||
|
|
||
|
int count = mListeners.size();
|
||
|
for (int i = 0; i < count; i++) {
|
||
|
mListeners.get(i).started(className);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void finished(String className) {
|
||
|
int count = mListeners.size();
|
||
|
for (int i = 0; i < count; i++) {
|
||
|
mListeners.get(i).finished(className);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void performance(String className,
|
||
|
long itemTimeNS,
|
||
|
int iterations,
|
||
|
List<IntermediateTime> intermediates) {
|
||
|
int count = mListeners.size();
|
||
|
for (int i = 0; i < count; i++) {
|
||
|
mListeners.get(i).performance(className,
|
||
|
itemTimeNS,
|
||
|
iterations,
|
||
|
intermediates);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void passed(String className) {
|
||
|
mPassed++;
|
||
|
int count = mListeners.size();
|
||
|
for (int i = 0; i < count; i++) {
|
||
|
mListeners.get(i).passed(className);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void failed(String className, Throwable exception) {
|
||
|
mFailed++;
|
||
|
int count = mListeners.size();
|
||
|
for (int i = 0; i < count; i++) {
|
||
|
mListeners.get(i).failed(className, exception);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public int passedCount() {
|
||
|
return mPassed;
|
||
|
}
|
||
|
|
||
|
public int failedCount() {
|
||
|
return mFailed;
|
||
|
}
|
||
|
|
||
|
public void run(String[] classes) {
|
||
|
for (String cl : classes) {
|
||
|
run(cl);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void setInternalIterations(int count) {
|
||
|
mInternalIterations = count;
|
||
|
}
|
||
|
|
||
|
public void startTiming(boolean realTime) {
|
||
|
if (realTime) {
|
||
|
mStartTime = System.currentTimeMillis();
|
||
|
} else {
|
||
|
mStartTime = SystemClock.currentThreadTimeMillis();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void addIntermediate(String name) {
|
||
|
addIntermediate(name, (System.currentTimeMillis() - mStartTime) * 1000000);
|
||
|
}
|
||
|
|
||
|
public void addIntermediate(String name, long timeInNS) {
|
||
|
mIntermediates.add(new IntermediateTime(name, timeInNS));
|
||
|
}
|
||
|
|
||
|
public void finishTiming(boolean realTime) {
|
||
|
if (realTime) {
|
||
|
mEndTime = System.currentTimeMillis();
|
||
|
} else {
|
||
|
mEndTime = SystemClock.currentThreadTimeMillis();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void setPerformanceMode(int mode) {
|
||
|
mMode = mode;
|
||
|
}
|
||
|
|
||
|
private void missingTest(String className, Throwable e) {
|
||
|
started(className);
|
||
|
finished(className);
|
||
|
failed(className, e);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
This class determines if more suites are added to this class then adds all individual
|
||
|
test classes to a test suite for run
|
||
|
*/
|
||
|
public void run(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 void runInPerformanceMode(Object testCase, String className, boolean junitTest,
|
||
|
String testNameInDb) throws Exception {
|
||
|
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 void runSingleJunitTest(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 static Method getChildrenMethod(Class clazz) {
|
||
|
try {
|
||
|
return clazz.getMethod("children", (Class[]) null);
|
||
|
} catch (NoSuchMethodException e) {
|
||
|
}
|
||
|
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
public static Method getChildrenMethod(Context c, String className) {
|
||
|
try {
|
||
|
return getChildrenMethod(c.getClassLoader().loadClass(className));
|
||
|
} catch (ClassNotFoundException e) {
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
public static String[] getChildren(Context c, 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 String[] getChildren(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 String[] getTestChildren(Context c, 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 String[] getTestChildren(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 Method[] getAllTestMethods(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;
|
||
|
}
|
||
|
|
||
|
private static boolean isTestMethod(Method m) {
|
||
|
return m.getName().startsWith("test") &&
|
||
|
m.getReturnType() == void.class &&
|
||
|
m.getParameterTypes().length == 0;
|
||
|
}
|
||
|
|
||
|
public static int countJunitTests(Class clazz) {
|
||
|
Method[] allTestMethods = getAllTestMethods(clazz);
|
||
|
int numberofMethods = allTestMethods.length;
|
||
|
|
||
|
return numberofMethods;
|
||
|
}
|
||
|
|
||
|
public static boolean isTestSuite(Context c, 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;
|
||
|
}
|
||
|
|
||
|
|
||
|
public boolean isJunitTest(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;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the number of tests that will be run if you try to do this.
|
||
|
*/
|
||
|
public static int countTests(Context c, String className) {
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns a title to display given the className of a test.
|
||
|
* <p/>
|
||
|
* <p>Currently this function just returns the portion of the
|
||
|
* class name after the last '.'
|
||
|
*/
|
||
|
public static String getTitle(String className) {
|
||
|
int indexDot = className.lastIndexOf('.');
|
||
|
int indexDollar = className.lastIndexOf('$');
|
||
|
int index = indexDot > indexDollar ? indexDot : indexDollar;
|
||
|
if (index >= 0) {
|
||
|
className = className.substring(index + 1);
|
||
|
}
|
||
|
return className;
|
||
|
}
|
||
|
}
|