移动端自动测试工具appium快速入门(代码片段)

zuozewei zuozewei     2023-01-09     392

关键词:

一、前言

今天简单介绍 移动端 UI 自动测试工具 Appium。

二、Appium 概述

Appium 是一个自动化测试开源工具,支持 iOS 平台和 Android 平台上的原生应用,web 应用和混合应用。“移动原生应用”是指那些用 iOS SDK 或者 Android SDK 写的应用。所谓的“移动web 应用”是指使用移动浏览器访问的应用(Appium 支持 iOS 上的 Safari 和 Android 上的 Chrome)。所谓的“混合应用”是指原生代码封装网页视图——原生代码和 web 内容交互。Appium 既能在 window 安装也能在 Mac 上安装,但是 window 上只能跑安卓设备,Mac 上能跑安卓与 IOS 两个设备。

Guihub:You can write tests with your favorite dev tools using any WebDriver-compatible language such as Java, Objective-C, JavaScript (Node), PHP, Python, Ruby, C#, Clojure, or Perl with the Selenium WebDriver API and language-specific client libraries.

源码地址:https://github.com/appium/appium

1、架构图

2、UI 自动化收益

任何 UI 自动化测试都不能完部替代人工测试,收益率高不高看部门怎么使用任何工具使用都是两方看怎么使用,如果有重复的工作每次需要人工去回归,建议使用自动化去回归,部门大家都用自动使用,会让大家的心信提高因为每次都机会使用自己写的脚本去验证自己重复工作。

脚本维护成本真的高吗?大家都说成本高,自己是否真的维护过,写过脚本?如果没有写过,没有维护过,没有发言权。只有自己用了才知道是否高。

三、环境安装

1、桌面版本安装

打开下面链接选择版本为exe进行下载:

下载安装后:

点击启动:

2、DOS命令安装


安装JDK

下载地址:https://www.oracle.com/technetwork/java/javase/downloads/index.html

配置环境变量:

JAVA_HOME:

JAVA_HOME=C:\\Program Files (x86)\\Java\\jdk1.8.0_181
%JAVA_HOME%\\bin;%JAVA_HOME%\\jre\\bin;
CLASSPATH:
.;%JAVA_HOME%\\lib;%JAVA_HOME%\\lib\\tools.jar

Java 验证:

java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) Client VM (build 25.181-b13, mixed mode, sharing)

3、安装SDK

下载地址:

配置环境变量:

ANDROID_HOME
C:\\Program Files (x86)\\android-sdk-windows
Path:
;%ANDROID_HOME%\\tools;%ANDROID_HOME%\\platform-tools
## 下载 node
http://nodejs.cn/download/
## 安装 appium
npm install -g appium

## 如果上面下载比较慢可以使用如下命名
## cnpm 安装
npm install -g cnpm --registry=https://registry.npm.taobao.org
cnpm install -g appium --no-cache
cnpm i appium-doctor
appium -v

安装验证环境命令:appium-doctor

执行命令验证是否成功:

Appium 版本检查与运行显示:

注意:如果上面环境没有配置,请自己搜索解决。

四、常用操作方法

  • 点击:click()
  • 输入:
sendKeys(CharSequence... keysToSend);
  • 清除:clear()
  • 长按:
     /**
     * 购物车商品图片
     * 长按
     * @param driver
     */
     
    public void cartSingleProductImage(AndroidDriver<AndroidElement> driver, String coordinate) 
        WaitUtil.waitWebElement(driver, getByLocator.getLocatorApp(coordinate), "长按购物车商品图片-弹出收藏与删除浮层");
        element = driver.findElement(getByLocator.getLocatorApp(coordinate));

        int x = element.getLocation().getX();
        int y = element.getLocation().getY();
        TouchAction action = new TouchAction(driver);
        //长按
        action.longPress(PointOption.point(x, y)).release().perform();
  • 滑动:
       WebElement webElement = null;
        try 
            driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
            webElement = driver.findElementByAndroidUIAutomator(
                    "new UiScrollable(new UiSelector().scrollable(true)).scrollIntoView(new UiSelector().text(\\"See more details\\"))");
         catch (Exception e) 
            e.printStackTrace();
        
  • 上下左右滑动,最简单的下滑命令行:(uuid 表示手机设备号)
adb -s " + uuid + " shell input touchscreen swipe 400 800 400 400
     /**
         * 滑动方法
         *
         * @param driver
         * @param direction up、down、left、right
         */

        static Duration duration = Duration.ofSeconds(1);
        public static void swipe(AndroidDriver<AndroidElement> driver, String direction) 
            switch (direction.toLowerCase()) 
                case "up":
                    SwipeUp(driver);
                    break;
                case "down":
                    SwipeDown(driver);
                    break;
                case "left":
                    SwipeLeft(driver);
                    break;
                case "right":
                    SwipeRight(driver);
                    break;
                default:
                    System.out.println("方向参数不对,只能是up、down、left、right");
                    break;
            
        


        /**
         * 上滑
         *
         * @param driver
         */

        public static void SwipeUp(AndroidDriver<AndroidElement> driver) 
            try 
                Thread.sleep(1000);
             catch (InterruptedException e) 
                e.printStackTrace();
            
            Dimension size = driver.manage().window().getSize();
            int height = size.height;
            int width = size.width;
            new TouchAction(driver).longPress(PointOption.point(width / 2, 100))
                    .moveTo(PointOption.point(width / 2, height - 100)).release()
                    .perform();

        


        /**
         * 下滑
         *
         * @param driver
         */

        public static void SwipeDown(AndroidDriver<AndroidElement> driver) 
            try 
                Thread.sleep(1000);
             catch (InterruptedException e) 
                e.printStackTrace();
            
            Dimension size = driver.manage().window().getSize();
            int height = size.height;
            int width = size.width;
            new TouchAction(driver)
                    .longPress(PointOption.point(width / 2, height - 100))
                    .moveTo(PointOption.point(width / 2, 100)).release().perform();
        


        /**
         * 左滑
         *
         * @param driver
         */

        public static void SwipeLeft(AndroidDriver<AndroidElement> driver) 
            try 
                Thread.sleep(1000);
             catch (InterruptedException e) 
                e.printStackTrace();
            
            Dimension size = driver.manage().window().getSize();
            int height = size.height;
            int width = size.width;
            new TouchAction(driver)
                    .longPress(PointOption.point(width - 100, height / 2))
                    .moveTo(PointOption.point(100, height / 2)).release().perform();
        


        /**
         * 右滑
         *
         * @param driver
         */

        public static void SwipeRight(AndroidDriver<AndroidElement> driver) 
            try 
                Thread.sleep(1000);
             catch (InterruptedException e) 
                e.printStackTrace();
            

            Dimension size = driver.manage().window().getSize();
            int height = size.height;
            int width = size.width;
            new TouchAction(driver).longPress(PointOption.point(100, height / 2))
                    .moveTo(PointOption.point(width - 100, height / 2)).release()
                    .perform();
        
  • 获取属性:getAttribute()
  • 获取文本:getText()
  • 获取资源:getPageSource()
  • 元素定位,两种方式。
    • 第一种使用 sdk 中的【uiautomatorviewer.bat】进行元素定位
      打开:

双击 uiautomatorviewer.bat 即可弹出:

在操作上面之前需要链接手机或者链接模拟器并操作命令显示:adb devices
如果是模拟器需要先链接:adb connect 127.0.0.1:62001 这样再次链接.

模拟器链接显示:

点击 sdk 中的【uiautomatorviewer.bat】

链接成功显示:

鼠标点击某个控件就会提示该控件可操作的相应内容:

说明:

其实在做移动端自动化测试,定位方式很少基本就是 id/name/xpath/ 坐标等定位方式。

五、常见定位方式

1、ID 定位

 driver.findElement(By.id("xxxxxx")).click();

2、name定位

 driver.findElement(By.name("xxxxxx")).click();

3、xpath 定位

xpath定位是最常用的一种方式,可以去学习下 xpath 语法:

但是网上也有大牛做一个插件,做 ui 自动化可直接使用:- https://github.com/lazytestteam/lazyuiautomatorviewer

大家下载后替换 sdk 中的 uiautomatorviewer.jar 就可使用。

点击 uiautomatorviewer.bat 再次弹出如下:

driver.findElement(By.xpath("xxxxxx")).click();

4、定位 h5 页面

启动:

点击:

再弹出对话中输入:

在下面选项框中输入:
需要获取 appPackage 与 appActivity

使用命令:

aapt d badging pinduoduov4.76.0_downcc.com.apk |findstr "package launchable-activity"

获取结果:

  "platformName": "Android",  "deviceName": "127.0.0.1:62001",  "appPackage": "com.xunmeng.pinduoduo",  "appActivity": "com.xunmeng.pinduoduo.ui.activity.MainFrameActivity"

点击启动:

显示正在启动:

启动完毕显示:

启动完毕,剩下的就是常用与其他操作一样:

六、简单 demo 示例

    import io.appium.java_client.AppiumDriver;
    import io.appium.java_client.TouchAction;
    import io.appium.java_client.android.AndroidDriver;
    import io.appium.java_client.android.AndroidElement;
    import io.appium.java_client.android.AndroidKeyCode;
    import io.appium.java_client.functions.ExpectedCondition;
    import io.appium.java_client.remote.AndroidMobileCapabilityType;
    import io.appium.java_client.remote.MobileCapabilityType;
    import io.appium.java_client.touch.LongPressOptions;
    import io.appium.java_client.touch.WaitOptions;
    import io.appium.java_client.touch.offset.PointOption;
    import org.apache.commons.io.FileUtils;
    import org.openqa.selenium.*;
    import org.openqa.selenium.remote.DesiredCapabilities;
    import org.openqa.selenium.support.ui.ExpectedConditions;
    import org.openqa.selenium.support.ui.WebDriverWait;
    import javax.imageio.ImageIO;
    import java.awt.image.BufferedImage;
    import java.io.ByteArrayInputStream;
    import java.io.File;
    import java.io.IOException;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.time.Duration;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.TimeUnit;


    /**
     * @author 7DGroup
     * @Title: Bases
     * @Description: 安装初始化类
     * @date 2019/11/20 / 22:34
     */

    public class DriverBase 


        public static AndroidDriver<AndroidElement> driver;

        /**
         * @param port :服务器启动的端口号,系统自动获取
         * @param udid :手机设备号:系统自动化获取
         * @param apk  :自动化运行的APK包,系统会根据该地址获取包名与actiber
         * @param flag :true 卸掉有重新安装与运行后自动化卸掉包。false 直接安装运行
         * @return

         */

        public static AndroidDriver<AndroidElement> initDriver(String port, String udid, String apk, boolean flag) 
            ArrayList<String> packAct = OperationalCmd.getPackAct(apk);
    //        File app = new File(".\\\\apk\\\\20171026.apk");
            DesiredCapabilities caps = new DesiredCapabilities();
            //自动安装
            if (flag) 
                caps.setCapability(MobileCapabilityType.APP, apk);
                //结束后会卸载程序
                caps.setCapability(MobileCapabilityType.FULL_RESET, AndroidCapabilityType.FULL_RESET);
            

            caps.setCapability(AndroidMobileCapabilityType.APPLICATION_NAME, udid);
            //PLATFORM_NAME: 平台名称
            caps.setCapability(AndroidMobileCapabilityType.PLATFORM_NAME, AndroidCapabilityType.PLATFORM_NAME);
           
           //UDID:设置操作手机的唯一标识,android手机可以通过adb devices查看
            caps.setCapability(MobileCapabilityType.DEVICE_NAME, udid);
           
           //NEW_COMMAND_TIMEOUT: appium server和脚本之间的 session超时时间
            caps.setCapability(AndroidCapabilityType.NEW_COMMAND_TIMEOUT, AndroidCapabilityType.NEW_COMMAND_TIMEOUT);
            
            //APP_PACKAG:Android应用的包名
            caps.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, packAct.get(0));

            //APP_ACTIVITY :启动app的起始activity
            caps.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, packAct.get(1));

            //UNICODE_KEYBOARD:1、中文输入不支持,2、不用它键盘会弹出来,说不定会影响下一步操作.需要注意设置后,需要将手机的输入法进行修改
            caps.setCapability(AndroidMobileCapabilityType.UNICODE_KEYBOARD, AndroidCapabilityType.UNICODE_KEY_BOARD);

            //Reset_KEYBOARD:是否重置输入法
            caps.setCapability(AndroidMobileCapabilityType.RESET_KEYBOARD, AndroidCapabilityType.RESET_KEY_BOARD);

            //NO_SIGN:跳过检查和对应用进行 debug 签名的
            caps.setCapability(AndroidMobileCapabilityType.NO_SIGN, AndroidCapabilityType.NO_SIGN);

            try 
                //appium测试服务的地址
                String serverUrl = "http://127.0.0.1";
                driver = new AndroidDriver<>(new URL(serverUrl +移动端自动化测试appium框架之数据驱动(代码片段)

...文章,实在不会在参考网上怎么搭建。移动端自动化测试工具Appium快速入门主要实现UI自动化框架元素放文本存储、数据存储、代码直接存储等其实随便那个都行,只有自己用者方便就行,我工作中用文本文件存储... 查看详情

移动端自动化测试appium框架之数据驱动(代码片段)

文章目录背景前置条件主要实现元素读取工具类读取文件操作方法元素等待查找工具类元素定位类基础启动类业务组合测试类总结背景自动化是为业务测试服务,如果数据与业务放在一起看起来不是专业,把数据与业务... 查看详情

python爬虫:使用appium在移动端抓取微博数据(代码片段)

...息使用Appium在移动端抓取微博数据Appium是移动端的自动化测试工具,读者可以类比为PC端的selenium。通过它,我们可以驱动App完成自动化的一系列操作,同样也可以爬取需要的内容。这里,我们需要首先在PC端安装A... 查看详情

python爬虫:使用appium在移动端抓取微博数据(代码片段)

...息使用Appium在移动端抓取微博数据Appium是移动端的自动化测试工具,读者可以类比为PC端的selenium。通过它,我们可以驱动App完成自动化的一系列操作,同样也可以爬取需要的内容。这里,我们需要首先在PC端安装A... 查看详情

appium移动端自动化测试一

最近公司决定使用appium为主体框架做一个移动端得自动化测试系统,我会陆续记录项目得进展。1.首先是appium环境得搭建,需要安装appium-server,appium-desktop,android-sdk等一系列工具,编译工具我用的是IDEA 这些安装请自行百度。... 查看详情

移动端自动化测试appium环境搭建(代码片段)

...个分类,接口自动化和ui自动化,ui自动化呢又分移动端的和web端的,当然还有c/s架构的,这种桌面程序应用的自动化,使用QTP,只不过现在没人做了。web自动化呢,现在基本上都是用selenium,webdrive... 查看详情

移动端自动化测试appium环境搭建

...要有两个分类,接口自动化和ui自动化,ui自动化呢又分移动端的和web端的,当然还有c/s架构的,这种桌面程序应用的自动化,使用QTP,只不过现在没人做了。 web自动化呢,现在基本上都是用selenium,webdriver这些,app的自动化... 查看详情

移动端自动化测试-po设计模式(代码片段)

...gt;输入内容->点击返回按钮#2.实现点击设置->更多->移动网络->首选网络类型-> 查看详情

po设计模式-实现移动端自动化测试(代码片段)

...gt;输入内容->点击返回按钮#2.实现点击设置->更多->移动网络->首选网络类型-> 查看详情

appium+java实现androidapp自动化测试(代码片段)

...一个开源测试自动化框架,可用于原生,混合和移动Web应用程序测试。它使用WebDriver协议驱动iOS,Android和Windows应用程序;UiAutomator测试框架是AndroidSDK自带的AppUI自动化测试Java库;appium在Android端基于WebDriver协... 查看详情

appium+java实现androidapp自动化测试(代码片段)

...一个开源测试自动化框架,可用于原生,混合和移动Web应用程序测试。它使用WebDriver协议驱动iOS,Android和Windows应用程序;UiAutomator测试框架是AndroidSDK自带的AppUI自动化测试Java库;appium在Android端基于WebDriver协... 查看详情

移动appium测试必知必会(代码片段)

 针对移动端Android的测试,adb命令是很重要的一个点,必须将常用的adb命令熟记于心,将会为Android测试带来很大的方便,其中很多命令将会用于自动化测试的脚本当中.    ADB,中文名安卓调试桥,它是... 查看详情

移动端自动化测试之appium+pyhton环境准备篇

  由于工作的需要进行Andriod手机app自动化测试,公司现有支持的app的手机平台(Andriod和IOS),所以选择了Appium工具。因为Andriod和IOS,Appium都支持。百度和谷歌上的各种Appium教程可谓是琳琅满目,但大抵都是浅尝辄止。因此笔... 查看详情

appium移动端自动化测试--使用ide编辑并强化脚本

目录Appium客户端安装安装PythonIDE-PycharmJavaIDE安装使用隐式等待让用例更稳定隐式等待启动Appium非GUI模式:AppiumServer安装PythonIDE-Pycharm和JavaIDE编辑脚本,增加脚本的稳定性。@Appium客户端安装上一节录制完成测试用例脚本,每种语言... 查看详情

appinum自动化测试利器入门(代码片段)

...f1f;Appium是c/s架构的,Appium是基于webdriver协议添加了对移动设备自动化api扩展而成的,webdriver是基于http协议的,第一次连接会建立一个session会话, 查看详情

app自动化测试----基础入门appium初使用2(uiautomator元素定位)(代码片段)

1.说明元素定位方式有多种,Android也有自身独有的定位方式。下面就单独介绍其基于uiautomator定位元素的方法。基本语法:driver.find_element_by_android_uiautomator(xx)参考文档:https://developer.android.com/reference/androidx/test/uiautomator/UiSelector&n... 查看详情

python+appium自动化测试——appium并发测试之多设备启动(代码片段)

来自APPAndroid端自动化测试初学者的笔记,写的不对的地方大家多多指教哦一、启动appium服务器1.通过命令行窗口启动单个appium服务器appium--直接打开默认的4723端口号appium-p4723--使用-p来启动固定端口号的appium服务器复制代码2.... 查看详情

appinum自动化测试利器入门(代码片段)

文章目录1前言2什么是Appinum?3环境准备3.1设置JDK变量3.2设置Android环境3.3下载Appium工具3.4下载AppiumInspector工具3.5手机需要开启调试模式4启动Appium服务5连接Appinum服务5.1使用命令行连接5.2使用`AppiumInspector`工具连接6常用命... 查看详情