| /* |
| * Copyright (C) 2012 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 com.android.test.runner; |
| |
| import android.util.Log; |
| |
| import org.junit.runner.Description; |
| import org.junit.runner.notification.Failure; |
| |
| import java.io.PrintStream; |
| import java.lang.reflect.Method; |
| import java.util.LinkedList; |
| import java.util.List; |
| |
| /** |
| * A class for loading JUnit3 and JUnit4 test classes given a set of potential class names. |
| */ |
| public class TestLoader { |
| |
| private static final String LOG_TAG = "TestLoader"; |
| |
| private List<Class<?>> mLoadedClasses = new LinkedList<Class<?>>(); |
| private List<Failure> mLoadFailures = new LinkedList<Failure>(); |
| |
| private PrintStream mWriter; |
| |
| /** |
| * Create a {@link TestLoader}. |
| * |
| * @param writer a {@link PrintStream} used for reporting errors. |
| */ |
| public TestLoader(PrintStream writer) { |
| mWriter = writer; |
| } |
| |
| /** |
| * Loads the test class from the given class name. |
| * <p/> |
| * Will store the result internally. Successfully loaded classes can be retrieved via |
| * {@link #getLoadedClasses()}, failures via {@link #getLoadFailures()}. |
| * |
| * @param className the class name to attempt to load |
| * @return the loaded class or null. |
| */ |
| public Class<?> loadClass(String className) { |
| Class<?> loadedClass = doLoadClass(className); |
| if (loadedClass != null) { |
| mLoadedClasses.add(loadedClass); |
| } |
| return loadedClass; |
| } |
| |
| private Class<?> doLoadClass(String className) { |
| try { |
| return Class.forName(className); |
| } catch (ClassNotFoundException e) { |
| String errMsg = String.format("Could not find class: %s", className); |
| Log.e(LOG_TAG, errMsg); |
| mWriter.println(errMsg); |
| Description description = Description.createSuiteDescription(className); |
| Failure failure = new Failure(description, e); |
| mLoadFailures.add(failure); |
| } |
| return null; |
| } |
| |
| /** |
| * Loads the test class from the given class name. |
| * <p/> |
| * Similar to {@link #loadClass(String, PrintStream))}, but will ignore classes that are |
| * not tests. |
| * |
| * @param className the class name to attempt to load |
| * @return the loaded class or null. |
| */ |
| public Class<?> loadIfTest(String className) { |
| Class<?> loadedClass = doLoadClass(className); |
| if (loadedClass != null && isTestClass(loadedClass)) { |
| mLoadedClasses.add(loadedClass); |
| return loadedClass; |
| } |
| return null; |
| } |
| |
| /** |
| * @return whether this {@link TestLoader} contains any loaded classes or load failures. |
| */ |
| public boolean isEmpty() { |
| return mLoadedClasses.isEmpty() && mLoadFailures.isEmpty(); |
| } |
| |
| /** |
| * Get the {@link List) of classes successfully loaded via |
| * {@link #loadTest(String, PrintStream)} calls. |
| */ |
| public List<Class<?>> getLoadedClasses() { |
| return mLoadedClasses; |
| } |
| |
| /** |
| * Get the {@link List) of {@link Failure} that occurred during |
| * {@link #loadTest(String, PrintStream)} calls. |
| */ |
| public List<Failure> getLoadFailures() { |
| return mLoadFailures; |
| } |
| |
| /** |
| * Determines if given class is a valid test class. |
| * |
| * @param loadedClass |
| * @return <code>true</code> if loadedClass is a test |
| */ |
| private boolean isTestClass(Class<?> loadedClass) { |
| // TODO: try to find upstream junit calls to replace these checks |
| if (junit.framework.Test.class.isAssignableFrom(loadedClass)) { |
| return true; |
| } |
| // TODO: look for a 'suite' method? |
| if (loadedClass.isAnnotationPresent(org.junit.runner.RunWith.class)) { |
| return true; |
| } |
| for (Method testMethod : loadedClass.getMethods()) { |
| if (testMethod.isAnnotationPresent(org.junit.Test.class)) { |
| return true; |
| } |
| } |
| Log.v(LOG_TAG, String.format("Skipping class %s: not a test", loadedClass.getName())); |
| return false; |
| } |
| } |