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 */ 16 17package com.android.uiautomator.testrunner; 18 19import junit.framework.AssertionFailedError; 20import junit.framework.Test; 21import junit.framework.TestCase; 22import junit.framework.TestResult; 23 24import java.lang.reflect.Method; 25import java.util.ArrayList; 26import java.util.Collections; 27import java.util.List; 28 29/** 30 * A convenient class that encapsulates functions for adding test classes 31 * 32 * @hide 33 */ 34public class TestCaseCollector { 35 36 private ClassLoader mClassLoader; 37 private List<TestCase> mTestCases; 38 private TestCaseFilter mFilter; 39 40 public TestCaseCollector(ClassLoader classLoader, TestCaseFilter filter) { 41 mClassLoader = classLoader; 42 mTestCases = new ArrayList<TestCase>(); 43 mFilter = filter; 44 } 45 46 /** 47 * Adds classes to test by providing a list of class names in string 48 * 49 * The class name may be in "<class name>#<method name>" format 50 * 51 * @param classNames class must be subclass of {@link UiAutomatorTestCase} 52 * @throws ClassNotFoundException 53 */ 54 public void addTestClasses(List<String> classNames) throws ClassNotFoundException { 55 for (String className : classNames) { 56 addTestClass(className); 57 } 58 } 59 60 /** 61 * Adds class to test by providing class name in string. 62 * 63 * The class name may be in "<class name>#<method name>" format 64 * 65 * @param className classes must be subclass of {@link UiAutomatorTestCase} 66 * @throws ClassNotFoundException 67 */ 68 public void addTestClass(String className) throws ClassNotFoundException { 69 int hashPos = className.indexOf('#'); 70 String methodName = null; 71 if (hashPos != -1) { 72 methodName = className.substring(hashPos + 1); 73 className = className.substring(0, hashPos); 74 } 75 addTestClass(className, methodName); 76 } 77 78 /** 79 * Adds class to test by providing class name and method name in separate strings 80 * 81 * @param className class must be subclass of {@link UiAutomatorTestCase} 82 * @param methodName may be null, in which case all "public void testNNN(void)" functions 83 * will be added 84 * @throws ClassNotFoundException 85 */ 86 public void addTestClass(String className, String methodName) throws ClassNotFoundException { 87 Class<?> clazz = mClassLoader.loadClass(className); 88 if (methodName != null) { 89 addSingleTestMethod(clazz, methodName); 90 } else { 91 Method[] methods = clazz.getMethods(); 92 for (Method method : methods) { 93 if (mFilter.accept(method)) { 94 addSingleTestMethod(clazz, method.getName()); 95 } 96 } 97 } 98 } 99 100 /** 101 * Gets the list of added test cases so far 102 * @return a list of {@link TestCase} 103 */ 104 public List<TestCase> getTestCases() { 105 return Collections.unmodifiableList(mTestCases); 106 } 107 108 protected void addSingleTestMethod(Class<?> clazz, String method) { 109 if (!(mFilter.accept(clazz))) { 110 throw new RuntimeException("Test class must be derived from UiAutomatorTestCase"); 111 } 112 try { 113 TestCase testCase = (TestCase) clazz.newInstance(); 114 testCase.setName(method); 115 mTestCases.add(testCase); 116 } catch (InstantiationException e) { 117 mTestCases.add(error(clazz, "InstantiationException: could not instantiate " + 118 "test class. Class: " + clazz.getName())); 119 } catch (IllegalAccessException e) { 120 mTestCases.add(error(clazz, "IllegalAccessException: could not instantiate " + 121 "test class. Class: " + clazz.getName())); 122 } 123 } 124 125 private UiAutomatorTestCase error(Class<?> clazz, final String message) { 126 UiAutomatorTestCase warning = new UiAutomatorTestCase() { 127 protected void runTest() { 128 fail(message); 129 } 130 }; 131 132 warning.setName(clazz.getName()); 133 return warning; 134 } 135 136 /** 137 * Determine if a class and its method should be accepted into test suite 138 * 139 */ 140 public interface TestCaseFilter { 141 142 /** 143 * Determine that based on the method signature, if it can be accepted 144 * @param method 145 */ 146 public boolean accept(Method method); 147 148 /** 149 * Determine that based on the class type, if it can be accepted 150 * @param clazz 151 * @return 152 */ 153 public boolean accept(Class<?> clazz); 154 } 155} 156