appium+Java实现自动化测试最新教程及实战

在前面的课程我们已经学习完成appium入门了,新来的同学可以从此跳转学习 appium入门

下面我们来学习如何使用代码来编写,将实现自动化测试和生成测试报告

Appium 和 Java 实现自动化测试的方法

Appium 是一个开源的移动端自动化测试工具,支持 Android 和 iOS 平台。结合 Java 语言,可以实现高效的自动化测试脚本编写。以下是具体实现步骤。

一、环境准备

Java JDK(1.8 或更高版本)和 Maven。  maven下载教程

安装 Node.js 以运行 Appium 服务器。

配置 Android 环境变量(如 ANDROID_HOME)并确保 adb 工具可用

在pom.xml配置文件中使用 Maven 添加 Appium 和 TestNG 依赖到项目中:

 
    
      io.appium
      java-client
      9.4.0
    

  
    
      org.testng
      testng
      7.8.0
      test
    

下面我们进入我们测试目录 project>src>test>java>org.example

appium+Java实现自动化测试最新教程及实战_第1张图片

二、基本框架

我们创建一个demoTest,代码如下:

package org.example;

import io.appium.java_client.AppiumDriver;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.options.UiAutomator2Options;
import org.example.util.WelcomeUtil;
import org.openqa.selenium.WebDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

import java.net.MalformedURLException;
import java.net.URL;

public class demoTest {
    private AppiumDriver driver;

    @BeforeTest
    public void setUp() throws MalformedURLException {
        //建立连接
        UiAutomator2Options options = new UiAutomator2Options();
        options.setPlatformVersion("13");
        options.setDeviceName("192.168.10.104:5555");
        options.setAutomationName("UiAutomator2");
        options.setAppPackage("com.fqcx.welcome");
        options.setAppActivity("com.fqcx.welcome.activity.MainActivity");

        driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), options);
    }

    @Test
    public void test(){
        //测试内容
    }

    @AfterTest
    public void tearDown(){
        //断开连接
        driver.quit();
    }
}

这段 Java 代码是一个基于 TestNG 和 Appium 的简单自动化测试框架模板,用于对移动应用进行自动化测试。我会从代码结构、各部分功能和需要补充完善的内容来为你讲解:

1.首先定义一个AppiumDriver对象

2.在@BeforeTest注解下的方法建立连接,信息需要填写自己设备的版面,名字和测试应用包名,启动页面

PlatformVersion        安卓版本,获取命令:adb shell getprop ro.build.version.release
DeviceName        设备名称,获取命令:adb devices
AppPackage和AppActivity可根据adb命令获取: adb shell dumpsys activity top | grep ACTIVITY

后面是Appium Server 的监听地址,127.0.0.1是本地环回地址。告诉驱动去哪里找 Appium Server,以便发送自动化命令

3.在@Test注解下写测试内容,稍候具体讲解

4.@AfterTest注解的tearDown方法:在当前类的所有测试方法执行完毕后运行,主要用于清理和释放资源。代码中 driver.quit(); 语句用于关闭AppiumDriver实列,断开与移动设备的连接,确保测试结束后资源被正确释放,避免占用系统资源。

三、实战演练

我们将测试一个如图计算器APP,下面我们来正式开始

appium+Java实现自动化测试最新教程及实战_第2张图片

1.首先我们拿到测试设备名称,版本号。以及测试APP的包名和启动页面

包名为:com.rp.calculator

启动页面为:com.rp.calculator.MainActivity

 @BeforeTest
    public void setUp() throws MalformedURLException {
        //建立连接
        UiAutomator2Options options = new UiAutomator2Options();
        options.setPlatformVersion("13");
        options.setDeviceName("192.168.10.104:5555");
        options.setAutomationName("UiAutomator2");
        options.setAppPackage("com.rp.calculator");
        options.setAppActivity("com.rp.calculator.MainActivity");

        driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), options);
    }

2.现在我们先编写两条测试用例实例:

用例编号 用例名称 操作步骤 预期结果
Test_01 输入溢出,测试超长数字时是否截断或报错

1.点击7个9

2.点击*

3.点击10个9

4.点击=

9999999*9999999

=99999980000001

Test_02 零值处理,0参与的加减乘除

1. 0+983=

2. 0-983=

3. 983-0=

4. 0*3=

5. 12/0=

6. 0/12=

1.  983

2.  -983

3.  983

4.  0

5.  ∞

6.  0

下面我们用代码实现。我们发现,需要点击一个button很多次,我们可以把他写成一个方法。我们传入需要点击的数字就好,根据传入的数字不同,获取不同的xpath点击。

 // 通用点击方法(带等待)
    private void clickElement(By locator) {
        wait.until(ExpectedConditions.elementToBeClickable(locator)).click();
    }  


// 输入数字
    public void inputNumber(String number) {
        for (char c : number.toCharArray()) {
            String digit = String.valueOf(c);
           /* if (digit.equals(".")) {
                clickElement(By.id("com.rp.calculator:id/dec"));
            }*/
            clickElement(By.xpath("//android.widget.Button[@text=\"" + digit + "\"]"));
        }
    }
//测试代码 
@Test(priority = 1)
    public void test1() {
        //最大值
        for (int i = 0; i < 7; i++) {
            inputNumber("9");
        }
        driver.findElement(By.xpath("//android.widget.Button[@resource-id=\"com.rp.calculator:id/signButton\"]")).click();
        for (int i = 0; i < 9; i++) {
            inputNumber("9");
        }
        driver.findElement(By.id("com.rp.calculator:id/eql")).click();
        String expressionText = driver.findElement(By.id("com.rp.calculator:id/qusTv")).getText();
        String resultText = driver.findElement(By.id("com.rp.calculator:id/ansTv")).getText();
        
        Assert.assertEquals(expressionText,"9999999*9999999","输入值不符合");
        Assert.assertEquals(resultText,"99999980000001","输出结果不符合");
    }

上面为第一条用例的测试代码。我们可以给测试用例编priority=1。 我们已知输入框最大输入15个字符。 我们使用xpath元素定位到9,首先输入7个9,再点击*。最后输入9个9,如果有长度限制,实际只输入了7个9,再点击等于。

最后我们可以断言判断:

拿到输入框的文本,判断是否是9999999*9999999。如果是则PASS,否则提示输入值不符合

拿到输出结果文本,判断是否是99999980000001。如果是则PASS,否则提示输出结果不符合

下面我们来编写第二条测试用例,零值处理

我们看到用例有很多数据,可以创建一个参数化测试数据源,为测试方法提供多组输入数据和预期结果,从而实现一个测试方法自动执行多次不同的测试场景。

 // 数据提供者:生成多个测试用例
    @DataProvider(name = "calculationData3")
    public Object[][] provideCalculations() {
        return new Object[][]{
                {"0", "+", "983", "983"},
                {"0", "-", "983", "-983"},
                {"983", "-", "0", "983"},
                {"0", "×", "3", "0"},
                {"12", "÷", "0", "∞"},
                {"0", "÷", "2", "0"},
        };
    }

经过后面优化,发现加减乘除点击次数也比较多,我们也可以写成一个方法:

    // 输入运算符
    public void inputOperator(String operator) {
        String xpath;
        switch (operator) {
            case "+":
                xpath = "//android.widget.Button[@text=\"+\"]";
                break;
            case "-":
                xpath = "//android.widget.Button[@text=\"-\"]";
                break;
            case "×":
                xpath = "//android.widget.Button[@text=\"×\"]";
                break;
            case "÷":
                xpath = "//android.widget.Button[@text=\"÷\"]";
                break;
            default:
                throw new IllegalArgumentException("不支持的运算符: " + operator);
        }
        clickElement(By.xpath(xpath));
    }

最后编写我们的测试代码:

    @Test(dataProvider = "calculationData3", priority = 2)
    public void test3(String num1, String operator, String num2, String expectedResult) {
        inputNumber(num1);
        inputOperator(operator);
        inputNumber(num2);
        driver.findElement(By.id("com.rp.calculator:id/eql")).click();
        String expressionText = driver.findElement(By.id("com.rp.calculator:id/qusTv")).getText();
        String resultText = driver.findElement(By.id("com.rp.calculator:id/ansTv")).getText();

        Assert.assertEquals(expressionText,expectedResult,"输入值不符合");
        Assert.assertEquals(resultText,expectedResult,"输出结果不符合");
    }

现在我们的自动化测试用例编写完毕了,总共写了两条,后续同学们也可以自己再完善,下面附上完整的源码和测试结果。

完整代码

package org.example;

import io.appium.java_client.AppiumDriver;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.options.UiAutomator2Options;
import org.example.util.CalculatorUtil;
import org.example.util.WelcomeUtil;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;

public class demoTest {
    private AppiumDriver driver;
    private static final int TIMEOUT = 10; // 等待超时时间(秒)
    private WebDriverWait wait;

    @BeforeTest
    public void setUp() throws MalformedURLException {
        //建立连接
        UiAutomator2Options options = new UiAutomator2Options();
        options.setPlatformVersion("13");
        options.setDeviceName("192.168.10.104:5555");
        options.setAutomationName("UiAutomator2");
        options.setAppPackage("com.rp.calculator");
        options.setAppActivity("com.rp.calculator.MainActivity");

        driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(TIMEOUT));
    }

    // 通用点击方法(带等待)
    private void clickElement(By locator) {
        wait.until(ExpectedConditions.elementToBeClickable(locator)).click();
    }

    public void inputNumber(String number) {
        for (char c : number.toCharArray()) {
            String digit = String.valueOf(c);
           /* if (digit.equals(".")) {
                clickElement(By.id("com.rp.calculator:id/dec"));
            }*/
            clickElement(By.xpath("//android.widget.Button[@text=\"" + digit + "\"]"));
        }
    }


    @Test(priority = 1)
    public void test1() {
        //最大值
        for (int i = 0; i < 7; i++) {
            inputNumber("9");
        }
        driver.findElement(By.xpath("//android.widget.Button[@resource-id=\"com.rp.calculator:id/signButton\"]")).click();
        for (int i = 0; i < 9; i++) {
            inputNumber("9");
        }
        driver.findElement(By.id("com.rp.calculator:id/eql")).click();
        String expressionText = driver.findElement(By.id("com.rp.calculator:id/qusTv")).getText();
        String resultText = driver.findElement(By.id("com.rp.calculator:id/ansTv")).getText();

        Assert.assertEquals(expressionText, "9999999×9999999", "输入值不符合");
        Assert.assertEquals(resultText, "99999980000001", "输出结果不符合");
    }


    // 输入运算符
    public void inputOperator(String operator) {
        String xpath;
        switch (operator) {
            case "+":
                xpath = "//android.widget.Button[@text=\"+\"]";
                break;
            case "-":
                xpath = "//android.widget.Button[@text=\"-\"]";
                break;
            case "×":
                xpath = "//android.widget.Button[@text=\"×\"]";
                break;
            case "÷":
                xpath = "//android.widget.Button[@text=\"÷\"]";
                break;
            default:
                throw new IllegalArgumentException("不支持的运算符: " + operator);
        }
        clickElement(By.xpath(xpath));
    }

    // 数据提供者:生成多个测试用例
    @DataProvider(name = "calculationData3")
    public Object[][] provideCalculations() {
        return new Object[][]{
                {"0", "+", "983", "983"},
                {"0", "-", "983", "-983"},
                {"983", "-", "0", "983"},
                {"0", "×", "3", "0"},
                {"12", "÷", "0", "∞"},
                {"0", "÷", "2", "0"},
        };
    }

    @Test(dataProvider = "calculationData3", priority = 2)
    public void test3(String num1, String operator, String num2, String expectedResult) {
        inputNumber(num1);
        inputOperator(operator);
        inputNumber(num2);
        driver.findElement(By.id("com.rp.calculator:id/eql")).click();
        String expressionText = driver.findElement(By.id("com.rp.calculator:id/qusTv")).getText();
        String resultText = driver.findElement(By.id("com.rp.calculator:id/ansTv")).getText();

        Assert.assertEquals(resultText, expectedResult, "输出结果不符合");
    }


    @AfterTest
    public void tearDown() {
        //断开连接
        driver.quit();
    }
}

测试结果

appium+Java实现自动化测试最新教程及实战_第3张图片

总结

上面就是Appium+Java的实战例子了。我们从环境搭建--->认识基本框架--->编写测试用例--->实现自动化测试脚本。相信大家有了个基础的了解。但是这些还是不够的,后面我还会讲解生成测试报告,滑动操作等。

你可能感兴趣的:(测试,Java,java,appium,自动化,pytest)