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