文章目录

  • 1 前言
  • 2 什么是Appinum?
  • 3 环境准备
    • 3.1 设置JDK变量
    • 3.2 设置Android环境
      • 3.2.1 windows
      • 3.2.2 Mac环境
    • 3.3 下载Appium工具
    • 3.4 下载Appium Inspector工具
    • 3.5 手机需要开启调试模式
  • 4 启动Appium服务
  • 5 连接Appinum服务
    • 5.1 使用命令行连接
    • 5.2 使用`Appium Inspector`工具连接
  • 6 常用命令
    • 6.1 查看是否连接成功
    • 6.2 进程占用问题
    • 6.3 通过命令获取app自动化核心参数
  • 7 Appium定位元素的几种方法总结
  • 8 应用测试案例
    • 8.1 dingDing测试案例
    • 8.2 studyEnhanceCountry测试案例

1 前言

之前有些app,笔者进行学习任务时需要签到什么的,就想着能不能使用程序自动化的方式,代替我去进行操作,因为那些操作每天重复,也没有什么意义。最近几天使用Appinum进行简单任务的自动化测试时,刚好遇到了一些坑,这里记录下,方便以后再次遇到。

2 什么是Appinum?

  • Appium是c/s架构的,Appium是基于webdriver协议添加了对移动设备自动化api扩展而成的, webdriver是基于http协议的,第一次连接会建立一个session会话,并通过post发送一个json告知服务端相关测试信息 。

  • Appium会首先开启一个监听4723端口的server,接收测试脚本发送过来的对应请求,再将对应的请求发送给中间件Bootstrap.jar(比如点击一个App中的一个Button就是一条请求)

  • Bootstrap.jar
    监听4724端口由Appium发送过来的相关请求,并且将请求转换成UiAutomator可以识别的命令发给UiAutomator进行处理

3 环境准备

这个Appinum需要的环境还是蛮多的,在进行自动化测试之前,还是尽可能多的把环境准备下

3.1 设置JDK变量

这个比较常见基础变量,没有此环境的自行百度哈

注: 如果没有node也可以进行appinum测试,就不需要安装node,如果有问题就把node也装一下,因为笔者本身就有node环境,不确定node环境会不会有影响

3.2 设置Android环境

3.2.1 windows

既然时进行App自动化测试,那肯定需要android运行环境的,笔者为了方便,使用的Android Studio下的SDK环境

  • 新增系统变量ANDROID_HOME,设置Android环境变量,具体以自己实际安装的SDK路径为准
    C:\Users\26310\AppData\Local\Android\Sdk

  • 编辑path,新建以下2个变量
    %ANDROID_HOME%\tools
    %ANDROID_HOME%\platform-tools

3.2.2 Mac环境

vim ~/.bash_profile
source ~/.bash_profile
source ~/.zshrc(mac默认为该位置,如果使用的bash_profile,且退出命令终端窗口maven命令失效,需要在该zshrc内容里面加载source ~/.bash_profile)

vim ~/.zshrc
source ~/.zshrc

#andoid环境
ANDROID_HOME=/Users/xxx/Library/Android/sdk
export ANDROID_HOME
export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools

3.3 下载Appium工具

多系统下载地址: https://github.com/appium/appium-desktop/releases/tag/v1.22.2

Windows系统:直接点击下载

3.4 下载Appium Inspector工具

下载地址: https://github.com/appium/appium-inspector/releases/tag/v2022.2.1

3.5 手机需要开启调试模式

一般情况是,设置里面,手机版本号多次点击5~10次,就会开启开发者模式

4 启动Appium服务

  • 基础配置信息如下,点击Start Server即可启动:

  • 出现如下界面,说明启动成功

5 连接Appinum服务

打开手机,使用数据线连接电脑,开启手机开发者调试模式(也可以使用模拟器)

5.1 使用命令行连接

在cmd命令行中输入可以简单连接:adb connect 127.0.0.1:4723

5.2 使用Appium Inspector工具连接

  • 核心参数如下:

  • 核心参数说明:
    appium:deviceName,标识手机的设备名称,这个可以通过adb devices获取
    appium:platformName,标识系统平台名称,常见的有AndroidIOS
    appium:platformVersion,设备版本号

    注:在使用Appium Inspector连接时可能会报以下错误,所以如果需要使用Appium Inspector,推荐使用使用Appium客户端来进行启动,开启跨域请求:
    Could not connect to server; are you sure it's running? If you are using the browser version, also ensure your Appium server has been started with --allow-cors.

  • 如果连接失败,还可以使用模拟器代替
    比如说开夜神模拟器,打开设置,调成手机开发者模式,初次进入的话,进入设置,点击版本号5次,可以激活使用开发者模式,进入后打开USB调试功能

  • 连接成功界面如下:

6 常用命令

6.1 查看是否连接成功

  • 在cmd中输入以下命令:
    adb devices (-l)

  • 获取设备安装的所有包名列表,需要找一下下~
    adb shell pm list package
    adb shell pm list package | findStr jingdong

注:此种方式适合简单的adb(android debug brige)操作,如果复杂的操作,还是建议使用Appium Inspector连接

6.2 进程占用问题

如果重新启动Appium时提示,address already in user 127.0.0.1:port,可以杀掉进程重启

  • Windows系统杀掉进程:

    端口被占用的查找与kill进程(62001为查找的端口号)
    netstat -aon | findstr 62001
    杀掉进程
    taskkill -f -pid 进程号

  • Mac系统杀掉进程:

    查看端口号
    lsof -i tcp:4723
    杀掉进程
    sudo kill -9 29443

6.3 通过命令获取app自动化核心参数

  • 通过adb shell,获取Desired Capabilities需要的核心参数appPackageappActivity,而不同的app ,也会有不同的Activity和Package

    adb shell dumpsys window w | findstr \/ | findstr name=

  • 其他核心参数,通过手机,设置里面查看即可
    deviceName,标识手机的设备名称,这个可以通过adb devices获取
    platformName,标识系统平台名称,常见的有AndroidIOS
    platformVersion,设备版本号

7 Appium定位元素的几种方法总结

这个可以参考写的比较详细的一篇博文:https://blog.csdn.net/lovedingd/article/details/111058898

8 应用测试案例

以下测试案例,笔者基于Python语言 3.10 版本实现,当然了,Java语言,以及其他语言也是可以的

8.1 dingDing测试案例

自动化测试一个钉钉打卡的场景,代码示例如下:

#!/usr/bin/python3
# coding=utf-8import json
import os
import sys
import timefrom appium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWaitdef android_driver():desired_caps = {"deviceName": "D3Hxxxxxxxxxx","platformName": "Android","platformVersion": "10.0",# 与工具连接时间"newCommandTimeout": 3600,'appPackage': 'com.alibaba.android.rimet','appActivity': '.biz.LaunchHomeActivity',# 不重置,appium1.6以后的版本需要这个设置才可以保存app的登录状态'noReset': 'True',"connectHardwareKeyboard": True,'automationName': "UiAutomator2"}driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)print(json.dumps(desired_caps))return driverdef open_app():try:# 连接手机driver = android_driver()# 等待界面完全加载完成(3秒)driver.wait_activity("com.alibaba.android.rimet.biz.LaunchHomeActivity", 3)return driverexcept:print("打开手机app时异常,异常原因:", sys.exc_info()[0])raisedef awake_phone():# 在adb shell中,有一个经常使用的命令,模拟唤醒屏幕功能按键输入os.system("adb shell input keyevent 224")# 向上滑动屏幕os.system("adb shell input swipe 200 150 200 650")def do_login(driver):WebDriverWait(driver, 20, 1).until(lambda x: x.find_elements(by=By.ID, value='com.android.systemui:id/row1'))rowZero = driver.find_elements(by=By.ID, value='com.android.systemui:id/row2')colOne = rowZero[0].find_element(by=By.ID, value='com.android.systemui:id/key2')colThree = rowZero[0].find_element(by=By.ID, value='com.android.systemui:id/key4')rowTwo = driver.find_elements(by=By.ID, value='com.android.systemui:id/row3')colTwoThree = rowTwo[0].find_element(by=By.ID, value='com.android.systemui:id/key8')colOne.click()colTwoThree.click()colTwoThree.click()colThree.click()# print(driver.find_element(by=By.ID, value='com.android.systemui:id/pinEntry').text())def da_ka():# 工作台list = driver.find_elements(by=By.ID, value='com.alibaba.android.rimet:id/home_app_item')list[2].click()# 显示等待加载,超时时间为20s,每隔1秒搜索一次元素是否存在,如果元素存在返回定位对象并退出search_button = WebDriverWait(driver, 20, 1).until(lambda x: x.find_elements(by=By.XPATH,value='(//*[@resource-id="__react-content"]//android.view.View[@text="考勤打卡"])'))el1 = driver.find_elements(by=By.XPATH,value='(//*[@resource-id="__react-content"]//android.view.View[@text="考勤打卡"])')el1[1].click()# 定位等待5秒time.sleep(5)el2 = driver.find_element(by=By.XPATH,value='(//*[@resource-id="__react-content"]//android.view.View[@text="上班打卡"])')el2.click()driver.quit()if __name__ == '__main__':driver = open_app()awake_phone()# 数字解锁登录do_login(driver)try:da_ka()except:print("打卡异常,异常原因:", sys.exc_info()[0])raise

8.2 studyEnhanceCountry测试案例

自动化测试一个studyEnhanceCountry阅读新闻的场景,代码示例如下:

#!/usr/bin/python3
# coding=utf-8
import json
import os
import sys
import timefrom selenium.webdriver.support.wait import WebDriverWait
from appium import webdriver
# For W3C actions
# 滑动手机
from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.common.by import By'''desired_caps = {"deviceName": "D3XXXXXXXXXXX","platformName": "Android","platformVersion": "10.0",# 与工具连接时间"newCommandTimeout": 3600,# 在Android真机上跑自动化脚本时,发现在启动App时报java.lang.SecurityException: Permission Denial: starting Intent,因为配置中的appActivity并不是App启动时最先加载时的Activity, 所以Appium无法启动App'appPackage': 'com.ehai','appActivity': '.view.oldview.activity.LoadingActivity',# 如果指定了 appWaitPackage 和 appWaitActivity,Appium 将自动等待,直到这些Activity启动'appWaitPackage': 'com.huawei.android.launcher','appWaitActivity': 'com.huawei.android.launcher.unihome.UniHomeLauncher',# 不重置,appium1.6以后的版本需要这个设置才可以保存app的登录状态'noReset': 'True',"connectHardwareKeyboard": True,# appWaitDuration   Timeout in milliseconds used to wait for the appWaitActivity to launch (default 20000)'appWaitDuration': 5000,'automationName': "UiAutomator2"} '''# 阅读消息,时长控制,单位s
timeControl = 65def android_driver():desired_caps = {"deviceName": "D3H5xxxxxxxxxx","platformName": "Android","platformVersion": "10.0",# 与工具连接时间"newCommandTimeout": 3600,'appPackage': 'cn.xuexi.android','appActivity': 'com.alibaba.android.rimet.biz.SplashActivity',# 不重置,appium1.6以后的版本需要这个设置才可以保存app的登录状态'noReset': 'True',"connectHardwareKeyboard": True,# 'automationName': "UiAutomator2"}driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)print(json.dumps(desired_caps))return driverdef open_app():try:# 连接手机driver = android_driver()# 等待界面完全加载完成(8秒)driver.wait_activity("com.alibaba.android.rimet.biz.SplashActivity", 8)# 等待app加载2秒time.sleep(2)return driverexcept:print("打开手机app时异常,异常原因:", sys.exc_info()[0])raisedef watch_channel_new(driver, str_channel):WebDriverWait(driver, 20, 1).until(lambda x: x.find_elements(by=By.XPATH, value=str_channel))el2 = driver.find_element(by=AppiumBy.XPATH, value=str_channel)el2.click()# 等待数据加载2秒time.sleep(2)# 组合定位,获取某个频道的,部分新闻列表new_list = "//*[@resource-id='cn.xuexi.android:id/general_card_title_id' and @package='cn.xuexi.android']"search_button = WebDriverWait(driver, 20, 1).until(lambda x: x.find_elements(by=By.XPATH, value=new_list))el3 = driver.find_elements(by=By.XPATH, value=new_list)for i in range(len(el3)):el3[i].click()time.sleep(5)# 向下滑动,选中部分阅读内容# swip = SwipeOperate(driver)# swip.swipe_to_bottom(0.75, 10)# KEYCODE_PAGE_UP 向上翻页键 92# os.system("adb shell input keyevent 92")# KEYCODE_PAGE_DOWN 向下翻页键 93os.system("adb shell input keyevent 93")time.sleep(5)# 阅读内容65秒time.sleep(timeControl - 10)driver.back()def watch_new(driver):# header = driver.find_element_by_id("com.ss.android.article.lite:id/ayv")# list = header.find_elements_by_class_name("android.widget.TextView")# list = header.find_elements_by_xpath("//*[@resource-id='com.ss.android.article.lite:id/bb'][@clickable='true']")# 显示等待加载,超时时间为20s,每隔1秒搜索一次元素是否存在,如果元素存在返回定位对象并退出search_button = WebDriverWait(driver, 20, 1).until(lambda x: x.find_elements(by=By.ID, value='cn.xuexi.android:id/home_bottom_tab_icon_large'))# 学习中心el1 = driver.find_elements(by=By.ID, value='cn.xuexi.android:id/home_bottom_tab_icon_large')el1[0].click()# 要闻频道-精确定位new_channel = "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.LinearLayout/android.widget.FrameLayout[2]/android.widget.FrameLayout[1]/android.support.v4.view.ViewPager/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.LinearLayout/android.view.ViewGroup/android.widget.LinearLayout[2]/android.widget.TextView"watch_channel_new(driver, new_channel)# 新思想频道-精确定位new_opinion_channel = "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.LinearLayout/android.widget.FrameLayout[2]/android.widget.FrameLayout[1]/android.support.v4.view.ViewPager/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.LinearLayout/android.view.ViewGroup/android.widget.LinearLayout[3]/android.widget.TextView"watch_channel_new(driver, new_opinion_channel)def awake_phone():# 唤醒屏幕,在adb shell里有一个非常使用的命令,模拟功能按键输入os.system("adb shell input keyevent 224")def watch_video(driver):# 电视台el1 = driver.find_elements(by=By.ID, value='cn.xuexi.android:id/home_bottom_tab_button_contact')el1[0].click()# video list 精确定位video_element = "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.LinearLayout/android.widget.FrameLayout[2]/android.widget.FrameLayout[1]/android.support.v4.view.ViewPager/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout/android.widget.FrameLayout[2]/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.ListView/android.widget.FrameLayout"search_button = WebDriverWait(driver, 20, 1).until(lambda x: x.find_elements(by=AppiumBy.XPATH, value=video_element))videoList = driver.find_elements(by=AppiumBy.XPATH, value=video_element)for i in range(len(videoList)):videoList[i].click()# 阅读内容65秒time.sleep(timeControl)driver.back()if __name__ == '__main__':awake_phone()driver = open_app()# 查看文章消息watch_new(driver)# 切换其他app测试# driver.start_activity('com.ehai', '.view.oldview.activity.LoadingActivity')# 试听学习watch_video(driver)# 退出appdriver.quit()

好啦,本篇内容就简单介绍到这里了,虽然是个入门教程,但是笔者还是很辛苦的,踩了很多的坑,花费了一天多才搞出来,有需要的老铁们,可以白嫖了~

如果这篇内容对你有帮助,欢迎老铁三连击,先点赞,关注,加收藏,然后再看~

Appinum 自动化测试利器入门相关推荐

  1. Android自动化测试-从入门到入门(5)AdapterView的测试

    在之前的文章中,我们简单介绍了Espresso的使用.通过onView()方法我们可以快速定位到界面上我们需要测试的目标元素.整体来说,onView()比较适用于UI比较简单的情况,在不需要过于复杂的 ...

  2. 【学习笔记】HttpRunner自动化测试框架入门

    HttpRunner自动化测试框架入门 文章目录 设计思想和理念 一.Httprunner环境搭建 可以用相关命令**直接生成对应的项目文件夹** 二.Httprunner五个命令 三.一分钟生成用例 ...

  3. 史上最全的MonkeyRunner自动化测试从入门到精通(1)

    史上最全的MonkeyRunner自动化测试从入门到精通(1) 史上最全的MonkeyRunner自动化测试从入门到精通(2) 史上最全的MonkeyRunner自动化测试从入门到精通(3) 史上最全 ...

  4. 11小时 python自动化测试从入门到_从设计到开发Python接口自动化测试框架实战,资源教程下载...

    课程名称 从设计到开发Python接口自动化测试框架实战,资源教程下载 课程简介: 课程从接口基础知识入门,从抓包开始,到接口工具的运用,再到常见接口库.接口开发.Mock服务.unittest框架的 ...

  5. element 登录_Python selenium自动化测试框架入门实战--登录测试案例

    本文为Python自动化测试框架基础入门篇,主要帮助会写基本selenium测试代码又没有规划的同仁. 本文应用到POM模型.selenium.unittest框架.configparser配置文件. ...

  6. web 自动化测试(入门篇)

    自动化测试入门篇 本次实现自动化是用python语言进行实现,所以需要有一点python基础,其实python还是比较简单入门的,下面开始. 安装python,我安装的是最新版本的python,传送门 ...

  7. 零基础入门python web 自动化测试_python web自动化测试,入门篇

    自动化测试入门篇 本次实现自动化是用python语言进行实现,所以需要有一点python基础,其实python还是比较简单入门的,下面开始. 安装完毕之后,设置环境变量属性,这样可以全局操作pytho ...

  8. 11小时 python自动化测试从入门到_自动化测试实战宝典(Robot Framework+Python从小工到专家)...

    目录 第1部分 入门篇 第1章 大话测试行业 1.1 测试行业现状分析 1.2 未来发展趋势 1.3 测试工程师的核心竞争力 1.4 测试知识体系 1.5 测试发展能力图谱及推荐书单 1.6 本章总结 ...

  9. python自动化测试登录_Python selenium自动化测试框架入门实战--登录测试案例

    本文为Python自动化测试框架基础入门篇,主要帮助会写基本selenium测试代码又没有规划的同仁. 本文应用到POM模型.selenium.unittest框架.configparser配置文件. ...

最新文章

  1. 【队列源码研究】消息队列beanstalkd源码详解
  2. iOS中responseToSelector()方法是不是需要优化
  3. npm 查看当前生效的配置
  4. 慢雾安全工程师:安全审计是目前保护 DeFi 项目安全最高性价比的方式
  5. Fedora升级后Python虚拟环境中的pip报错
  6. 在VC中使用Delphi构造公共对话框
  7. ffmpeg对H.264进行rtp打包
  8. 如何激发孩子的想象力_如何培养孩子想象力
  9. 谭浩强C语言练习题及详细答案
  10. python简明教程电子书下载_python简明教程中文pdf下载-Python入门级电子书完整免费版-东坡下载...
  11. 宗成庆统计自然语言处理第二版第13章读书笔记-文本分类与情感分类
  12. 全能电子地图下载器-获取离线地图瓦片的工具
  13. wordpress 百度主动推送 PHP,WordPress 百度自动推送插件
  14. 如何用matlab求解多变量非线性回归,matlab多元非线性回归教程
  15. Bounds和Frame简介
  16. Java发送短信验证码
  17. (有趣)把文字隐藏到图片中
  18. 1.6 FPGA电路设计
  19. MOV PC, LR解析
  20. 列主元素消去法的Matlab实现

热门文章

  1. 用Python爬取并分析Box Office Mojo网站2019年每日票房数据
  2. python江红余青松_python上机实践重点代码江红余青松版
  3. 程序员如何从技术岗转为技术管理层
  4. [Leetcode学习-c++java]Count Sorted Vowel Strings
  5. 高数知识点整理——有理分式的不定积分(多项式的除法)
  6. php怎么显示gif图片,如何让伪进度条在页面上显示成gif图像
  7. 【3】Maxwell轴向电机“单边磁拉力”仿真设置
  8. DICOM:开源DICOM服务框架DCM4CHE 安装
  9. 3D EXPERIENCE DraftSight的协作能力
  10. vue项目启动报错Cannot find module ‘xxx’