软测入门(四)Appium-APP移动测试基础
Appium
用来测试手机程序。
测试方面:
- 功能测试
- 安装卸载测试
- 升级测试
- 兼容测试
- Android系统版本
- 不同分辨率
- 不同网络
- 网络切换、中断测试
- 使用中来电话、短信
- 横竖屏切换
环境搭建
- Java安装(查资料)
- Android SDK安装,配置 HOME和PATH(下载安装Android SDK)
- 虚拟机安装(夜神模拟器或者使用真机打开调试功能),完毕后将Android SDK中的adb替换掉虚拟机里的
adb
和nox_adb
Appium自动化测试工具
- 安装appnium的程序后,确定Java和Andriod的HOME配置了,然后点start即可
-
在python中安装
Appium-Python-Client
pip install Appium-Python-Client
ADB
会在电脑上创建一个服务(ADB服务),手机连接电脑后,会与服务建立连接,要想发送指令给手机,需要把指令发送到ADB服务中,然后转发给手机。
ADB: Android Debug Bridge,安卓调试桥。通过命令操作手机。
打开模拟器,然后adb devices
可查看连接到的手机。
常用的终端命令:
-
服务开启关闭
# 关闭 adb kill-server # 开启 adb start-server
-
查看设备
adb devices
-
进入手机终端
adb shell
-
获取信息
# 手机版本信息 adb shell getprop ro.build.version.release # 获取当前手机运行的程序和界面 adb shell dumpsys window | findstr mCurrentFocus
-
文件传输
# 发送文件到手机 adb push 电脑文件 手机位置 # 发送文件到电脑 adb pull 手机文件 电脑位置
入门案例
记得先把appium的包安装好 pip install Appium-Python-Client
手机或虚拟机可以先到一个页面,然后获取到必要的参数。
常见参数可见:python+appium实现自动化测试
import timefrom appium import webdriver# 连接手机设备 所必须的参数
desired_caps = {"platformName": "Android","deviceName": "127.0.0.1:62001", # 通过 adb devices命令获取"appPackage": "com.android.settings","appActivity": ".Settings", # 这里只取包名后面的内容即可"platformVersion":"7.1" # 7.1.2
}
# 获取到手机实例
driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_capabilities=desired_caps)time.sleep(10)
# 关闭app
driver.close_app()
# 释放资源
driver.quit()
原理
整体来讲就是自动化测试脚本(python、java等)执行后,发送给Appium
的服务器,服务器再去转发给设备;而转发给设置又需要用到了安卓的SDK相关的一些库(adb),然后再给安卓设备执行。
网上借个图
基础操作
-
driver
-
close_app() :关闭打开的应用
-
quit(): 断开连接
-
install_app(‘apk的在电脑的绝对路径’):安装应用
如果安装失败,有可能是AndroidSDK问题,或者安装的apk和手机不兼容,(比如可以试着下载个32位的看看)
可以提前看下手机的操作位数。
adb shell getprop ro.product.cpu.abi
driver.install_app(r"D:\environment\python-workspace\iBiliPlayer-bili.apk")
-
remove_app(‘应用包名’):卸载应用
-
page_source
:获取界面的xml源码 -
current_package:获取当前操作的包名
-
current_activity:获取当前操作的应用界面名称
-
is_app_installed(“包名”) : 是否已安装
-
-
element
- text:获取文本
- click() : 点击元素
- get_attrubute(‘属性名’) : 获取属性值
- location:获取元素左上角的坐标
- size: 获取元素宽高(字典)
el = driver.find_element(By.XPATH, "//*[@text='显示']") print(el.get_attribute("text")) print(el.text) print(el.size)
根据元素属性定位,及操作
driver.find_element(By.XPATH, "//*[@resource-id='com.android.settings:id/search']").click()time.sleep(1)
driver.find_element(By.XPATH, "//*[@resource-id='android:id/search_src_text']").send_keys("abc")driver.find_element(By.XPATH, "//*[@resource-id='android:id/search_src_text']").send_keys("张三")
多次调用send_keys()时,它会自己去删掉原内容,再输入
支持中文`:在老版本中send_keys()不支持中文,可以这么设置参数
{"unicodeKeyboard": True,"resetKeyboard": True
}
元素定位
打开Android SDK的tools中的uiautomatorviewer.bat
,点击设备屏幕快照,获取此App页面上的数据信息。
如果想要其他页面的数据,那么在App进入其他应用后,再次点击Device Screenshot
按钮即可。(本文中直接简称 DS
)
在DS中,节点细节中,所有的属性基本上都是重复的,可以根据text属性
来确定唯一定位。
# @creator by wlh
# @date 2023/3/1 17:56
import timefrom appium import webdriver# 连接手机设备 所必须的参数
from selenium.webdriver.common.by import Bydesired_caps = {"platformName": "Android","deviceName": "127.0.0.1:62001", # 通过 adb devices命令获取"appPackage": "com.android.settings","appActivity": ".Settings","platformVersion":"7.1" # 7.1.2
}
# 获取到手机实例
driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_capabilities=desired_caps)time.sleep(5)
# 需要注意:在Android中,text并不是文本,而是标签的属性 切记。。
driver.find_element(By.XPATH, "//*[@text='显示']").click()# 关闭app
driver.close_app()
# 释放资源
driver.quit()
滑动&拖拽
滑动
-
swipe(start_x, start_y, end_x, end_y, duration)
需要计算坐标
- duration默认600毫秒
driver.swipe(start_x=270, start_y=640, end_x=270, end_y=320)
如果要做到合理适配所有分辨率的手机,那么可以自己去计算即可。
get_window_size()
能够获取整个屏幕的宽高。 -
scroll(origin_el, destination_el) : 只需要原始元素和目标元素点即可
or_ = driver.find_element(By.XPATH, "//*[@text='通知']") des_ = driver.find_element(By.XPATH, "//*[@text='WLAN']") driver.scroll(origin_el=or_, destination_el=des_)
拖拽
找到两个元素即可。
el1 = driver.find_element(By.XPATH, "//*[@text='酷安']")
el2 = driver.find_element(By.XPATH, "//*[@text='抖音']")
driver.drag_and_drop(el1, el2)
高级模拟手势
TouchAction
类中的方法实现。
- press() 按下(参数既可以使用坐标,也可以是元素)
- release() 释放(可和press一起用,可以达到click的效果)
- move_to() 移动
- wait() 等待 press+wait=长按
- long_press() 长按
tap() 轻敲
可设置敲击的次数,比如双击perform()
执行,最后一定要写,否则设计的动作全都失效
高级手势实现 拖动
。
# @creator by wlh
# @date 2023/3/1 17:56
import timefrom appium import webdriver# 连接手机设备 所必须的参数
from appium.webdriver.common.touch_action import TouchAction
from selenium.webdriver.common.by import Bydesired_caps = {"platformName": "Android","deviceName": "127.0.0.1:62001", # 通过 adb devices命令获取"appPackage": "com.android.settings","appActivity": ".Settings","platformVersion": "7.1" # 7.1.2
}
# 获取到手机实例
driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_capabilities=desired_caps)el1 = driver.find_element(By.XPATH, "//*[@text='通知']")
el2 = driver.find_element(By.XPATH, "//*[@text='WLAN']")action = TouchAction(driver)# 按下
action.press(el1).wait(500).move_to(el2)
action.release()# 执行
action.perform()time.sleep(2)
# 关闭app
driver.close_app()
# 释放资源
driver.quit()
注意:拖动=press+wait+move。注意各种手势的合理搭配
设置图形密码案例
在安卓手机中,没有出现在手机屏幕中的元素,是不会被加载的。
最好在所有的页面跳转后都等一小段时间,因为代码执行速度很快,很有可能页面还没有加载好元素,代码就已经执行了,导致报错或者看不到理想的效果。
通过视图工具,确定各个点的坐标即可
# @creator by wlh
# @date 2023/3/1 17:56
import timefrom appium import webdriver
# 连接手机设备 所必须的参数
from appium.webdriver.common.touch_action import TouchAction
from selenium.webdriver.common.by import Bydesired_caps = {"platformName": "Android","deviceName": "127.0.0.1:62001", # 通过 adb devices命令获取"appPackage": "com.android.settings","appActivity": ".Settings","platformVersion": "7.1" # 7.1.2
}
# 获取到手机实例
driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_capabilities=desired_caps)action = TouchAction(driver)el1 = driver.find_element(By.XPATH, "//*[@text='声音']")
el2 = driver.find_element(By.XPATH, "//*[@text='WLAN']")action.press(el1).wait(500).move_to(el2).release()
# 开始执行
action.perform()time.sleep(1)
driver.find_element(By.XPATH, "//*[@text='安全']").click()time.sleep(1)
driver.find_element(By.XPATH, "//*[@text='屏幕锁定']").click()time.sleep(1)
driver.find_element(By.XPATH, "//*[@text='图案']").click()time.sleep(0.5)
# 按下位置 105 450
action.press(x=105, y=453).wait(200).move_to(x=270, y=453).wait(200).move_to(x=435, y=453).wait(200) \.move_to(x=270, y=615).wait(200) \.move_to(x=105, y=780).wait(200).move_to(x=270, y=780).wait(200).move_to(x=435, y=780)
action.release()
action.perform()time.sleep(2)
# 关闭app
driver.close_app()
# 释放资源
driver.quit()
Driver驱动的其他操作
- device_time 获取手机时间
- get_window_size() 获取屏幕宽高
- network_connection 获取手机网络信息
- set_network_connection() 设置网络信息
- keyevent(按键数字) 点击按键
- get_screenshot_as_file/save_screenshot(图片路径) : 截图
- open_notifications() 打开通知栏
# 手机时间
print(driver.device_time)# 屏幕宽高
print(driver.get_window_size())# 网络信息
print(driver.network_connection)# 打开通知栏
driver.open_notifications()# 截图
driver.get_screenshot_as_file("jietu.png")
相关文章:

软测入门(四)Appium-APP移动测试基础
Appium 用来测试手机程序。 测试方面: 功能测试安装卸载测试升级测试兼容测试 Android系统版本不同分辨率不同网络 网络切换、中断测试使用中来电话、短信横竖屏切换 环境搭建 Java安装(查资料)Android SDK安装,配置 HOME和P…...

华为OD机试用Python实现 -【集五福】 |老题且简单
华为OD机试题 最近更新的博客华为 OD 机试 300 题大纲集五福题目描述输入描述输出描述示例一输入输出示例二输入输出代码编写思路Python 代码最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典...

Typro使用以及安装教程来啦
Typora是一款轻便简洁的Markdown编辑器,支持即时渲染技术,这也是与其他Markdown编辑器最显著的区别。即时渲染使得你写Markdown就想是写Word文档一样流畅自如,不像其他编辑器的有编辑栏和显示栏。今天为大家分享下有关Typroa的安装以及使用&a…...

武汉凯迪正大KD305系列智能数字绝缘电阻测试仪
一、概述 KD305系列智能数字绝缘电阻测试仪采用嵌入式工业单片机实时操作系统,数字模拟指针与数字段码显示结合,该系列表具有多种电压输出等级(500V、1000V、2500V、5000V、10000V)、容量大、抗干扰强、模拟指针与数字同步显示、交…...

如何使用码匠连接 Redis
目录 在码匠中集成 Redis 在码匠中使用 Redis 关于码匠 Redis 是由 Salvatore Sanfilippo 用 C 语言开发的一款开源的、高性能的键值对存储数据库,它采用 BSD 协议,为了适应不同场景下的存储需求,提供了多种键值数据类型。到目前为止&…...
防止网络攻击的10大网络安全措施
网络攻击每天都在发生。事实上,每天有超2000次的攻击是针对连接了互联网且未受保护的系统,大概每39s就会发生一次。网络攻击导致的数据泄露、敏感信息被盗、财务损失、声誉受损都给企业及个人带来威胁。随着各大企业对数字系统的依赖,网络威胁已成为当下面临的主要挑战。 实…...
LeetCode 面试题 05.02. 二进制数转字符串
【LetMeFly】面试题 05.02.二进制数转字符串 力扣题目链接:https://leetcode.cn/problems/bianry-number-to-string-lcci/ 二进制数转字符串。给定一个介于0和1之间的实数(如0.72),类型为double,打印它的二进制表达式…...

[MatLab]图像绘制
一、绘制二维图像 1.一张图上绘制一条线 绘制代码如下面所示: x 0:0.01:2*pi; y sin(x); figure %建立幕布 plot(x,y) %绘制图像 %设置图像属性 title(ysin(x)) xlabel(x) ylabel(y)xlim([0 2*pi]) %限制x轴的值域 自定义图线的颜色…...

datax导入到hive的数据量翻倍
现象 mysql->hive 或者oracle->hdfs 源表数据100w 结果hive表数据200w。 这个现象很容易发生,只要你同一时间调度这个json两次。 原因 "writeMode" : "append", "nonconflict","truncate" * appendÿ…...

拿下3个大厂offer的软件测试面试宝典,面试一文搞定
我是谁、工作几年、你上家公司做什么、负责什么、你的优势、为什么适合这个职位、我想做什么、在这个职位上想得到什么 【呕心沥血】耗时7天整理的金三银四必看的软件测试频面试题 涵盖 接口自动化测试框架面试题_哔哩哔哩_bilibili【呕心沥血】耗时7天整理的金三银四必看的软…...

长短记忆神经网络(LSTM,Long Short-Term Memory)
长短记忆神经网络定义 长短记忆神经网络(Long-short term memory, LSTM)是一种特殊的RNN结构。该神经网络可以有效保留历史信息,实现对文本的长期依赖信息进行学习。 关键问题:控制长期状态信息 解决方法:门控开关 门的…...
Makefile学习2
自动变量和通配符 * 通配符 * 和 % 在Make 中都被称为通配符,但他们的含义完全不同。 * 会在你的文件系统中搜索匹配的文件名。可以在目标,先决条件或 wildcard 函数中使用。 print:$(wildcard *.c)ls -la $?wildcard 作用:在 Makefile 规…...

【字符串】leetcode28. 实现 strStr()(C/C++/Java/Python/Js)
leetcode28. 实现 strStr() 1 题目2 KMP2.1 什么是KMP?2.2 KMP有什么用?2.3 什么是前缀表?2.4 最长公共前后缀2.5 为什么一定要用前缀表?2.6 如何计算前缀表2.7 前缀表与next数组2.8 使用next数组来匹配2.9…...

游戏开发是个“坑”,而且是个“天坑”
本文首发于CSDN公众号 作者 | 开发游戏的老王 责编 | 梦依丹 出品 | CSDN(ID:CSDNnews) 各位游戏开发者大家好,我是开发游戏的老王,一名游戏开发者同时也是一名高校游戏方向的主讲教师,从事游戏开发及相关教…...
剑指 Offer 64. 求 1 + 2 + … + n(java解题)
剑指 Offer 64. 求 1 2 … n(java解题)1. 题目2. 解题思路3. 数据类型功能函数总结4. java代码1. 题目 求 12…n ,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。 示例…...

2022 年度_职业项目总结_Java技术点归纳
Java技术点归纳目录概述需求:设计思路实现思路分析1.Structs 元工程改造2.个贷子系统开发3.架构的迭代开发,升级,部署,参考资料和推荐阅读Survive by day and develop by night. talk for import biz , show your perfect code,fu…...

【项目实战】32G的电脑启动IDEA一个后端服务要2min,谁忍的了?
一、背景 本人电脑性能一般,但是拥有着一台高性能的VDI(虚拟桌面基础架构),以下是具体的配置 二、问题描述 但是,即便是拥有这么高的性能,每次运行基于Dubbo微服务架构下的微服务都贼久,以下…...
接口自动化面试题汇总(持续更新)
在自动化测试过程中,你如何处理测试数据?你会使用哪些方法来生成测试数据? 在自动化测试过程中,测试数据对于测试的准确性和覆盖率至关重要,常见方法有: 1、使用真实的生产数据:使用真实的生产…...

SpringBoot实现静态资源映射,登录功能以及访问拦截验证——以黑马瑞吉外卖为例
目录 一、项目简介 二、设置静态资源访问路径 三、实现登录功能 四、拦截访问请求 本篇文章以黑马瑞吉外卖为例 一、项目简介 瑞吉外卖项目分为后台和前台系统,后台提供给管理人员使用,前台则是用户订餐使用 资源我们放在resources下 二、设置静态…...

PythonWeb Django PostgreSQL创建Web项目(三)
了解Django框架下如何配置数据库链接与创建模型和应用 使用Django创建web项目,首先需要了解生成的项目文件结构,以及对应文件功能用途方可开始web项目页面创建,下方先介绍文件功能,之后再配置数据库连接以及管理创建模型与应用&a…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...