1e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu/* 2e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Copyright (C) 2012 The Android Open Source Project 3e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * 4e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Licensed under the Apache License, Version 2.0 (the "License"); 5e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * you may not use this file except in compliance with the License. 6e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * You may obtain a copy of the License at 7e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * 8e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * http://www.apache.org/licenses/LICENSE-2.0 9e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * 10e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Unless required by applicable law or agreed to in writing, software 11e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * distributed under the License is distributed on an "AS IS" BASIS, 12e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * See the License for the specific language governing permissions and 14e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * limitations under the License. 15e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 16e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 17e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhupackage com.android.uiautomator.testrunner; 18e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 19e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport junit.framework.TestCase; 20e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 21e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport java.lang.reflect.Method; 22e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport java.util.ArrayList; 23e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport java.util.Collections; 24e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport java.util.List; 25e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 26e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu/** 27e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * A convenient class that encapsulates functions for adding test classes 28e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * 29ddc1008f06fd2a875037026490ce1f848a442572Guang Zhu * @hide 30e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 31e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhupublic class TestCaseCollector { 32e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 33e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private ClassLoader mClassLoader; 34e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private List<TestCase> mTestCases; 35e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private TestCaseFilter mFilter; 36e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 37e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public TestCaseCollector(ClassLoader classLoader, TestCaseFilter filter) { 38e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mClassLoader = classLoader; 39e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestCases = new ArrayList<TestCase>(); 40e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mFilter = filter; 41e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 42e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 43e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu /** 44e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Adds classes to test by providing a list of class names in string 45e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * 46e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * The class name may be in "<class name>#<method name>" format 47e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * 48e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * @param classNames class must be subclass of {@link UiAutomatorTestCase} 49e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * @throws ClassNotFoundException 50e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 51e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public void addTestClasses(List<String> classNames) throws ClassNotFoundException { 52e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu for (String className : classNames) { 53e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu addTestClass(className); 54e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 55e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 56e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 57e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu /** 58e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Adds class to test by providing class name in string. 59e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * 60e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * The class name may be in "<class name>#<method name>" format 61e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * 62e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * @param classNames classes must be subclass of {@link UiAutomatorTestCase} 63e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * @throws ClassNotFoundException 64e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 65e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public void addTestClass(String className) throws ClassNotFoundException { 66e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu int hashPos = className.indexOf('#'); 67e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu String methodName = null; 68e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (hashPos != -1) { 69e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu methodName = className.substring(hashPos + 1); 70e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu className = className.substring(0, hashPos); 71e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 72e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu addTestClass(className, methodName); 73e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 74e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 75e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu /** 76e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Adds class to test by providing class name and method name in separate strings 77e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * 78e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * @param className class must be subclass of {@link UiAutomatorTestCase} 79e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * @param methodName may be null, in which case all "public void testNNN(void)" functions 80e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * will be added 81e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * @throws ClassNotFoundException 82e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 83e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public void addTestClass(String className, String methodName) throws ClassNotFoundException { 84e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu Class<?> clazz = mClassLoader.loadClass(className); 85e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (methodName != null) { 86e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu addSingleTestMethod(clazz, methodName); 87e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } else { 88e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu Method[] methods = clazz.getMethods(); 89e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu for (Method method : methods) { 90e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (mFilter.accept(method)) { 91e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu addSingleTestMethod(clazz, method.getName()); 92e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 93e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 94e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 95e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 96e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 97e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu /** 98e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Gets the list of added test cases so far 99e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * 100e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * @return 101e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 102e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public List<TestCase> getTestCases() { 103e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return Collections.unmodifiableList(mTestCases); 104e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 105e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 106e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu protected void addSingleTestMethod(Class<?> clazz, String method) { 107e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (!(mFilter.accept(clazz))) { 108e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu throw new RuntimeException("Test class must be derived from UiAutomatorTestCase"); 109e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 110e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu try { 111e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu TestCase testCase = (TestCase) clazz.newInstance(); 112e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu testCase.setName(method); 113e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestCases.add(testCase); 114e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } catch (InstantiationException e) { 115e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu throw new RuntimeException("Could not instantiate test class. Class: " 116e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu + clazz.getName()); 117e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } catch (IllegalAccessException e) { 118e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu throw new RuntimeException("Could not access test class. Class: " + clazz.getName()); 119e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 120e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 121e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 122e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 123e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu /** 124e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Determine if a class and its method should be accepted into test suite 125e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * 126e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 127e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public interface TestCaseFilter { 128e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 129e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu /** 130e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Determine that based on the method signature, if it can be accepted 131e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * @param method 132e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 133e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public boolean accept(Method method); 134e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 135e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu /** 136e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Determine that based on the class type, if it can be accepted 137e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * @param clazz 138e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * @return 139e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 140e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public boolean accept(Class<?> clazz); 141e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 142e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu} 143