Android UiAutomator2.0

一、环境搭建

  JDK(java环境)、SDK(adb appt环境),这两个已经不想再叙述了直接看详见-->

  android studio 安装,下载地址:https://developer.android.google.cn/studio/index.html

安装完成,打开后大概是这个样子的:

二、新建测试工程

1.开始新建一个工程:点击上图的“Start a new Android Studio project ”

2.进入创建工程界面,设置app的名称、包名,及工程路径,点击 “Next”

3.选择平台类型及sdk的最小版本,点击 “Next”

4.选择Empty Activity,点击“Next”;选择No Activity,点击“Finish”  

5.工程创建完成。(默认是Android目录模式,且有一个默认的Module【app】)

三、编写脚本

在编写脚本前说明几点:(实例并非以上新建的工程目录,但并不影响此教程)

  a:脚本实例中将测试脚本写在main中,以便后续build apk后,能在CTS框架中运行。

  b:需先配置AndroidManifest.xml文件、build.gradle(Module:app)文件、以及settings.gradle文件。

1.settings文件内容

2.AndroidManifest.xml文件中添加Instrumentation标签

3.build.gradle(Module:app)文件中添加测试依赖的包。文件代码如下:

apply plugin: ‘com.android.application‘

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.1"
    defaultConfig {
        applicationId "com.zzw.testdemo"
        minSdkVersion 24
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile(‘proguard-android.txt‘), ‘proguard-rules.pro‘
        }
    }
}

dependencies {
    compile fileTree(dir: ‘libs‘, include: [‘*.jar‘])
    androidTestCompile(‘com.android.support.test.espresso:espresso-core:2.2.2‘, {
        exclude group: ‘com.android.support‘, module: ‘support-annotations‘
    })
    compile ‘com.android.support:appcompat-v7:26.+‘
    testCompile ‘junit:junit:4.12‘

    compile ‘com.android.support.test:runner:0.5‘
    // Set this dependency to use JUnit 4 rules
    compile ‘com.android.support.test:rules:0.5‘
    // Set this dependency to build and run Espresso tests
    compile ‘com.android.support.test.espresso:espresso-core:2.2.2‘
    // Set this dependency to build and run UI Automator tests
    compile ‘com.android.support.test.uiautomator:uiautomator-v18:2.1.2‘
    // Add uiTestHelper
    compile project(‘:uiTestHelper‘)

}

 4.接下来就是代码的编写了,这里贴出一个例子

package com.zzw.testdemo;

import android.graphics.Rect;
import android.os.Environment;
import android.os.SystemClock;
import android.support.test.InstrumentationRegistry;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiScrollable;
import android.support.test.uiautomator.UiSelector;

import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.util.Locale;

/**
 * Created by zhangying on 2017/12/19.
 */

public class TestPermission2 {
    private UiDevice mDevice;
    private static long LONG_TIMEOUT = 5000;
    private static long SHORT_TIMEOUT = 3000;
    private static String TEST_PACKAGE_NAME ="com.android.settings";
    private static String TEST_MAIN_ACTIVITY="com.android.settings/.Settings";

    @Before
    public void setUp() throws IOException {
        mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
        mDevice.executeShellCommand("pm clear "+TEST_PACKAGE_NAME);
    }

    @After
    public void tearDown(){
        mDevice.pressHome();
    }

    /**
     * Case : 打开设置->点击语言&输入法->点击语言->切换语言(en || cn)
     *
     */
    @Test
    public void test01_a()throws Throwable {
        try {
            // Launch settings application
            mDevice.executeShellCommand("am start -n " + TEST_MAIN_ACTIVITY);
            // Sleep 5s
            SystemClock.sleep(LONG_TIMEOUT);
            // Setting list interface
            UiScrollable settingList = new UiScrollable(new UiSelector().resourceId("com.android.settings:id/dashboard_container"));
            // Sliding lookup "Languages & input" or "语言和输入法"
            UiObject languageInput = mDevice.findObject(new UiSelector().textMatches("Languages & input|语言和输入法"));
            settingList.scrollIntoView(languageInput);

            //UiObject languageInput = settingList.getChildByText(new UiSelector().textMatches("Languages & input|语言和输入法")
            //  ,Locale.getDefault().getLanguage().equals("en")?"Languages & input":"语言和输入法");

            // Click "Languages & input" or "语言和输入法"
            languageInput.clickAndWaitForNewWindow();
            // Click "Languages" or "语言"
            mDevice.findObject(new UiSelector().textMatches("Languages|语言")).clickAndWaitForNewWindow();
            // Add language control
            UiObject addLanguage = mDevice.findObject(new UiSelector().resourceId("com.android.settings:id/add_language"));
            // Language list interface control
            UiObject dragList = mDevice.findObject(new UiSelector().resourceId("com.android.settings:id/dragList"));
            // The first language displayed rect
            Rect rect = dragList.getChild(new UiSelector().className("android.widget.RelativeLayout").index(0)).getBounds();
            // Language cn control
            UiObject cn = dragList.getChild(new UiSelector().textMatches(".*中文(中国)"));
            // Language en control
            UiObject en = dragList.getChild(new UiSelector().text("English (United States)"));
            // Add language list interface control
            UiScrollable findList = new UiScrollable(new UiSelector().className("android.widget.ListView"));
            // If language cn and en exists in the language list interface
            if (cn.exists() && en.exists()) {
                UiObject first = dragList.getChild(new UiSelector().className("android.widget.RelativeLayout").index(0))
                        .getChild(new UiSelector().className("android.widget.TextView"));

                if (first.getText().equals("English (United States)")) {
                    // if the first language displayed "English (United States)" , Switch to cn
                    cn.dragTo(rect.centerX(), rect.top, 500);
                } else if (first.getText().matches(".*中文(中国)")) {
                    // if it displayed ".*中文(中国)" ,  Switch to en
                    en.dragTo(rect.centerX(), rect.top, 500);
                } else {
                    // else none of them , Switch to en
                    en.dragTo(rect.centerX(), rect.top, 500);
                }
            } else if (cn.exists() && !en.exists()) {
                // if cn exists and en not exists , add en and switch to en
                addLanguage.clickAndWaitForNewWindow();
                findList.getChildByText(new UiSelector().text("English"), "English").clickAndWaitForNewWindow();
                findList.getChildByText(new UiSelector().text("United States"), "United States").clickAndWaitForNewWindow();
                SystemClock.sleep(SHORT_TIMEOUT);
                en.dragTo(rect.centerX(), rect.top, 500);
            } else if (en.exists() && !cn.exists()) {
                // if en exists and cn not exists , add cn and switch to cn
                addLanguage.clickAndWaitForNewWindow();
                UiObject chinese = mDevice.findObject(new UiSelector().textMatches(".*中文"));
                findList.scrollIntoView(chinese);
                chinese.clickAndWaitForNewWindow();
                UiObject china = mDevice.findObject(new UiSelector().text("中国"));
                if (china.exists()) {
                    china.clickAndWaitForNewWindow();
                }
                SystemClock.sleep(SHORT_TIMEOUT);
                cn.dragTo(rect.centerX(), rect.top, 500);
            } else {
                // else none of them , add en and switch to en
                addLanguage.clickAndWaitForNewWindow();
                findList.getChildByText(new UiSelector().text("English"), "English").clickAndWaitForNewWindow();
                findList.getChildByText(new UiSelector().text("United States"), "United States").clickAndWaitForNewWindow();
                SystemClock.sleep(LONG_TIMEOUT);
                en.dragTo(rect.centerX(), rect.top, 500);
            }
            SystemClock.sleep(LONG_TIMEOUT);
        }catch (Throwable e){
            // if error exist ,print stack trace log and screenshot to sdcard/test01_a.png
            e.printStackTrace();
            mDevice.takeScreenshot(new File(Environment.getExternalStorageDirectory(),this.getClass().getName()+".png"));
        }finally {
            mDevice.pressBack();
            mDevice.pressBack();
            mDevice.pressBack();
        }
    }

    @Test
    public void test02_a() {

    }

    @Ignore
    public void test03_a() {

    }
}

四、运行测试

1.首先来看下在哪里运行测试,及怎么运行测试。步骤见图解

2.编辑运行测试的配置

3.运行测试

实际上测试执行是这样的:(a~d:安装主程序和测试程序; e:执行测试)

a. adb push E:\Androids\AndroidStudioProjects\TestDemo\calculator\build\outputs\apk\calculator-debug.apk /data/local/tmp/com.zzw.testdemo
b. adb shell pm install -r "/data/local/tmp/com.zzw.testdemo"
c. adb push E:\Androids\AndroidStudioProjects\TestDemo\calculator\build\outputs\apk\calculator-debug-androidTest.apk /data/local/tmp/com.zzw.testdemo.test
d. adb shell pm install -r "/data/local/tmp/com.zzw.testdemo.test"
e. adb shell am instrument -w -r -e debug false -e class com.zzw.testdemo.TestPermission2#test01_a com.zzw.testdemo.test/android.support.test.runner.AndroidJUnitRunner

五、生成报告

六、使用CTS框架运行测试脚本

  要使用CTS测试框架进行测试生成报告:需要将测试脚本写在main中(编写脚本处也提到过),然后将生成的主程序 app-debug.apk放置CTS的testcase目录下,配置完成后即可运行测试。详见 《Android UiAutomator - CTS Frame》cts 7.0以上部分=>>>>

原文地址:https://www.cnblogs.com/zeo-to-one/p/8245732.html

时间: 2024-08-30 18:31:52

Android UiAutomator2.0的相关文章

UiAutomator2.0升级填坑记

UiAutomator2.0升级填坑记 SkySeraph May. 28th 2017 Email:[email protected] 更多精彩请直接访问SkySeraph个人站点:www.skyseraph.com 啰嗦 Google Android Developers 在2015年3月就发布了UiAutomator 2.0版本(下文简称U2),而公司的核心产品中用到还是UiAutomator老版本(下文简称U1),业界用U2的也不是很多,虽然有诸多问题和不便(如高版本OS中不支持Remo

uiautomator2.0框架

1.   Uiautomator1.0 Uiautomator2.0 date 2012 2015 super class UiAutomatorTestCase InstrumentationTestCase language java java executable file jar APK API-level 16(4.1)+ 18(4.3)+ permission - less context no yes extends Junit3 需要继承UiAutomatorTestCase J

UiAutomator2.0 - Toast信息的验证

目录 问题:在做UI自动化测试时,偶尔会碰到 Toast 这种提示信息(如图),通过Uiautomatorviewer 无法获该类控件的信息.所以无法验证,该条case不能实现.然后就没然后了... 思考:在<UiAutomator2.0 - 与AccessibilityService的关联>实验后,发现Toast提示信息所属事件为 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHAN

UiAutomator2.0 - 与AccessibilityService的关联

目录 一.Android中的 Accessibility 二.UiAutomator2.0 与 AccessibilityService 三.验证与 AccessibilityService的关联 Accessibility:无障碍,又称辅助性功能. AccessibilityService:无障碍服务,继承于 Serveice. 它可以监听操作.检索窗口内容.启用触摸浏览等 一.Android中的 Accessibility 在原生android设备中 Settings 应用程序菜单中有一项

初探UiAutomator2.0中使用Xpath定位元素

J 今天的主题是讲一下在使用过程中遇到的一个问题,如何在UiAutomator2.0中使用Xpath定位元素? 背景 现在的app在打包成apk的时候都是有加固处理的,各种混淆加固,所以已经破坏了或扰乱了原本的代码变量命名形式,这就给我们要基于界面来做自动化测试带来了灾难性的阻碍,因为那些混淆过的id是不固定的,下一次再出个新版本,这一切都变了,所以这就没办法用id来定位混淆过的app元素,那还有什么好的方法吗?还记得Web自动化测试中神乎其技的xpath吗?不管什么元素都可以用它定位出来,所以

Android 6.0 运行时权限处理完全解析

一.概述 随着Android 6.0发布以及普及,我们开发者所要应对的主要就是新版本SDK带来的一些变化,首先关注的就是权限机制的变化.对于6.0的几个主要的变化,查看查看官网的这篇文章http://developer.android.com/intl/zh-cn/about/versions/marshmallow/android-6.0-changes.html,其中当然包含Runtime Permissions. ok,本篇文章目的之一就是对运行时权限处理的一个介绍,以及对目前权限相关的库

android 6.0 系统获取权限

在Android 6.0 (API 23) 发布之前, 所有的权限都在安装应用的时候显示给用户,用户选择安装则表示全部接受这些权限, 之后无法撤销对这些权限的授权.但Android 6.0开始, 一部分比较危险的权限需要在程序运行时显式弹框,请求用户授权.所以,之前开发应用时,在manifest文件中配置对应的权限这种做法便达不到之前的效果.那么,现在要怎么做呢?提供两种思路,仅供参考: 1:判断android系统的版本,如果不是6.0及以上,按正常逻辑处理,如果是,则去打开系统弹框,请求系统权

Android 5.0特性

虽然此前Google对其已经做过了比较深入的介绍,但作为一个如此重要的升级版本,更新内容自然是海量的. Google今天很贴心地在官网上放出了Android 5.0正式版的完整更新日志,涵盖了升级的方方面面,不过说实话也只是一些重要的.大面上的概略更新介绍,还有更多细节等待挖掘. 1.Material Design 醒目的.多彩的.快速响应的UI设计,可为你所有的设备带来一致的直觉体验. - 响应快速.自然流畅的动作,真实的光照和阴影,熟悉的视觉元素,设备导航更加轻而易举. - 惊艳的新色彩,凸

解决Android 5.0中出现的警告:Service Intent must be explicit

extends:http://www.eoeandroid.com/thread-568853-1-1.html 本帖最后由 469874851 于 2015-3-11 18:15 编辑 有些时候我们使用Service的时需要采用隐私启动的方式,但是Android 5.0一出来后,其中有个特性就是Service Intent  must be explitict,也就是说从Lollipop开始,service服务必须采用显示方式启动.而android源码是这样写的(源码位置:sdk/source