Appium自动化测试(本文基于Java的io.appium.java_client实现)

摘要

APP数据获取,目前为止已介绍了两种方法,一种是APK反编译,一种是破解数据流在传输过程中的各种转换;上述两种方式,对能力和毅力都有很大的要求。本文“投机取巧”,仅关注输入输出;输入的是用户APP数据所在页面的操作,输出的是数据所在接口的源码。输出,可通过Fiddler、Charles等拦截工具进行拦截,本文不作累述;输入,涉及Appium自动化测试,本文将对此进行详解。

前期准备

手机端

软件 版本
魅蓝 Note5 M5 Note
Android 6.0
Xposed Installer 3.1.5
Xposed Version 89
Just Trust Me 0.2

PC端

软件 版本
JDK 1.8.0_77
Android SDK 25.2.5
Node.js 12.0
Appium 1.18.3

PC端通过Appium操作手机端APP截图

Appium自动化测试(本文基于Java的io.appium.java_client实现)
Appium自动化测试(本文基于Java的io.appium.java_client实现)

Appium自动化测试(本文基于Java的io.appium.java_client实现)

Appium自动化测试(本文基于Java的io.appium.java_client实现)

Maven

<dependency>
	<groupId>io.appium</groupId>
	<artifactId>java-client</artifactId>
	<version>4.1.2</version>
</dependency>

Java APP操作代码

import io.appium.java_client.MobileElement;
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.remote.AndroidMobileCapabilityType;
import io.appium.java_client.remote.MobileCapabilityType;
import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URL;

public abstract class BaseCrawler {
    public static final Logger LOGGER = LoggerFactory.getLogger(BaseCrawler.class);
    public static final String url="http://0.0.0.0:4723/wd/hub";

    protected URL serverURL;
    protected DesiredCapabilities capabilities;
    protected AndroidDriver<AndroidElement> driver;

    public BaseCrawler(){
        try {
            serverURL = new URL(url);
        } catch (Exception e) {
            e.printStackTrace();
        }
        capabilities = new DesiredCapabilities();
        capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
        capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "TPE9X18612W18698");
        capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, "UiAutomator2");
        capabilities.setCapability(MobileCapabilityType.NO_RESET, true);
        capabilities.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "com.xingin.xhs");
        capabilities.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".activity.SplashActivity");
    }

    public void initDriver(){
        LOGGER.info("正在启动Appium");
        driver = new AndroidDriver(serverURL, capabilities);
    }

    public void sleep(long timeout) {
        try {
            Thread.sleep(timeout);
        } catch (Exception e) {
            ;
        }
    }

    public void goBack() {
        driver.pressKeyCode(AndroidKeyCode.BACK);
        sleep(3000);
    }

    public void click(By by, String errorMsg) {
        LOGGER.debug("点击 " + by);
        AndroidElement element = awaitFindElement(by,3000);
        if (element != null) {
            element.click();
        } else {
            LOGGER.error(errorMsg + " " + by);
            throw new RuntimeException(errorMsg);
        }
    }

    public void type(By by, String keyword, String errorMsg) {
        LOGGER.debug("输入:" + keyword + " " + by);
        AndroidElement element = awaitFindElement(by, 3000);
        if (element != null) {
            element.sendKeys(keyword);
        } else {
            LOGGER.error(errorMsg);
            throw new RuntimeException(errorMsg);
        }
    }

    public String getText(By by, String errorMsg) {
        AndroidElement element = awaitFindElement(by,3000);
        if (element != null) {
            return element.getText();
        } else {
            LOGGER.error(errorMsg);
            throw new RuntimeException(errorMsg);
        }
    }

    public void waitFor(By by, long timeout) {
        WebDriverWait wait = new WebDriverWait(driver, timeout);
        wait.until(ExpectedConditions.visibilityOfElementLocated(by));
    }

    public AndroidElement awaitFindElement(By by, long timeout) {
        try {
            waitFor(by, timeout);
            return driver.findElement(by);
        } catch (Exception e) {
            return null;
        }
    }

    public List<AndroidElement> awaitFindElements(By by, long timeout) {
        try {
            waitFor(by, timeout);
            return driver.findElements(by);
        } catch (Exception e) {
            return null;
        }
    }

    public boolean isVisiable(By by) {
        try {
            AndroidElement element = driver.findElement(by);
            return element.isDisplayed();
        } catch (Exception e) {
            return false;
        }
    }

    public boolean isVisiable(AndroidElement element, By by) {
        try {
            MobileElement mobileElement = element.findElement(by);
            return mobileElement.isDisplayed();
        } catch (Exception e) {
            return false;
        }
    }

    public void swipeUp() {
        try {
            driver.swipe(360, 1200, 360, 400, 200);
            sleep(3000);
        } catch (Exception e) {
            LOGGER.error("上划失败", e);
        }
    }
}
上一篇:Spring MVC 请求处理方法


下一篇:FATE学习:运行过程中产生的数据 概览