#client #devices #mobile #screen #android #appium

appium-client

Appium服务器的客户端,用于自动化移动应用测试

8个版本

0.2.2 2024年1月5日
0.2.1 2024年1月5日
0.2.0 2023年9月12日
0.1.4 2023年8月25日
0.1.2 2023年2月8日

#107 in 测试

Download history 42/week @ 2024-04-14 110/week @ 2024-04-21 161/week @ 2024-04-28 83/week @ 2024-05-05 82/week @ 2024-05-12 199/week @ 2024-05-19 41/week @ 2024-05-26 113/week @ 2024-06-02 54/week @ 2024-06-09 27/week @ 2024-06-16 96/week @ 2024-06-23 28/week @ 2024-06-30 142/week @ 2024-07-07 115/week @ 2024-07-14 94/week @ 2024-07-21 113/week @ 2024-07-28

每月465次下载

GPL-3.0-or-later

165KB
2.5K SLoC

appium-client

Rust编写的Appium服务器客户端,用于自动化移动应用测试。它基于fantoccini

Appium是一个用于自动化原生应用测试的工具。换句话说,它用于模拟应用中的用户活动。你告诉Appium在屏幕上寻找什么,点击什么,Appium会为你完成。

Appium由以下组成

  • 一个Appium服务器,通过REST服务Appium API并将命令委派给驱动程序,
  • Appium API,它是发送命令的统一方式,
  • Appium驱动程序,它是一个库,知道如何与您要控制的设备进行通信。

这个库是一个Appium客户端。这意味着它向Appium服务器发送命令。您需要设置Appium才能使用此库。

文档主要关注整个工具的客户端方面。因此,如果您需要有关Appium服务器、驱动程序或设备设置的更多信息,请参阅Appium文档

还可以查看示例

功能

  • 预定义的iOS和Android能力(至少其中一些)。
  • 锁定和解锁屏幕。
  • 获取设备/模拟器的当前时间。
  • 获取设备的旋转和方向。
  • 屏幕录制支持。
  • 电池状态支持。
  • Android网络状态。
  • 更改设备设置。
  • 推送和拉取文件。
  • 获取应用程序字符串。
  • 访问设备剪贴板。
  • 模拟Touch ID和指纹认证。
  • 键盘模拟。
  • 使用未实现的功能和驱动程序的能力。

指南、教程和文档

快速指南

本快速指南假设您了解Appium的工作原理。它重点介绍了该库的关键功能。如果您需要更基础的指南,请参阅设置和编写第一个自动化脚本

如何使用?

首先需要启动一个Appium服务器。您还需要将设备(或仿真器)连接到运行Appium服务器的机器。

如果您已正确设置Appium,则可以使用此库连接到服务器并控制设备。

要连接到Appium服务器,您需要创建一个Client的实例。要做到这一点,创建适当的能力(例如,AndroidCapabilities::new_uiautomator()),然后将它们提供给ClientBuilder

您需要一个Tokio异步运行时才能正常工作。

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut capabilities = AndroidCapabilities::new_uiautomator();
    capabilities.app("https://github.com/appium/android-apidemos/releases/download/v3.1.0/ApiDemos-debug.apk");

    let client = ClientBuilder::native(capabilities)
        .connect("https://127.0.0.1:4723/")
        .await?;

    // now you can start testing

    Ok(())
}

Appium使用DOM(文档对象模型)解释设备的屏幕。屏幕上的元素被转换成一种符合W3C Selenium标准的XML。

Appium是对此的某种扩展,具有允许控制移动设备、仿真器或桌面操作系统的驱动程序。

要查看Appium如何解释设备屏幕(并使用Appium与设备交互),您可以使用一个名为Appium Inspector的工具。这是一个非常有用的GUI工具,可以在自动化开发期间提供帮助。

如果这个库缺少某些功能怎么办?

您可以通过创建PR来添加缺少的功能。

如果您没有时间做这件事,您也可以直接发出命令,而不依赖于此库的特性。

例如,假设Appium添加了一个名为“在设备上模拟桶滚”的新功能。Appium服务器为此提供了一个新的API - POST /session/:sessionId/appium/device/barrel_roll。我们可以在请求中指定设备将进行多少次桶滚 - {"times": number}

您不必等到我将其添加到库中。您可以发出自定义命令

client.issue_cmd(AppiumCommand::Custom(
    Method::POST,
    "appium/device/barrel_roll".to_string(),
    Some(json!({
        "times": 2
    }))
)).await?;

如您所见,我没有添加原始端点的/session/:sessionId。没有必要这样做 - Appium客户端会自动添加。

示例用法

创建客户端

创建将用于发出命令和定位元素的Appium客户端。

客户端是一个对象,用于管理到Appium服务器的连接并向其发出命令。因此,我们需要描述自动化环境和服务器URL的能力来创建客户端。

您可以在Appium文档中了解更多关于能力的信息。

use appium_client::ClientBuilder;
use appium_client::capabilities::*;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut capabilities = AndroidCapabilities::new_uiautomator();
    capabilities.app("https://github.com/appium/android-apidemos/releases/download/v3.1.0/ApiDemos-debug.apk");

    let client = ClientBuilder::native(capabilities)
        .connect("https://127.0.0.1:4723/")
        .await?;
    
    Ok(())
}

在屏幕上定位元素

使用您喜欢的定位策略定位元素(例如,通过UiAutomator 2)。

还支持其他策略,如名称、XPath、iOS Class Chain等。

// you need this to use Appium locators with fantoccini's Client
use appium_client::find::{AppiumFind, By};

let element = client
    .find_by(By::accessibility_id("Click this"))
    .await?;

element.click().await?;

等待元素出现

如果元素没有立即出现在屏幕上,您可以等待元素。

默认情况下,等待时间为30秒。在等待期间,客户端会每250毫秒进行一次搜索,直到元素最终出现,或达到超时。

// you need these to use Appium-enhanced wait with fantoccini's Client
use appium_client::find::{AppiumFind, By};
use appium_client::wait::AppiumWait;

let element = client
    .appium_wait()
    .for_element(By::uiautomator("new UiSelector().className(\"android.widget.ImageView\");"))
    .await?;

element.click().await?;

限制等待时间

您可以定义等待元素出现的时间长度以及检查频率。

这在您知道某物应该很快出现的情况下很有用。如果它没有出现,那么可能发生了其他事情,您不想等待完整的30秒超时。

搜索间隔也可以相应调整,以便Appium服务器有更多时间“呼吸”。

// you need these to use Appium-enhanced wait with fantoccini's Client
use appium_client::find::{AppiumFind, By};
use appium_client::wait::AppiumWait;

let element = client
    .appium_wait()
    .at_most(Duration::from_secs(20))
    .check_every(Duration::from_millis(500))
    .for_element(By::uiautomator("new UiSelector().className(\"android.widget.ImageView\");"))
    .await?;

element.click().await?;

定位多个元素

要定位多个元素,请使用find_all_by.appium_wait().for_elements(..)

第一种方法的工作方式与find_by相同 - 立即返回结果。第二种方法等待给定时间,直到至少出现一个元素。它的工作方式与上面的例子相同。

// you need these to use Appium-enhanced wait with fantoccini's Client
use appium_client::find::{AppiumFind, By};
use appium_client::wait::AppiumWait;

let result = client
    .appium_wait()
    .for_elements(By::class_name("android.widget.LinearLayout"))
    .await?;

result.first().unwrap().click().await?;

您也可以在找到的元素内部进行搜索。

当您想首先找到父元素,然后在其内部找到特定子元素时,这很有用。无论听起来多么奇怪,这都是在处理DOM时非常有用的功能。

// you need this to use Appium locators with fantoccini's Client
use appium_client::find::{AppiumFind, By};

let element = client
    .find_by(By::accessibility_id("Click this"))
    .await?;

// now let's find a child of element
let image_child = element
    .find_by(By::class_name("android.widget.ImageButton"))
    .await?;

滚动

要滚动,您可以使用触摸操作。例如,让我们模拟向上滑动以进行滚动。

请记住,滑动会将屏幕“拉动”,因此您需要向下滑动以“拉动”屏幕,从而显示顶部内容。

    let swipe_down = TouchActions::new("finger".to_string())
        // position the finger first
        .then(PointerAction::MoveTo {
            duration: Some(Duration::from_millis(0)),
            x,
            y
        })
        // THEN touch the screen
        .then(PointerAction::Down {
            button: MOUSE_BUTTON_LEFT // believe me, it is not a mouse, but a simple touch
        })
        // THEN move the finger through the screen
        .then(PointerAction::MoveTo {
            duration: Some(Duration::from_millis(500)),
            x,
            y
        });

    client.perform_actions(swipe_down)
        .await?;

示例

依赖项

~8–22MB
~361K SLoC