android自动化测试Uiautomator源码分析之三

本文介绍如何通过构建测试用例来进行UI自动化测试,包括测试类和方法的选择标准、测试用例的实例化流程及测试执行前的各项准备工作。

4 测试准备

4.1,建立测试用例TestCase

start方法建立测试用例代码如下

TestCaseCollector collector = getTestCaseCollector(this.getClass().getClassLoader());
        try {
            collector.addTestClasses(mTestClasses);
        } catch (ClassNotFoundException e) {
            // will be caught by uncaught handler
            throw new RuntimeException(e.getMessage(), e);
        }
        if (mDebug) {
            Debug.waitForDebugger();
        }

getTestCaseCollector方法如下

protected TestCaseCollector getTestCaseCollector(ClassLoader classLoader) {
        return new TestCaseCollector(classLoader, getTestCaseFilter());
    }

getTestCaseFilter方法如下,

public UiAutomatorTestCaseFilter getTestCaseFilter() {
        return new UiAutomatorTestCaseFilter();
    }

实际上,首先new一个UiAutomatorTestCaseFilter对象,然后利用该UiAutomatorTestCaseFilter对象new一个TestCaseCollector对象。

最后调用TestCaseCollector的addTestClasses方法添加测试用例, addTestClass方法如下,

public void addTestClass(String className) throws ClassNotFoundException {
        int hashPos = className.indexOf('#');
        String methodName = null;
        if (hashPos != -1) {
            methodName = className.substring(hashPos + 1);
            className = className.substring(0, hashPos);
        }
        addTestClass(className, methodName);
    }

如果是测试类的其中一个测试方法,中间用#号隔开

输入指令如下       className# methodName

如果输入的是整个测试类,则会测试每一个方法。

addTestClass方法如下,

public void addTestClass(String className, String methodName) throws ClassNotFoundException {
        Class<?> clazz = mClassLoader.loadClass(className);
        if (methodName != null) {
            addSingleTestMethod(clazz, methodName);
        } else {
            Method[] methods = clazz.getMethods();
            for (Method method : methods) {
                if (mFilter.accept(method)) {
                    addSingleTestMethod(clazz, method.getName());
                }
            }
        }
    }

如果输入了测试方法,则直接调用addSingleTestMethod方法添加。

如果仅仅输入了测试类,则首先获取该类的所有方法,然后调用UiAutomatorTestCaseFilter的accept方法来过滤测试方法。

如果是测试方法,就调用addSingleTestMethod方法添加。

UiAutomatorTestCaseFilter的accept方法如下,

@Override
    public boolean accept(Method method) {
        return ((method.getParameterTypes().length == 0) &&
                (method.getName().startsWith("test")) &&
                (method.getReturnType().getSimpleName().equals("void")));
    }

符合以下三个条件的方法属于测试方法:

1,无输入参数

2,以字符串”test”开头

3,返回值为空

所以实际上,一个测试方法对应一个测试用例。

addSingleTestMethod方法如下,

protected void addSingleTestMethod(Class<?> clazz, String method) {
        if (!(mFilter.accept(clazz))) {
            throw new RuntimeException("Test class must be derived from UiAutomatorTestCase");
        }
        try {
            TestCase testCase = (TestCase) clazz.newInstance();
            testCase.setName(method);
            mTestCases.add(testCase);
        } catch (InstantiationException e) {
            mTestCases.add(error(clazz, "InstantiationException: could not instantiate " +
                    "test class. Class: " + clazz.getName()));
        } catch (IllegalAccessException e) {
            mTestCases.add(error(clazz, "IllegalAccessException: could not instantiate " +
                    "test class. Class: " + clazz.getName()));
        }
    }

首先调用UiAutomatorTestCaseFilter的accept方法判断该类是不是一个测试类,

方法如下,

public boolean accept(Class<?> clazz) {
        return UiAutomatorTestCase.class.isAssignableFrom(clazz);
    }

如果该类是UiAutomatorTestCase类或者UiAutomatorTestCase的子类,则返回true,说明是一个测试类,否则不是测试类。

利用测试方法创建一个TestCase对象,该类是一个抽象类并且仅有一个变量

private String fName;

最后将该对象添加到mTestCases列表中。mTestCases列表定义如下,

private List<TestCase> mTestCases;

因此,一个测试方法对应一个测试用例,对应一个TestCase对象。都存放在mTestCases列表中。

实际上, TestCase是一个抽象类,创建的是其子类的对象。例如 UiAutomatorTestCase对象。

4.2 准备工作

1,创建UiAutomationShellWrapper对象,连接并且设置monkey模式(true/false)

UiAutomationShellWrapper automationWrapper = new UiAutomationShellWrapper();
        automationWrapper.connect();

automationWrapper.setRunAsMonkey(mMonkey); 

2,UiDevice对象的初始化

mUiDevice = UiDevice.getInstance();
mUiDevice.initialize(new ShellUiAutomatorBridge(automationWrapper.getUiAutomation()));

3,为测试报告类设置监听类

long startTime = SystemClock.uptimeMillis();
        TestResult testRunResult = new TestResult();
        ResultReporter resultPrinter;
        String outputFormat = mParams.getString("outputFormat");
        List<TestCase> testCases = collector.getTestCases();
        Bundle testRunOutput = new Bundle();
        if ("simple".equals(outputFormat)) {
            resultPrinter = new SimpleResultPrinter(System.out, true);
        } else {
            resultPrinter = new WatcherResultPrinter(testCases.size());
        }

testRunResult.addListener(resultPrinter);
            // add all custom listeners
            for (TestListener listener : mTestListeners) {
                testRunResult.addListener(listener);
            }

TestResult的构造方法如下,

public TestResult() {
		// BEGIN android-changed to Vector
		fFailures= new Vector<TestFailure>();
		fErrors= new Vector<TestFailure>();
		fListeners= new Vector<TestListener>();
		// END android-changed
		fRunTests= 0;
		fStop= false;
	}

三个vector,分别对应测试失败,测试错误,测试过程的监听。

addListener方法如下,

public synchronized void addListener(TestListener listener) {
		fListeners.add(listener);
	}

该TestListener对象是WatcherResultPrinter对象。将WatcherResultPrinter对象添加到fListeners中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值