Appium 2安装与使用java对Android进行自动化测试

news2024/11/25 4:19:06

文章目录

    • 1、Appium 2.1安装
      • 1.1、系统要求
      • 1.2、安装Appium2.1服务
      • 1.3、安装UiAutomator2驱动
      • 1.4、安装Android SDK platform tools
      • 1.5、下载OpenJDK
    • 2、Android自动代码例子
      • 2.1、安装Android自动化测试元素定位工具Appium Inspector
      • 2.2、编写android app自动化测试代码和使用extentreports生成测试报告

1、Appium 2.1安装

1.1、系统要求

当前Appium2.1服务器的要求:

  • 支持macOS、Linux或Windows操作系统
  • Node.js版本要求^14.17.0 || ^16.13.0 | >=18.0.0
  • NPM版本>= 8 (NPM通常与Node.js捆绑在一起,但可以独立升级)

系统要求:http://appium.io/docs/en/2.1/intro/requirements/

1.2、安装Appium2.1服务

下载nodejs:https://nodejs.org/zh-cn/download/releases
本文下载:node-v18.17.1-win-x64.zip
解压在D:\Program Files\nodejs\node-v18.17.1-win-x64目录
在PATH环境变量中添加

D:\Program Files\nodejs\node-v18.17.1-win-x64

npm默认使用国外源,网络原因容易出现安装依赖失败,本文设置npm为国内源

npm config set registry https://registry.npmmirror.com

运行NPM命令安装Appium,参考官方安装http://appium.io/docs/en/2.1/quickstart/install/

npm i --location=global appium

图片

安装成功后,输入下边命令可以直接启动服务

appium

在这里插入图片描述

1.3、安装UiAutomator2驱动

查看当前可用驱动appium driver list

C:\Users\admin>appium driver list
✔ Listing available drivers
- uiautomator2 [not installed]
- xcuitest [not installed]
- mac2 [not installed]
- espresso [not installed]
- safari [not installed]
- gecko [not installed]
- chromium [not installed]
  • uiautomator2 用于android自动化测试
  • xcuitest 用于ios自动化测试
    本文只研究android测试,输入下边命令安装
appium driver install uiautomator2

在这里插入图片描述

官方参考:http://appium.io/docs/en/2.1/quickstart/uiauto2-driver/

1.4、安装Android SDK platform tools

下载Android SDK platform tools:Android SDK platform tools
解压目录:D:\ProgramData\android\sdk\platform-tools
在PATH环境变量中添加

D:\ProgramData\android\sdk\platform-tools

如果使用真机测试,只安装platform tools就可以了,如果使用模拟器,需要安装完整在sdk,可以下载Android Studio:https://developer.android.google.cn/studio,使用Android Studio里面的管理SDK工具管理相关SDK和工具。
在这里插入图片描述
在这里插入图片描述

1.5、下载OpenJDK

下载OpenJDK:https://21doc.net/java/awesomejava#jvm-and-jdk
当前版本支持JDK11,本文使用bellsoft-jdk11.0.20+8-windows-amd64.zip,下载地址:https://bell-sw.com/pages/downloads/

下载后解压在:C:\Program Files\Java\bellsoft\jdk-11.0.20
在PATH环境变量中添加

C:\Progra~1\Java\bellsoft\jdk-11.0.20\bin

2、Android自动代码例子

2.1、安装Android自动化测试元素定位工具Appium Inspector

Appium Inspector官网:https://github.com/appium/appium-inspector
官方介绍Appium Inspector基本上只是一个带有用户界面的Appium客户端(如WebdriverIO、Appium的Java客户端、Appium的Python客户端等)。有一个接口用于指定使用哪个Appium服务器、设置哪些功能,然后在启动会话后与元素和其他Appium命令进行交互。
在1.22版本后appium-deskop不集成Appium Inspector,所以Appium Inspector需要单独打开。
Appium Inspector支持web和客户端版本。

  • web版本
    web版本可以直接访问:https://inspector.appiumpro.com/使用。

  • 客户端版本
    下载地址:https://github.com/appium/appium-inspector/releases
    在这里插入图片描述

点击“启动会话”,就可以打开APP,进行元素定位
在这里插入图片描述

参数配置可查看:https://appium.io/docs/en/2.1/guides/caps/

** 启动会话可能会出现下边的错误提示**

Exception in thread "main" org.openqa.selenium.SessionNotCreatedException: Could not start a new session. Response code 500. Message: An unknown server-side error occurred while processing the command. Original error: Check https://forum.xda-developers.com/t/i-cant-enable-write_secure_settings-for-an-app-over-adb.3855596/ for throubleshooting. Error executing adbExec. Original error: 'Command 'D:\\ProgramData\\android\\sdk\\platform-tools\\adb.exe -P 5037 -s 972cac1 shell 'settings delete global hidden_api_policy_pre_p_apps;settings delete global hidden_api_policy_p_apps;settings delete global hidden_api_policy'' exited with code 255'; Command output: Security exception: Permission denial: writing to settings requires:android.permission.WRITE_SECURE_SETTINGS

解决办法

  • 小米设备: 开启 USB调试(安全设置)
    (1) 手机-插入 sim卡
    (2) 设置 - 更多设置 - 开发者选项 - USB调试(安全设置)- 开启

  • OPPO设备: 开启 禁止权限监控
    开发者选项 - 禁止权限监控 - 开启

2.2、编写android app自动化测试代码和使用extentreports生成测试报告

使用appium的java-client库(https://github.com/appium/java-client)编写android app自动化测试代码,并使用extentreports生成测试报告
maven工程,pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.penngo.app</groupId>
    <artifactId>monitor_app</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <log4j2.version>2.17.2</log4j2.version>
        <slf4j_simple.version>1.7.36</slf4j_simple.version>
        <lombok.version>1.18.24</lombok.version>
        <testng.version>7.4.0</testng.version>
        <hutool.version>5.8.3</hutool.version>
        <extentreports-testng-adapter.version>1.2.3</extentreports-testng-adapter.version>
        <extentreports.version>5.0.9</extentreports.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>io.appium</groupId>
            <artifactId>java-client</artifactId>
            <version>8.5.1</version>
<!--            <scope>test</scope>-->
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>4.9.1</version>
        </dependency>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>${testng.version}</version>
        </dependency>
        <dependency>
            <groupId>com.aventstack</groupId>
            <artifactId>extentreports</artifactId>
            <version>${extentreports.version}</version>
        </dependency>
        <dependency>
            <groupId>com.aventstack</groupId>
            <artifactId>extentreports-testng-adapter</artifactId>
            <version>${extentreports-testng-adapter.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>${log4j2.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>${log4j2.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>${slf4j_simple.version}</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>${hutool.version}</version>
        </dependency>
    </dependencies>


    <repositories>
        <repository>
            <id>alimaven</id>
            <name>Maven Aliyun Mirror</name>
            <url>https://maven.aliyun.com/repository/central</url>
        </repository>
    </repositories>
    <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>${maven.compiler.source}</source>
                <target>${maven.compiler.source}</target>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.22.2</version>
            <configuration>
                <skip>true</skip>
            </configuration>
        </plugin>
    </plugins>
    </build>
</project>

测试用例java代码

import cn.hutool.core.io.FileUtil;
import com.aventstack.extentreports.testng.listener.ExtentIReporterSuiteClassListenerAdapter;
import io.appium.java_client.AppiumBy;
import io.appium.java_client.android.Activity;
import io.appium.java_client.android.AndroidDriver;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

import java.io.File;
import java.io.FileOutputStream;
import java.time.Duration;
import java.util.HashSet;
import java.util.List;

/**
 * 例子
 * https://github.com/appium/java-client/blob/master/src/test/java/io/appium/java_client/android/AndroidTouchTest.java
 */
@Listeners(ExtentIReporterSuiteClassListenerAdapter.class)
@Slf4j
@Test(description="APP测试", priority = 1)
public class AppTest {
    public static final String APP_ID = "com.penngo.xxx";
    protected static final int PORT = 4723;
    protected static AndroidDriver driver = null;
    private static AppiumDriverLocalService service;

    @BeforeClass
    public void setUpAll(){
        service = new AppiumServiceBuilder()
                .withIPAddress("127.0.0.1")
                .usingPort(PORT)
                .build();
        service.start();
        UiAutomator2Options options = new UiAutomator2Options()
                .setDeviceName("972cac1")
                .setAppPackage(APP_ID)
                .setAppActivity("com.penngo.xxx.activity.MainActivity")
                ;
        driver = new AndroidDriver(service.getUrl(), options);
    }

    @AfterClass
    public void tearDownAll(){
        if(driver != null){
            driver.quit();
        }
    }
    /**
     * app首页
     */
    @Test(description="APP首页", priority = 1)
    public void testHome() {
        String activity = driver.currentActivity();
        Assert.assertEquals(activity, ".activity.MainActivity");


    }

    /**
     * app 我首页
     */
    @Test(description="关于", priority = 2)
    public void testMe() {
        String activity = driver.currentActivity();
        // 获取底部5个选项
        WebElement navTabIndicator = driver.findElement(AppiumBy.id("com.penngo.xxx:id/NavTabIndicator"));
        List<WebElement> list = navTabIndicator.findElements(AppiumBy.className("android.widget.TextView"));
        System.out.println("list.size====="+ list.size());
        HashSet tabs = new HashSet();

        WebElement myElement = null;
        for(WebElement el:list){
            String text = el.getAttribute("text");
            if(text.equals("关于")){
                myElement = el;
            }
        }
        // 切换到关于选项卡
        myElement.click();
        new WebDriverWait(driver, Duration.ofSeconds(10)).until(ExpectedConditions.elementToBeClickable(AppiumBy.id("com.penngo.xxx:id/setting_fragment")));

        // 切换到设置
        WebElement setting = driver.findElement(AppiumBy.id("com.penngo.xxx:id/setting_fragment"));
        setting.click();

        new WebDriverWait(driver, Duration.ofSeconds(10)).until(d->{
            AndroidDriver driver2 = (AndroidDriver)d;
            String currentActive = driver2.currentActivity();
            if(!currentActive.equals(activity)){
                log.info("设置====" + activity);
                return currentActive;
            }
            else{
                return null;
            }
        });
        System.out.println("设置 Activity====" + driver.currentActivity());
        log.info("设置 Activity====" + driver.currentActivity());
        // 截图
        File screenShotFile = driver.getScreenshotAs(OutputType.FILE);
        System.out.println("screenShotFile====" + screenShotFile);

        FileUtil.copy(screenShotFile.getAbsolutePath(), new File("logs/setting.png").getAbsolutePath(), true);
    }

}


运行效果:
在这里插入图片描述

生成测试报告:
在这里插入图片描述

更多官方例子:https://github.com/appium/java-client/tree/master/src/test/java/io/appium/java_client/android

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/904301.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Lemon8与中国各大社交平台的内容输出整合,将会掀起何种风浪?

近期,Lemon8迅速在北美地区展开了布局,短短几天的时间,下载量就冲到了美国APP下载总榜的前十,随后更是直登顶生活类APP首榜。作为字节跳动旗下的出海内容平台,一经问世后,就受到了大量用户的关注,并吸引了海外媒体以及营销人士的目光。那么Lemon8与中国各大社交平台的内容输出整…

机器学习笔记之优化算法(十六)梯度下降法在强凸函数上的收敛性

机器学习笔记之优化算法——梯度下降法在强凸函数上的收敛性 引言回顾&#xff1a;凸函数与强凸函数梯度下降法&#xff1a;凸函数上的收敛性分析 关于白老爹定理的一些新的认识梯度下降法在强凸函数上的收敛性收敛性定理介绍结论分析证明过程 引言 本节将介绍&#xff1a;梯度…

人工智能大模型加速数据库存储模型发展 行列混合存储下的破局

数据存储模型 ​专栏内容&#xff1a; postgresql内核源码分析手写数据库toadb并发编程toadb开源库 个人主页&#xff1a;我的主页 座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物. 概述 在数据库的发展过程中&#xff0c;关…

【Linux】进程间通信之信号机制

文章目录 信号的概念信号的产生硬件产生&#xff08;按键盘中的按键&#xff09;软件产生kill函数kill命令abort函数raise函数 捕捉信号后的处理方式默认处理方式SIG_DFL忽略处理方式SIG_IGN自定义信号处理方式signal函数sigaciotn函数 信号的注册进程中的未决信号集&#xff0…

在python中通过调用dll来提高运行速度

1、前言 最近项目中需要录制键鼠命令&#xff0c;然后再通过注入的方式回放录制过程。一般来说&#xff0c;普通的一些点击命令完全可以通过python的一些包来完成键鼠模拟操作&#xff0c;比如通过pyautogui包。但是&#xff0c;鼠标移动过程中&#xff0c;如果采用频率很高的…

C++对象模型实验(clang虚函数表结构)

摘要&#xff1a;本科期间有对比过msvc&#xff0c;gcc&#xff0c;clang的内存布局&#xff0c;距今已经6-7年了&#xff0c;当时还是使用的c11。时间过得比较久了&#xff0c;这部分内容特别是内存对齐似乎C17发生了一些变化&#xff0c;因此再实践下C类模型。本文描述了C不同…

DuckDB Executor:物理计划构建Pipeline并执行(PipelineExecutor)

2023-03-20 duckdb-Push-Based Execution Model 如下SQL的物理计划执行 select 100(select 3), id from user where id (select id from score where id 1) Pipeline与MetaPipeline Pipeline是一串Op. MetaPipeline是pipeline组成的树 Executor构建MetaPipeline MetaPip…

【汇编语言】关于“段”的总结

文章目录 各种段三种段具体案例截图数据段、栈段、代码段同时使用不同段地址数据段、栈段、代码段同时使用一个段地址![在这里插入图片描述](https://img-blog.csdnimg.cn/45c299950ad949e3a90b7ed012b3a9ee.png) 各种段 1、基础 物理地址 段地址 x 16 偏移地址 2、做法 编…

Redis——主从复制+集群搭建(非哨兵)

主从复制 概念 主从复制&#xff0c;是指将一台Redis服务器的数据&#xff0c;复制到其他的Redis服务器。前者称为主节点(master/leader)&#xff0c;后者称为从节点(slave/follower); 数据的复制是单向的&#xff0c;只能由主节点到从节点。Master以写为主&#xff0c;Slave…

CentOS6.8图形界面安装Oracle11.2.0.1.0

Oracle11下载地址 https://edelivery.oracle.com/osdc/faces/SoftwareDelivery 一、环境 CentOS release 6.8 (Final)&#xff0c;测试环境&#xff1a;内存2G&#xff0c;硬盘20G&#xff0c;SWAP空间4G Oracle版本&#xff1a;Release 11.2.0.1.0 安装包&#xff1a;V175…

【C++奇遇记】构造函数 | 初始化列表

&#x1f3ac; 博客主页&#xff1a;博主链接 &#x1f3a5; 本文由 M malloc 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f384; 学习专栏推荐&#xff1a;LeetCode刷题集 数据库专栏 初阶数据结构 &#x1f3c5; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如…

LeetCode:Hot100python版本之回溯

回溯算法其实是纯暴力搜索。for循环嵌套是写不出的 组合&#xff1a;没有顺序 排列&#xff1a;有顺序 回溯法可以抽象为树形结构。只有在回溯算法中递归才会有返回值。 46. 全排列 78. 子集 17. 电话号码的字母组合 39. 组合总和 22. 括号生成 79. 单词搜索 ​​​​​​13…

剪枝基础与实战(3): 模型剪枝和稀疏化训练流程

Model Pruning 相关论文:Learning Efficient Convolutional Networks through Network Slimming (ICCV 2017) 考虑一个问题,深度学习模型里面的卷积层出来之后的特征有非常多,这里面会不会存在一些没有价值的特征及其相关的连接?又如何去判断一个特征及其连接是否有价值? …

Android学习之路(7) Frament

Fragment 表示应用界面中可重复使用的一部分。fragment 定义和管理自己的布局&#xff0c;具有自己的生命周期&#xff0c;并且可以处理自己的输入事件。fragment 不能独立存在。它们必须由 activity 或其他 fragment 托管。fragment 的视图层次结构会成为宿主的视图层次结构的…

2023国赛数学建模C题思路模型代码 高教社杯

本次比赛我们将会全程更新思路模型及代码&#xff0c;大家查看文末名片获取 之前国赛相关的资料和助攻可以查看 2022数学建模国赛C题思路分析_2022国赛c题matlab_UST数模社_的博客-CSDN博客 2022国赛数学建模A题B题C题D题资料思路汇总 高教社杯_2022国赛c题matlab_UST数模社…

【Keil软件 ST-Link下载问题】:提示ST-Link需要升级,但是升级之后会报错:Upgrade Error, Please try again.

项目场景&#xff1a; 报错&#xff1a; 平常一直使用J-link&#xff0c;一直没有问题&#xff0c;今天使用了一下ST-Link发现了问题&#xff0c;下载不进去。 并且提示我需要升级ST-Link&#xff0c;我按照规定的升级&#xff0c;但是依然报错。 下面是我的心路历程&#xff…

JDK中的Timer总结

目录 一、背景介绍二、思路&方案三、过程1.Timer关键类图2.Timer的基本用法3.结合面向对象的角度进行分析总结 四、总结五、升华 一、背景介绍 最近业务中使用了jdk中的Timer&#xff0c;通过对Timer源码的研究&#xff0c;结合对面向对象的认识&#xff0c;对Timer进行针…

简单认识Docker数据管理

文章目录 为何需要docker数据管理数据管理类型 一、数据卷二、数据卷容器三、容器互联 为何需要docker数据管理 因为数据写入后如果停止了容器&#xff0c;再开启数据就会消失&#xff0c;使用数据管理的数据卷挂载&#xff0c;实现了数据的持久化&#xff0c;重启数据还会存在…

合宙Air724UG LuatOS-Air LVGL API--运行

硬件准备 可以使用 724A13 开发板 ST7735S 屏幕 或者 iCool 开发板 软件准备 底层固件 底层固件需要支持 LVGL&#xff0c;通常选用的固件是 LuatOS-Air_VXXXX_RDA8910_BT_FLOAT.pac。 当然&#xff0c;您也可以通过 更新说明 选择支持 LVGL 的其他底层版本。 脚本 首先需要…

垂类模型大有前景,但AGI却给自己“挖了个坑”

巨量模型是个“坑”&#xff0c;但垂直模型不是。 数科星球原创 作者丨苑晶 编辑丨大兔 2023年4月&#xff0c;GPT-5的相关消息引起了一阵轰动。彼时&#xff0c;人们对巨量大模型既有期待、也有恐惧。更有甚者&#xff0c;认为人类历史或许将因此而画上终止符。 但很快&#…