TestRequestBuilder.java revision 53196f43b44ff02da07c243798168d7e5614ec34
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package com.android.test.runner; 17 18import android.app.Instrumentation; 19import android.util.Log; 20 21import com.android.test.runner.ClassPathScanner.ChainedClassNameFilter; 22import com.android.test.runner.ClassPathScanner.ExcludePackageNameFilter; 23import com.android.test.runner.ClassPathScanner.ExternalClassNameFilter; 24import com.android.test.runner.TestLoader.LoadResults; 25 26import org.junit.runner.Computer; 27import org.junit.runner.Request; 28import org.junit.runner.Runner; 29import org.junit.runner.manipulation.Filter; 30import org.junit.runners.model.InitializationError; 31 32import java.io.IOException; 33import java.io.PrintStream; 34import java.util.ArrayList; 35import java.util.Arrays; 36import java.util.Collection; 37import java.util.Collections; 38 39/** 40 * Builds a {@link Request} from test classes in given apk paths, filtered on provided set of 41 * restrictions. 42 */ 43public class TestRequestBuilder { 44 45 private static final String LOG_TAG = "TestRequestBuilder"; 46 47 private String[] mApkPaths; 48 private Collection<String> mTestClasses = new ArrayList<String>(); 49 @SuppressWarnings("unused") 50 private Filter mFilter = Filter.ALL; 51 52 public TestRequestBuilder(String... apkPaths) { 53 mApkPaths = apkPaths; 54 } 55 56 /** 57 * Add a test class to be executed 58 * @param className 59 * 60 * TODO: add method support 61 */ 62 public void addTestClass(String className) { 63 mTestClasses.add(className); 64 } 65 66 TestRequest build(PrintStream writer, Instrumentation instr) { 67 if (mTestClasses.isEmpty()) { 68 mTestClasses = getClassNames(writer); 69 } 70 TestLoader loader = new TestLoader(); 71 LoadResults loadedTests = loader.loadTests(mTestClasses, writer); 72 73 Request request = classes(instr, new Computer(), loadedTests.getLoadedClasses().toArray( 74 new Class[0])); 75 return new TestRequest(loadedTests.getLoadFailures(), request); 76 } 77 78 /** 79 * Create a <code>Request</code> that, when processed, will run all the tests 80 * in a set of classes. 81 * 82 * @param instr the {@link Instrumentation} to inject into any tests that require it 83 * @param computer Helps construct Runners from classes 84 * @param classes the classes containing the tests 85 * @return a <code>Request</code> that will cause all tests in the classes to be run 86 */ 87 public static Request classes(Instrumentation instr, Computer computer, Class<?>... classes) { 88 try { 89 AndroidRunnerBuilder builder = new AndroidRunnerBuilder(true, instr); 90 Runner suite = computer.getSuite(builder, classes); 91 return Request.runner(suite); 92 } catch (InitializationError e) { 93 throw new RuntimeException( 94 "Suite constructor, called as above, should always complete"); 95 } 96 } 97 98 private Collection<String> getClassNames(PrintStream writer) { 99 Log.i(LOG_TAG, String.format("Scanning classpath to find tests in apks %s", 100 Arrays.toString(mApkPaths))); 101 ClassPathScanner scanner = new ClassPathScanner(mApkPaths); 102 try { 103 // exclude inner classes, and classes from junit and this lib namespace 104 return scanner.getClassPathEntries(new ChainedClassNameFilter( 105 new ExcludePackageNameFilter("junit"), 106 new ExcludePackageNameFilter("org.junit"), 107 new ExcludePackageNameFilter("org.hamcrest"), 108 new ExternalClassNameFilter())); 109 } catch (IOException e) { 110 writer.println("failed to scan classes"); 111 Log.e(LOG_TAG, "Failed to scan classes", e); 112 } 113 return Collections.emptyList(); 114 } 115} 116