一种很轻松的Excel关键字方式进行Android端APP自动化测试(Java+Appium+TestNG+Excel)

说明


本次分享Android端APP自动化测试Excel执行逻辑,整体逻辑与Web端类似,没看过的读者可看这里 =========>>
一种很轻松的Excel关键字方式进行网页Web自动化测试(Java+Selenium+TestNG+Excel)

当然也存在差异的部分,本文会详细介绍该部分------------------(PS:作者使用版本appium框架 java版本8.0.0)

可能小伙伴会有疑问,整体框架看着可能有点臃肿(cn.nhdc.cloud.testscripts包下为测试脚本部分),代码不够简洁。

  • 那是因为:
      *设计之初,为提供测试人员一种只专注业务逻辑测试代码,快捷开发测试脚本(testcase)又同时加强代码可读性,case高可维护性的一种方案,同时考虑不同应用设备端、不同类型的测试,提供统一的一套框架。但前景美好,现实很残酷。。。跑题了
    ,总而言之,为了能快速落地,形成了目前这套框架,即不是专门为了Excel测试设计的,是为了多种形式调用测试及扩展开发设计的,so… **

  总之,就在此基础上,提供Excel执行测试的一种方案,同时结合EasyExcel工具提供用户快速编辑测试用例,整体形成一个闭环且相对便利的App/Web自动化测试解决方案

  - 文章作者:@随心自然fqc , 转载时,请注明来源,注明作者,这是对文章作者的尊重,也是对知识的尊重。

整体图解


整体图解

主要内容
1、测试调用方式

与Web类型调用一致,同时testUseBaseMethod(username,password)调用基类关键字操作方法。

import cn.nhdc.cloud.modules.casemanage.model.vo.TestCaseVo;
import cn.nhdc.cloud.testscripts.config.AppiumCapabilities;
import cn.nhdc.cloud.testscripts.config.LocateType;
import cn.nhdc.cloud.testscripts.listener.ExtentTestNGIReporterListener;
import cn.nhdc.cloud.testscripts.testcase.base.AndroidTestBase;
import org.testng.annotations.Listeners;
import org.testng.annotations.Optional;
import org.testng.annotations.Test;

import java.util.List;

/**
 * Android类型 Excel执行方式 自动化测试demo <br>
 * Method 1 :  {@link #testExcelExcute}  正向逻辑执行  <br>
 * Method 2 : {@link #testExcelInvokeExcute}  反射逻辑执行  <br>
 * Method 3 : {@link #testUseBaseMethod}  同时可调用基类方法  <br>
 *
 * ps: 以上2种方式 原理不同 但执行效果类似 具体选择哪种取决于调用者意愿
 * 
 * @author Fan QingChuan
 */

@Test(description = "Excel方式自动化测试示例-正向逻辑&反射执行逻辑")
@Listeners(value = ExtentTestNGIReporterListener.class)
public class ExcelAndroidTestDemo extends AndroidTestBase {

    @Test(description = "正向逻辑: 操作方法封装在 AndroidTestBase 中, 测试用例中可直接调用  解析Excel -> caseSteps 根据遍历操作编码switch执行各项操作")
    void testExcelExcute(
            @Optional("C:\\Users\\allen\\Desktop\\自动化测试_测试用例_2022_07_04_150350_623.xlsx") String fileName,
            @Optional("testcase")String sheetName,@Optional("null")Integer headerRowNumber) {

        List<TestCaseVo> caseVoList = analysisExcelUiCase(fileName, sheetName, headerRowNumber);
        excuteExcelUiTest(caseVoList);
    }


    @Test(description = "反射逻辑: 操作封装在 AndroidCommon 通过 AndroidTestBase 中反射获取 AndroidBasePage.class 并实例化 再根据操作编码+分类枚举 获取对应方法 并反射(invoke)执行测试")
    void testExcelInvokeExcute(
            @Optional("C:\\Users\\allen\\Desktop\\自动化测试_安卓APP类型测试用例_2022_07_08_133321_663.xlsx") String fileName,
            @Optional("testcase")String sheetName,@Optional("null")Integer headerRowNumber)
            throws  IllegalAccessException, InstantiationException {

        List<TestCaseVo> caseVoList = analysisExcelUiCase(fileName, sheetName, headerRowNumber);
        invokeExcelUiTest(caseVoList);
    }


    @Test
    void testUseBaseMethod(@Optional("ATE002")String username,@Optional("a123456")String password) {
        //开启Appium服务
        startDefaultBaseService();
        //初始化AndroidDriver
        initBaseAndroidDriver(AppiumCapabilities.getHarmonyJx());
        //点击同意隐私协议
        clickNegatively(LocateType.ID,"cn.newhope.qc:id/tv_privacy_agree");
        //输入用户名
        inputText(LocateType.ID,"cn.newhope.qc:id/etAccount",username);
        //输入密码
        inputText(LocateType.ID,"cn.newhope.qc:id/etPassword",password);
        //点击勾选同意隐私政策
        click(LocateType.ID,"cn.newhope.qc:id/protocolCb");
        //点击登录
        click(LocateType.ID,"cn.newhope.qc:id/btnLogin");
        //断言toast
        assertToastHasAppeared(10,"toast消息文本");
    }

}
2、执行测试逻辑

整体执行逻辑与Web一致,只是在App自动化方面,Appium ,执行测试前需开启Appium服务(AppiumDriverLocalService),并实例化具体不同测试端的Driver。
  强烈建议:看过Web端相关逻辑再来看Android端 传送门 >> 网页Web端Excel自动化测试(Java+Selenium+TestNG+Excel)

  • 先来App通用的测试基类–AppTestBase,    主要提供创建/关闭Appium服务
import cn.hutool.core.util.ObjectUtil;
import cn.nhdc.cloud.modules.casemanage.model.vo.TestCaseVo;
import cn.nhdc.cloud.testscripts.config.ReportLog;
import cn.nhdc.cloud.testscripts.testcase.base.common.AppCommon;
import io.appium.java_client.service.local.AppiumDriverLocalService;
import io.appium.java_client.service.local.AppiumServerHasNotBeenStartedLocallyException;
import io.appium.java_client.service.local.flags.ServerArgument;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeSuite;

import java.net.URL;
import java.util.List;
import java.util.Map;

/**
 * App相关测试通用Base <br>
 * 继承该类需实现抽象方法-Excel执行测试方法 {@link AppTestBase#excuteExcelUiTest(List)} {@link AppTestBase#invokeExcelUiTest(List)}  <br>
 * 该类只提供AppiumDriverLocalService {@link AppTestBase#service} 不提供具体类型baseDriver  <br>
 * 即:
 * 测试case应早已明确该从事具体类型Driver的测试,应选择继承该类子类 {@link AndroidTestBase} 或 {@link IOSTestBase} 或其他
 *
 * @author Fan QingChuan
 * @since 2022/6/7 16:53
 */

public abstract class AppTestBase extends WebTestBase implements AppCommon {

    private static final ReportLog reportLog = new ReportLog(AppTestBase.class);

    public static final int TIME_OUT = 5;
    public static final int SLEEP_TIME = 300;
    public static final int DEFAULT_PORT = 4723;
    public static final String DEFAULT_IP = "127.0.0.1";

    protected AppiumDriverLocalService service;

    @Override
    public abstract void excuteExcelUiTest(List<TestCaseVo> caseVoList);

    @Override
    public abstract void invokeExcelUiTest(List<TestCaseVo> caseVoList) throws InstantiationException, IllegalAccessException;

    public void startDefaultBaseService() {

        try {
            service = buildDefaultAppiumService();      //创建默认的AppiumDriverLocalService
            checkPortAndKillTask(DEFAULT_PORT);         //检查并KILL端口进程任务 默认4723
            service.start();                            //开启服务
            reportLog.info("开启Appium本地服务 ========== >>  URL: {}",service.getUrl());
        } catch (AppiumServerHasNotBeenStartedLocallyException e) {
            e.printStackTrace();
        }finally {
            reportLog.info("检查服务是否正常运行 ========== >>  [{}]",service.isRunning());
        }
    }

    public void startCustomBaseService(int port, String ipAddress, Map<ServerArgument,String> arguments) {

        try {
            service = buildCustomAppiumService(port,ipAddress,arguments);               //根据配置创建AppiumDriverLocalService
            checkPortAndKillTask(port);
            service.start();
            reportLog.info("开启Appium本地服务 ========== >>  URL: [{}]",service.getUrl());
        } catch (AppiumServerHasNotBeenStartedLocallyException e) {
            e.printStackTrace();
        }finally {
            reportLog.info("服务是否正常开启 ========== >>  [{}]",service.isRunning());
        }
    }

    public URL getServiceUrl() {
        if (service.isRunning()) {
            return service.getUrl();
        }else {
            throw new RuntimeException("AppiumDriverLocalService service 未启动!");
        }
    }

    protected void closeBaseAppium
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值