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

文章目录

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/
可能会遇到的一个错误

bash 复制代码
Error installing Chromedriver: unable to verify the first certificate

# 解决方法
npm config set strict-ssl false
npm config set ca=""

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和客户端版本。

点击"启动会话",就可以打开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代码

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

相关推荐
盐真卿9 小时前
python2
java·前端·javascript
Root_Hacker10 小时前
include文件包含个人笔记及c底层调试
android·linux·服务器·c语言·笔记·安全·php
stevenzqzq10 小时前
android flow的背压策略
android·flow
一嘴一个橘子10 小时前
mybatis - 动态语句、批量注册mapper、分页插件
java
组合缺一10 小时前
Json Dom 怎么玩转?
java·json·dom·snack4
危险、11 小时前
一套提升 Spring Boot 项目的高并发、高可用能力的 Cursor 专用提示词
java·spring boot·提示词
kaico201811 小时前
JDK11新特性
java
钊兵11 小时前
java实现GeoJSON地理信息对经纬度点的匹配
java·开发语言
jiayong2311 小时前
Tomcat性能优化面试题
java·性能优化·tomcat
秋刀鱼程序编程11 小时前
Java基础入门(五)----面向对象(上)
java·开发语言