Home | History | Annotate | Download | only in testrunner
      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