【笔记】移动端自动化:adb调试工具+appium+UIAutomatorViewer
学习源:
https://www.bilibili.com/video/BV11p4y197HQ
https://blog.csdn.net/weixin_47498728/category_11818905.html
一、移动端测试环境搭建
学习目标
1.能够搭建java 环境
2.能够搭建android 环境
(一)整体思路
我们的目标是Android测试,所以环境需要搭建三个,Java,AndroidSDK,Android模拟器。
为什么要安装这三个环境,我们倒着来说:
Android模拟器:实际上就是一台手机,方便我们给大家展示效果。
AndroidSDK: Android SDK给你提供开发测试所必须的Android API类库
Java:Android的底层是c、C++,应用层用的语言是Java所以需要使用Java环境
(二)环境搭建
java环境
安装JDK1.8
运行jdk-8u151-windows-x64.exe文件默认安装即可(例如我的安装目录:C:\Program Files Java\jdk1.8.0)
配置java环境变量(Windowns7为例)
1.进入我的电脑 ->属性 -> 高级系统设置 -> 环境变量
2.在系统变量下点击新建 ->变量名: JAVALHOME -> 变量值: 比如: c:\Program Files Java jdk1.8.-> 点击确定按钮
3.在系统变量下点击新建 -> 变量名: CLASSPATH -> 变量值:;%JAVA_HOME%1ib;%JAVALHOME%1ib\tools.jar(***变量值最前面有一个”")-> 点击确定按钮
4.在系统变量下找到系统的path变量,进入在最后添加:;%JAVAHOME%bin;%JAVALHOME%jre bin(最前面是一个分号,如果path变量最后已有分号,可不用添加) -> 点击确定按钮
验证环境变量
选择语言
1.win+r 或者开始->搜索框输入cmd
2.在界面运行java -version
Android环境
以windows为例:
将SDK保存到硬盘
Android SDK文件央解压到任意目录(记住这个目录的位置,目录不要有中文)
配置环境变量
选择语言
1.进入我的电脑->属性 -> 高级系统设置 -> 环境变量
2.在系统变量下点击新建 →变量名:ANDROID_HOME → 变量值:D:android-sdk -> 点击确定按钮
3.在系统变量下找到系统的path变量,最后添加: ;%ANDROID-HOME%platform-tools;%ANDROID-HOME%too1s;(最前面是一个分号,如果path变量最后已有分号,可不用添加》 -> 点击确定按钮
验证环境变量
重启命令行工具,命令行输入adb,不报错即可
Andriod模拟器
以模拟器Genymotion为例:
1.执行genymotion-2.11.0-vbox.exe(是一个集合程序,包含genymotion和virtualbox) → 不需要更改配置,直接下一步默认安装
2.安装完enymotion继续等待,会提示安装virtualbox,继续安装,期间会提示安装oracle插件,全部允许安装
3.安装完成后会在桌面展示genymotion和virtualbox两个图标
(三)为虚拟机提供安装apk功能
1.打开virtualbox
2.进入virtualbox -> 管理 -> 导入虚拟电脑
3.点击文件选择(Samsung Galaxy s6 - 5.1.0 API 22 - 1440x2560va) -> 点击下一步
4.勾选 重新初始化所有网卡的MAC地址
5.点击导入按钮 ->等待倒入完成
6.virtualbox列表会展示如下图圈出的选项
二、adb 调试工具
学习目标:
1.能够了解 adb 的工作原理
2.能够应用常用的 adb 命令
(一)adb 的工作原理
1.adb的概念
ADB 全名Android Debug Bridge,是一个调试工具
- 开发安卓应用的程序员必须要掌握
- 测试工程师在做安卓应用测试时,会使用到
- adb的构成和工作原理
提示:只需要知道组成部分和工作原理,会使用即可,面试可能会被问到
adb 包含三个部分:
1.Client端: 运行在开发机器中,即你的开发电脑,用来发送 adb 命令;
2.Daemon 守护进程: 运行在调试设备中,手机或模器,用来接收并执行 adb 命令;
3.Server端: 同样运行在开发机器中,用来管理 Client 端和手机的 Daemon 之间的通信。
小结
adb 工具可以在电脑通过终端命令操作安卓手机/模拟器。
- adb构成
client端,在电脑上,负责发送adb命令
daemon守护进程,在手机上,负责接收和执行adb命令
server端,在电脑上,负责管理client和daemon
- adb构成和工作原理
client端,在电脑上,负责发送adb命令
daemon守护进程,在手机上,负责接收和执行adb命令
server端,在电脑上,负责管理client和daemon之间的通信
adb工作原理
1.client端将命令发送给server端
2.server端会将命令发送给daemon端
3.daemon端进行执行
4.将执行结果,返回给server端
5.server端将结果再返回给client端
(二)adb 常用命令
1.包名和界面名
概念:
包名 (package):决定程序的唯一性 (不是应用的名字)
界面名 (activity) :目前可以理解,一个界面名,对应着一个界面。
2.应用场景
自动化测试需要通过代码的形式告诉手机测试哪个应用程序的哪一个界面,所以需要通过这个命令进行获取。
使用步骤
1.打开需要测试的应用程序
2.输入 adb 命令
查询命令:
Mac/Linux:
adb shell dumpsys window windows | grep mFocused
Windows:
adb shell dumpsys window windows | findstr mFocusedApp
示例
作用:获取设置程序的包名和界面名
1.先在模拟器或手机中打开《设置》应用程序
2.输入对应平台的命令
结果如下:
mFocusedApp=AppwindowToken{53309da token=Token{2e2fa785ActivityRecord{2928d4fc u0 com.android.settings/.Settings t1127}}}
其中:
- 包名为: com.android.settings
- 界面名为:.settings
注意点
界面名可能会在和同事沟通交流或网站的文章中翻译为启动名
2.文件传输[应用]
(1)发送文件到手机
(2)从手机中拉取文件
(1)发送文件到手机
将手机需要的数据(数据库文件) 在电脑上调整好,直接发送给手机
命令格式
adb push 电脑的文件路径 手机的文件夹路径
示例
作用:将桌面的 a.txt 发送到手机的 sd 卡
adb push c:\users hm\Desktop\a.txt /sdcard
(2)从手机中拉取文件
将手机产生的文件(数据库文件,日志文件) 拉取到电脑中
应用场景
将手机产生的文件 (数据库文件,日志文件) 拉取到电脑中命令格式
adb pull 手机的文件路径 电脑的文件夹路径
示例
作用:将手机的 sd 卡的 a.txt 拉取到桌面
adb pull /sdcard/a.txt c: users\hm\Desktop
3. 获取app启动时间[应用]
应用场景
如果企业对应用程序的启动速度有要求,则需要使用这个命令进行测试2.测试标准:参照同类软件,启动时间不能超出一倍即可
命令格式
adb she11 am start -w 包名/启动名
示例
作用:启动 com.android.settings 程序并且进入主界面(.Settings )
adb shell am start -w com.android.settings/.Settings
解释:
1.ThisTime :该界面( activity )启动耗时 (毫秒)
2.TotalTime:应用自身启动耗时= ThisTime +应用application 等资源启动时间 (毫秒)
3.waitTime:系统启动应用耗时 = TotalTime +系统资源启动时间 (毫秒)
4.获取手机日志[应用]
应用场景
将bug的日志信息发送给开发人员,便于开发人员定位bug
使用步骤
1.打开需要测试的应用程序
2.找到触发bug的位置
3.使用查看日志命令adb 1ogcat
4.触发bug
5.获取日志信息
命令格式
adb logcat
注意:实时监听操作
其它命令
其它命令
1、安装 app 到⼿机:adb install 路 径/xx.apk
2、卸载⼿机上的 app:adb uninstall 包名
3、 获取当前电脑已经连接设备和对应的设备号 :adb devices
4、 进⼊到安卓⼿机内部的linux 系统命令⾏中 :adb shell
5 、启动 adb 服务端:adb start-server
6 、停⽌ adb 服务端:adb kill-server
7、查看 adb 帮助: adb --help
三、Appium自动化测试框架
1.能够安装Appium 桌面客户端
2.能够安装Appium-python 库
Appium介绍
Appium是一个移动端的自动化框架,可用于测试原生应用,移动网页应用和混合型应用,且是跨平台的,可用于iOs和Android操作系统。原生的应用是指用andrid或iOS的sdk编写的应用,移动网页应用是指网页应用,类似于ios中safari应用或者Chrome应用或者类浏览器的应用。混合应用是指一种包裹webview的应用,原生应用于网页内容交互性的应用。
重要的是Appium是跨平台的,何为跨平台,意思就是可以针对不同的平台用一套api来编写测试脚本,
Appium自动化测试环境搭建
我们使用Appium和python来进行自动化测试,需要安装两个东西,一个是Appium的客户端,一个是Appium.python库。这两个需要安装的东西在加上手机就可以进行自动化测试。
它们之间的关系是: python代码·>Appium-python库->Appium -> 手机。
Appium桌面客户端安装方式
1.运行appium-desktop-Setup-1.6.2.exe,默认安装即可
2.启动客户端,按图片步骤 1-> 2->3-> 4 设置
3.启动成功展示如下图
Appium-python库安装
命令行安装(需要联网)
pip3 insta17 Appium-Python-Client
可能出现的问题:
错误提示: could not create /usr/local/lib/python2.7/dist-packages/virtualenv_support’: Permission denied
权限问题,使用管理员运行cmd
hello appium 初体验
-
能够使用 appium 启动任意应用程序
-
能够了解 “前置代码” 中各项参数的含义
01_hello-appium_快速体验_哔哩哔哩_bilibili
应用场景
在做app自动化的时候,我们肯定是针对某个产品、某个软件进行测试,那么我们一定是先让模拟器或
真机帮我们打开这款软件才可以。所以接下来要学的就是如何打开某个应用程序。
需求
使用以下步骤可以打开模拟器中的 《设置》 应用程序
步骤
-
打开手机模拟器
-
打开appium工具
-
创建一个python项目,取名为 hello_appium
-
创建一个 demo.py 文件
-
将下面代码直接复制,并运行即可
# 导模块
from appium import webdriver
# 创建一个字典,包装相应的启动参数
desired_caps = dict()
# 需要连接的手机的平台(不限制大小写)
desired_caps['platformName'] = 'Android'
# 需要连接的手机的版本号(比如 5.2.1 的版本可以填写 5.2.1 或 5.2 或 5 ,以此类推)
desired_caps['platformVersion'] = '5.1'
# 需要连接的手机的设备号(andoird平台下,可以随便写,但是不能不写)
desired_caps['deviceName'] = '192.168.56.101:5555'
# 需要启动的程序的包名
desired_caps['appPackage'] = 'com.android.settings'
# 需要启动的程序的界面名
desired_caps['appActivity'] = '.Settings'
# 连接appium服务器
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
# 退出
driver.quit()
启动过程
appium的启动实际上是在本机使用了4723端口开启了一个服务
我们写的 python 代码会访问本机的 appium 服务器,并获取 driver 对象
appium 会将我们的 driver 对象调用的方法转化成 post 请求,提交给appium服务器
appium 通过接收到的 post 请求发送给手机,再由手机进行执行
如何使用appium打开任意一个应用程序
步骤
1.打开要测试的应用
2.使用 adb 命令获取包名和界面名
3.修改 desired_caps 字典中的appPackage和appActivity 的参数
如果测试的设备版本号发生变化?
修改 desired_caps 字典中的 platformVersion 的参数
如果测试的设备平台发生变化?
修改desired_caps字典中的 platformName的参数
Appium 基础操作 API
-
能够使用 appium 在脚本内启动其他 app
-
能够使用 appium 获取包名和界面名
-
能够使用 appium 关闭 app 和 驱动对象
-
能够使用 appium 安装和卸载 app
-
能够使用 appium 将应用置于后台
一. Appium 基础操作 API
前置代码
from appium import webdriver
desired_caps = dict()
# 手机参数
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '5.1'
desired_caps['deviceName'] = '192.168.56.101:5555'
# 应用参数
desired_caps['appPackage'] = 'com.android.settings'
desired_caps['appActivity'] = '.Settings'
# 获取driver
driver = webdriver.Remote('http://localhost:4723/wd/hub',desired_caps)
# 退出driver
driver.quit()
1.在脚本内启动其他 app
应用场景
如果一个应用需要跳转到另外一个应用,就可以使用这个 api 进行应用的跳转,就像我们通过外卖应用下订单之后会跳转到支付应用一样。
方法名和参数
# 脚本内启动其他app
# 参数:
# appPackage:要打开的程序的包名
# appActivity:要打开的程序的界面名
driver.start_activity(appPackage, appActivity)
示例
打开《设置》应用程序,等待三秒后跳转到《短信》应用程序
from appium import webdriver
desired_caps = dict()
# 手机参数
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '5.1'
desired_caps['deviceName'] = '192.168.56.101:5555'
# 应用参数
desired_caps['appPackage'] = 'com.android.settings'
desired_caps['appActivity'] = '.Settings'
# 获取driver
driver = webdriver.Remote('http://localhost:4723/wd/hub',desired_caps)
# 跳转到短信
driver.start_activity('com.android.mms', '.ui.ConversationList')
time.sleep(5)
# 退出driver
driver.quit()
2.获取 app 的包名和界面名
应用场景
当我们从一个应用跳转到另外一个应用的时候,想输出其包名、界面名或者想在报告中展现对应信息,我们就可以调用这个属性来进行获取。
属性名
# 获取包名
driver.current_package
# 获取界面名
driver.current_activity
示例
打开《设置》应用程序后输出当前的包名和界面名
from appium import webdriver
desired_caps = dict()
# 手机参数
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '5.1'
desired_caps['deviceName'] = '192.168.56.101:5555'
# 应用参数
desired_caps['appPackage'] = 'com.android.settings'
desired_caps['appActivity'] = '.Settings'
# 获取driver
driver = webdriver.Remote('http://localhost:4723/wd/hub',desired_caps)
# 打印当前包名
print(driver.current_package)
# 打印当前界面名
print(driver.current_activity)
# 退出driver
driver.quit()
结果
com.android.settings
.Settings
3.关闭 app 和 驱动对象
应用场景
有的时候我们需要关闭某个应用程序后,再打开新的应用。那么如何关闭应用程序呢?
方法名
# 关闭当前操作的app,不会关闭驱动对象
driver.close_app()
# 关闭驱动对象,同时关闭所有关联的app
driver.quit()
示例
打开《设置》,使用 close_app() 方法关闭,再尝试使用 quit() 方法,最后打印当前程序的包名,观察区别
from appium import webdriver
desired_caps = dict()
# 手机参数
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '5.1'
desired_caps['deviceName'] = '192.168.56.101:5555'
# 应用参数
desired_caps['appPackage'] = 'com.android.settings'
desired_caps['appActivity'] = '.Settings'
# 获取driver
driver = webdriver.Remote('http://localhost:4723/wd/hub',desired_caps)
# 关闭应用
driver.close_app()
# 退出driver
driver.quit()
结果
使用 quit() 后会报错,使用close_app() 不会报错
小结
close_app() 不会关闭驱动对象,只会关闭应用
quit() 会关闭驱动对象
4.安装和卸载以及是否安装 app
应用场景
一些应用市场的软件可能会有一个按钮,如果某一个程序已经安装则卸载,如果没有安装则安装
方法名
# 安装app
# 参数:
# app_path:apk路径
driver.install_app(app_path)
# 卸载app
# 参数:
# app_id:应用程序包名
driver.remove_app(app_id)
# 判断app是否已经安装
# 参数:
# app_id:应用程序包名
# 返回值:
# 布尔类型,True为安装,False为没有安装
driver.is_app_installed(app_id)
示例
如果《安智市场》已经安装,则卸载《安智市场》,如果没有则安装
from appium import webdriver
desired_caps = dict()
# 手机参数
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '5.1'
desired_caps['deviceName'] = '192.168.56.101:5555'
# 应用参数
desired_caps['appPackage'] = 'com.android.settings'
desired_caps['appActivity'] = '.Settings'
# 获取driver
driver = webdriver.Remote('http://localhost:4723/wd/hub',desired_caps)
if driver.is_app_installed("cn.goapk.market"):driver.remove_app("cn.goapk.market")
else:driver.install_app("/Users/Yoson/Desktop/anzhishichang.apk")
# 退出driver
driver.quit()
5.将应用置于后台
应用场景
银行类 app 会在进入后台一定时间后,如果再回到前台页面会重新输入密码,如果需要自动化测试这种功能:
# app放置到后台一定时间后再回到前台,模拟热启动
# 参数:
# seconds:后台停留多少秒
driver.background_app(seconds)
示例
打开《设置》应用,进入后台 5 秒,再回到前台
from appium import webdriver
desired_caps = dict()
# 手机参数
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '5.1'
desired_caps['deviceName'] = '192.168.56.101:5555'
# 应用参数
desired_caps['appPackage'] = 'com.android.settings'
desired_caps['appActivity'] = '.Settings'
# 获取driver
driver = webdriver.Remote('http://localhost:4723/wd/hub',desired_caps)
time.sleep(3)
print("---- 准备进入后台 ----")
# 进入后台5秒,再回到前台
driver.background_app(5)
print("---- 以及回到前台 ----")
time.sleep(3)
# 退出driver
driver.quit()
注意点
热启动:表示进入后台回到前台
冷启动:关机再开这种切断电源的行为
四、UIAutomatorViewer
UIAutomatorViewer初体验
学习目标:
能够使用 UIAutomatorViewer 获取元素的特征信息
应用场景
定位元素的时候必须根据元素的相关特征来进行定位,而 UIAutomatorViewer 就是用来获取元素特征的。
简介
UIAutomatorViewer 用来扫描和分析 Android 应用程序的 UI 控件的工具。
使用步骤
1.进入SDK目录下的目录
mac 在 tools/bin 目录下,打开 uiautomatorviewer
windows 在 tools 目录下,打开 uiautomatorviewer.bat
2.电脑连接真机或打开android模拟器
3.启动待测试app
4.点击 uiautomatorviewer 的左上角 Device Screenshot (从左数第二个按钮)
5.点击希望查看的控件
6.查看右下角 Node Detail 相关信息
示例
查看《设置》应用程序右上角 ”放大镜“ 按钮的 ”resource-id“
1.打开 uiautomatorviewer
2.打开 android 模拟器
3.启动《设置》应用程序
4.点击 Device Screenshot 按钮
5.点击 ”放大镜“ 按钮
6.查看 Node Detail 中的 ”resource-id“ 信息
注意点
1.自动打开的命令行窗口不要关
如果关了,整个工具也会关闭
2.打开uiautomatorviewer闪退
解决方案:
jdk版本问题造成的,jdk为1.9时可能会出现这个问题,请换成1.8的版本
3.点击第二个按钮报错
解决方案:重启adb
-
adb kill-server
-
adb start-server
元素定位操作 API
学习目标
-
能够分别使用 id、class、xpath 定位某一个元素
-
能够分别使用 id、class、xpath 定位某一组元素
应用场景
计算机不像人一样 ”聪明“,我们需要通过元素定位来获取元素,才能让计算机帮我们 ”操作“ 这个元素。
步骤
打开 uiautomatorviewer 工具
打开模拟器或真机
通过 uiautomatorviewer 工具获取想要进行操作的元素的 Node Detail 信息
通过元素定位 API 进行定位
对元素进行相关操作
注意点
元素的定位基于当前屏幕范围内展示的可见元素。
1.定位一个元素【掌握】
应用场景
想要对按钮进行点击,想要对输入框进行输入,想要获取文本框的内容,定位元素是自动化操作必须要使用的方法。只有获取元素之后,才能对这个元素进行操作。
方法名
# 通过id定位一个元素
# 参数:
# id_value:元素的resource-id属性值
# 返回值:
# 定位到的单个元素
driver.find_element_by_id(id_value)
# 通过class_name定位一个元素
# 参数:
# class_value:元素的class属性值
# 返回值:
# 定位到的单个元素
driver.find_element_by_class_name(class_value)
# 通过xpath定位一个元素
# 参数:
# xpath_value:定位元素的xpath表达式
# 返回值:
# 定位到的单个元素
driver.find_element_by_xpath(xpath_value)
示例
通过 id 的形式,定位 ”放大镜“ 按钮,并点击
通过 class 的形式,定位 ”输入框“,输入 ”hello“
通过 xpath 的形式,定位"收起"按钮,并点击
关键代码
# 通过 id 的形式,定位 ”放大镜“ 按钮,并点击
driver.find_element_by_id("com.android.settings:id/search").click()# 通过 class 的形式,定位 ”输入框“,输入 ”hello“
driver.find_element_by_class_name("android.widget.EditText").send_keys("hello")# 通过 xpath 的形式,定位"收起"按钮,并点击
driver.find_element_by_xpath("//*[@content-desc='收起']").click()
小结:
-
find_element_by_id
传入的参数: resource-id 的值 -
find_element_by_class_name
传入的参数: class 的值 -
find_element_by_xpath
传入的参数:xpath 表达式。
注意点:
如果很多元素特征相同,使用 find_element_by_xxx 的方法会找到第一个
也就是说,尽量去找元素特征有唯一性的“特征”来定位
2.定位一组元素【掌握】
应用场景
和定位一个元素相同,但如果想要批量的获取某个相同特征的元素,使用定位一组元素的方式更加方便。
方法名
# 通过id定位一组元素
# 参数:
# id_value:元素的resource-id属性值
# 返回值:
# 列表,定位到的所有符合调价你的元素
driver.find_elements_by_id(id_value)
# 通过class_name定位一组元素
# 参数:
# class_value:元素的class属性值
# 返回值:
# 列表,定位到的所有符合调价你的元素
driver.find_elements_by_class_name(class_value)
# 通过xpath定位一组元素
# 参数:
# xpath_value:定位元素的xpath表达式
# 返回值:
# 列表,定位到的所有符合调价你的元素
driver.find_elements_by_xpath(xpath_value)
示例
通过 id 的形式,获取所有 resource-id 为 ”com.android.settings:id/title“ 的元素,并打印其文字内容
通过 class_name 的形式,获取所有class 为 ”android.widget.TextView“ 的元素,并打印其文字内容
通过 xpath 的形式,获取所有包含 ”设“ 的元素,并打印其文字内容
关键代码
# 通过 id 的形式,获取所有 resource-id 为 ”com.android.settings:id/title“ 的元素,并打印其文字内容
titles = driver.find_elements_by_id("com.android.settings:id/title")
for title in titles:print(title.text)
# 通过 class_name 的形式,获取所有class 为 ”android.widget.TextView“ 的元素,并打印其文字内容
text_views = driver.find_element_by_class_name("android.widget.TextView")
for text_view in text_views:print(text_view.text)
# 通过 xpath 的形式,获取所有包含 ”设“ 的元素,并打印其文字内容
elements = driver.find_element_by_xpath("//*[contains(@text,'设')]")
for element in elements:print(element.text)
小结:
-
find_elements_by_id
传入的参数: resource-id 的值 -
find_elements_by_class_name
传入的参数: class 的值 -
find_elements_by_xpath
传入的参数:xpath 表达式。
概念:
如果通过一组的方式进行定位,获取的返回值不再是一个元素。而是一个列表,列表中装着所有符合这个特征的元素。
3.定位元素的注意点【了解】
应用场景
了解这些注意点可以以后在出错误的时候,更快速的定位问题原因。
示例
使用 find_element_by_xx 或 find_elements_by_xx 的方法,分别传入一个没有的 ”特征“ 会是什么结果呢?
核心代码
driver.find_element_by_id(“xxx”)
driver.find_elements_by_id(“xxx”)
小结
1.如果使用 find_element_by_xx 方法,如果传入一个没有的特征,会报NoSuchElementException
的错误。
2.如果使用 find_elements_by_xx 方法,如果传入一个没有的特征,不会报错,会返回一个空列表
元素等待
学习目标
能够使用隐式等待来定位元素
能够使用显式等待来定位元素
应用场景
可能由于一些原因,我们想找的元素并没有立刻出来,此时如果直接定位可能会报错,比如以下原因:
1.由于网络速度原因
2.服务器处理请求原因
3.电脑配置原因
概念
WebDriver定位页面元素时如果未找到,会在指定时间内一直等待的过程
元素等待一共分为两种类型
1.显式等待
2.隐式等待
1.隐式等待
示例
在 5 秒钟内,在《设置》程序中的 ”返回“ 按钮,如果找到则点击。如果找不到则观察对应错误信息。
核心代码
from selenium.webdriver.support.wait import WebDriverWait
# -----
# 启动应用参数
# -----
driver.implicitly_wait(5)
search_button = driver.find_element_by_xpath("//*[contains(@content-desc,'收起')]")
search_button.click()
方法参数解释
# 参数:
# timeout:超时的时长,单位:秒
implicitly_wait(timeout)
关键方法:
通过 driver 对象调用implicitly_wait 方法
设置超时时间
作用:
在设置了超时时间之后,后续所有的定位元素的方法都会在这个时间内等待元素的出现。
如果出现了,直接进行后续操作。
如果没有出现,报错,NoSuchElementException。
2.显示等待
应用场景
针对所有定位元素的超时时间设置为不同的值的时候
概念
等待元素加载指定的时长,超出时长抛出TimeoutException异常
步骤
1.导包
2.创建 WebDriverWait 对象
3.调用 WebDriverWait 对象的 until 方法
示例
在 5 秒钟内,每 1 秒在《设置》程序中的 ”返回“ 按钮,如果找到则点击。如果找不到则观察对应错误信息。
核心代码
from selenium.webdriver.support.wait import WebDriverWait
# -----
# 启动应用参数
# -----
# 创建WebDriverWait对象
wait = WebDriverWait(driver, 5, poll_frequency=1)
# 获取元素并设置超时时间和频率
search_button = wait.until(lambda x: x.find_element_by_xpath("//*[contains(@content-desc,'收起')]"))
# 点击搜索按钮,没有显示等待
search_button.click()
方法参数解释
# 参数:
# driver:驱动对象
# timeout:超时的时长,单位:秒
# poll_frequency:检测间隔时间,默认为0.5秒
# 返回值:
# WebDriverWait对象
WebDriverWait(driver, timeout, poll_frequency=0.5)
# 参数:
# method:lambda查找元素表达式
# 返回值:
# 定位到的元素,如果没有定位到会抛出TimeoutException异常
wait.until(method)
隐式等待和显式等待的选择
作用域:
显式等待为单个元素有效(更灵活),隐式为全局元素(更简单)
方法:
显式等待方法封装在 WebDriverWait 类中,而隐式等待则直接通过 driver 实例化对象调用
关于 sleep 的形式?
sleep 是固定死一个时间,不是不行,是不推荐。
元素等待可以让元素出来的第一时间进行操作。sleep 可能造成不必要的浪费。
元素操作API
学习目标
1.能够使用代码点击按钮
2.能够使用代码对输入框输入文字3.能够使用代码对输入框清空文字
4.能够使用代码获取元素的文本内容
5.能够使用代码获取元素的位置和大小
6.能够使用代码根据属性名获取元素的属性值
1.点击元素click()
应用场景
需要点击某个按钮的时候使用
方法名
# 对element按钮进行点击操作
element.click()
示例
-
打开《设置》
-
点击放大镜按钮
driver.find_element_by_id("com.android.settings:id/search").click()
2.输入和清空输入框内容 send_keys() 和 clear()
应用场景
需要对输入框进行输入或清空的时候使用
方法名
# 对element输入框进行输入操作
# 参数:
# value:输入的内容
element.send_keys(value)
# 对element输入框进行输入操作
element.clear()
示例
1.打开《设置》
2.点击 ”放大镜“
3.输入 ”hello“
4.暂停 2 秒
5.清空所有文本内容
6.暂停 5 秒
7.输入 ”你好“
默认输入中文无效,但不会报错,需要在 ”前置代码“ 中增加两个参数
desired_caps[‘unicodeKeyboard’] =True
desired_caps[‘resetKeyboard’] = True
核心代码
desired_caps[‘unicodeKeyboard’] =True
desired_caps[‘resetKeyboard’] = True
...
driver.find_element_by_id("com.android.settings:id/search").click()
edit_text = driver.find_element_by_class_name("android.widget.EditText")
edit_text.send_keys("hello")
time.sleep(2)
edit_text.clear()
time.sleep(5)
edit_text.send_keys("你好")
3.获取元素的文本内容
应用场景
需要获取按钮、文本框、输入框等控件的文本内容时使用
属性名
# 获取element控件的文本内容
# 返回值:
# 控件的文本内容
element.text
示例
1.打开《设置》
2.获取所有 resource-id 为 ”com.android.settings:id/title“ 的元素,并打印其文字内容
核心代码
titles = driver.find_elements_by_id("com.android.settings:id/title")
for title in titles:print(title.text)
4.获取元素的位置和大小
应用场景
需要获取元素的位置和大小的时候使用
属性名
属性名
# 获取element的位置
# 返回值:
# 字典,x为元素的x坐标,y为元素的y坐标
element.location
# 获取element的大小
# 返回值:
# 字典,width为宽度,height为告诉
element.size
# 获取element的位置
# 返回值:
# 字典,x为元素的x坐标,y为元素的y坐标
element.location
# 获取element的大小
# 返回值:
# 字典,width为宽度,height为告诉
element.size
示例
1.打开《设置》
2.获取 ”放大镜“ 的位置和大小
核心代码
search_button = driver.find_element_by_id("com.android.settings:id/search")
print(search_button.location)
print(search_button.size)
5.获取元素的属性值
应用场景
根据特征定位到元素后,使元素的属性名获取对应的属性值
方法名
# 对element进行点击操作
# 参数:
# value:要获取的属性名
# 返回值:
# 根据属性名得到的属性值
element.get_attribute(value) # value:元素的属性
示例
1.打开《设置》
2.获取所有 resource-id 为 ”com.android.settings:id/title“ 的元素
3.使用 get_attribute 获取这些元素的 enabled、text、content-desc、resource-id、class 的属性值
核心代码
titles = driver.find_elements_by_id("com.android.settings:id/title")
for title in titles:
print(title.get_attribute("enabled"))
print(title.get_attribute("text"))
print(title.get_attribute("name"))
# 特殊:resourceId、ClassName固定属性名
print(title.get_attribute("resourceId"))
print(title.get_attribute("ClassName"))
注意点:
value=‘text’ 返回text的属性值
value=‘name’ 返回content-desc / text属性值
value=‘className’ 返回 class属性值,只有 API=>18(即安卓版本大于4.3) 才能支持
value=‘resourceId’ 返回 resource-id属性值,只有 API=>18 (即安卓版本大于4.3) 才能支持
滑动和拖拽事件
学习目标
1.能够使用 swipe 滑动屏幕
2.能够使用 scroll 滑动屏幕
3.能够使用 drag_ahd_drop 滑动屏幕
应用场景
我们在做自动化测试的时候,有些按钮是需要滑动几次屏幕后才会出现,此时,我们需要使用代码来模拟手指的滑动,也就是我们将要学习的滑动和拖拽事件
swipe 滑动事件
driver.swipe(起始x坐标起始y坐标,结束x坐标结束y坐标持续时间ms)
概念
从一个坐标位置滑动到另一个坐标位置,只能是两个点之间的滑动。
方法名
# 从一个坐标位置滑动到另一个坐标位置,只能是两个点之间的滑动
# 参数:
# start_x: 起点X轴坐标
# start_y: 起点Y轴坐标
# end_x: 终点X轴坐标
# end_y: 终点Y轴坐标
# duration: 滑动这个操作一共持续的时间长度,单位:ms
driver.swipe(start_x, start_y, end_x, end_y, duration=None)
示例1
模拟手指从(100, 2000),滑动到(100, 1000)的位置
核心代码
driver.swipe(100, 2000, 100, 1000)
示例2
模拟手指从(100, 2000),滑动到(100, 100)的位置
核心代码
driver.swipe(100, 2000, 100, 100)
示例3
模拟手指从(100, 2000),滑动到(100, 100)的位置,持续5秒
核心代码
driver.swipe(100, 2000, 100, 100, 5000)
小结
距离相同时,持续时间越长,惯性越小
持续时间相同时,手指滑动的距离越大,实际滑动的距离也就越大
为什么每次运行滑动的时候会有一些误差
cpu工作量大会导致计时器的时间和真实时间有误差
scroll 滑动事件
driver.scroll(起始元素, 结束元素)
概念
从一个元素滑动到另一个元素,直到页面自动停止。
方法名
# 从一个元素滑动到另一个元素,直到页面自动停止
# 参数:
# origin_el: 滑动开始的元素
# destination_el: 滑动结束的元素
driver.scroll(origin_el, destination_el)
示例
从 “存储” 滑动到 “更多”
核心代码
save_button = driver.find_element_by_xpath("//*[@text='存储']")
more_button = driver.find_element_by_xpath("//*[@text='更多']")
driver.scroll(save_button, more_button)
小结
不能设置持续时间,惯性很大
drag_and_drop 拖拽事件
driver.drag_and_drop(起始元素, 结束元素)
概念
从一个元素滑动到另一个元素,第二个元素替代第一个元素原本屏幕上的位置。
方法名
# 从一个元素滑动到另一个元素,第二个元素替代第一个元素原本屏幕上的位置
# 参数:
# origin_el: 滑动开始的元素
# destination_el: 滑动结束的元素
driver.drag_and_drop(origin_el, destination_el)
示例
将 “存储” 拖拽到 “更多”
核心代码
save_button = driver.find_element_by_xpath("//*[@text='存储']")
more_button = driver.find_element_by_xpath("//*[@text='更多']")
driver.drag_and_drop(save_button, more_button)
小结
不能设置持续时间,没有惯性
滑动和拖拽事件的选择
滑动和拖拽无非就是考虑是否有 “惯性” ,以及传递的参数是 “元素” 还是 “坐标”。
可以分成以下四种情况
- 有 “惯性” ,传入 “元素”
scroll
- 无 “惯性” ,传入 “元素”
drag_and_drop
- 有 “惯性” ,传入 “坐标”
swipe,并且设置较短的 duration 时间
- 无 “惯性” ,传入 “坐标”
swipe,并且设置较长的 duration 时间
小结
高级手势TouchAction
学习目标
1.能够使用代码完成轻敲手势
2.能够使用代码完成按下手势
3.能够使用代码完成抬起手势
4.能够使用代码完成等待操作
5.能够使用代码完成长按手势
6.能够使用代码完成手指移动操作
应用场景
TouchAction 可以实现一些针对手势的操作,比如滑动、长按、拖动等。我们可以将这些基本手势组合成一个相对复杂的手势。比如,我们解锁手机或者一些应用软件都有手势解锁的这种方式。
使用步骤
1.创建 TouchAction 对象
2.通过对象调用想执行的手势
3.通过 perform() 执行动作
注意点
所有手势都要通过执行perform()函数才会运行。
1.轻敲操作【掌握】- tap()
应用场景
模拟手指对某个元素或坐标按下并快速抬起。比如,固定点击(100, 100)的位置。
方法名
# 模拟手指对元素或坐标的轻敲操作
# 参数:
# element:元素
# x:x坐标
# y:y坐标
TouchAction(driver).tap(element=None, x=None, y=None).perform()
示例
打开《设置》
轻敲 “WLAN”
核心代码
el = driver.find_element_by_xpath("//*[contains(@text,'WLAN')]")
TouchAction(driver).tap(el).perform()
2.按下和抬起操作【掌握】- press() 和release()
应用场景
模拟手指一直按下,模拟手指抬起。可以用来组合成轻敲或长按的操作
方法名
# 模拟手指对元素或坐标的按下操作
# 参数:
# el:元素
# x:x坐标
# y:y坐标
TouchAction(driver).press(el=None, x=None, y=None).perform()
# 模拟手指对元素或坐标的抬起操作
TouchAction(driver).release().perform()
示例1
使用坐标的形式按下 WLAN (650, 650),2 秒后,按下(650, 650)的位置
核心代码
TouchAction(driver).press(x=650, y=650).perform()
time.sleep(2)
TouchAction(driver).press(x=650, y=650).perform()
示例2
使用坐标的形式按下 WLAN (650, 650),2 秒后,按下(650, 650)的位置,并抬起
TouchAction(driver).press(x=650, y=650).perform()
time.sleep(2)
TouchAction(driver).press(x=650, y=650).release().perform()
3.等待操作【掌握】- wait()
应用场景
模拟手指等待,比如按下后等待 5 秒之后再抬起。
方法名
# 模拟手指暂定操作
# 参数:
# ms:暂停的毫秒数
TouchAction(driver).wait(ms=0).perform()
示例
使用坐标的形式点击 WLAN (650, 650),2 秒后,按下(650, 650)的位置,暂停 2 秒,并抬起
核心代码
TouchAction(driver).tap(x=650, y=650).perform()
time.sleep(2)
TouchAction(driver).press(x=650, y=650).wait(2000).release().perform()
4.长按操作【掌握】-long_press()
应用场景
模拟手指对元素或坐标的长按操作。比如,长按某个按钮弹出菜单。
方法名
# 模拟手指对元素或坐标的长按操作
# 参数:
# el:元素
# x:x坐标
# y:y坐标
# duration:长按时间,毫秒
TouchAction(driver).long_press(el=None, x=None, y=None, duration=1000).perform()
示例
使用坐标的形式点击 WLAN (650, 650),2 秒后,长按(650, 650)的位置持续 2 秒
核心代码
TouchAction(driver).tap(x=400, y=400).perform()
time.sleep(2)
TouchAction(driver).long_press(x=400, y=400, duration=2000).release().perform()
5.移动操作【掌握】- move_to
应用场景
模拟手指移动操作,比如,手势解锁需要先按下,再移动。
方法名
# 模拟手指对元素或坐标的移动操作
# 参数:
# el:元素
# x:x坐标
# y:y坐标
TouchAction(driver).move_to(el=None, x=None, y=None).perform()
示例
在手势解锁中,画一个如下图的案例
包名界面名为 com.android.settings/.ChooseLockPattern
核心代码
TouchAction(driver).press(x=246, y=857).move_to(x=721, y=867).move_to(x=1200,
y=851).move_to(x=1200, y=1329).move_to(x=724, y=1329).move_to(x=246,
y=1329).move_to(x=718, y=1815).release().perform()
手机操作API
学习目标
能够获取手机分辨率
能够获取手机截图
能够获取和设置网络状态
能够发送键到设备
能够打开和关闭手机通知栏
1.获取手机分辨率【掌握】
应用场景
自动化测试可能会需要根据当前设备的屏幕分辨率来计算一些点击或者滑动的坐标
方法名
# 获取手机分辨率
driver.get_window_size()
示例
输出当前设备的屏幕分辨率
核心代码
print(driver.get_window_size())
执行结果
{‘height’: 800, ‘width’: 480}
2.手机截图【掌握】
应用场景
有些自动化的操作可能没有反应,但并不报错。此时我们就可以将操作过后的关键情况,截图留存。后期也可以根据图片发现问题。
方法名
# 获取手机分辨率
# 参数:
# filename:指定路径下,指定格式的图片
get_screenshot_as_file(filename)
示例
打开设置页面
截图当前页面保存到当前目录,命名为screen.png
核心代码
driver.get_screenshot_as_file(os.getcwd() + os.sep + './screen.png')
3.获取和设置手机网络【掌握】
应用场景
视频应用在使用流量看视频的时候,大部分都会提示用户正在是否继续播放。作为测试人员,我们可能需要用自动化的形式来判断是否有对应的提示。即,用流量的时候应该有提示,不用流量的时候应该没有提示。
获取手机网络
属性名
# 获取手机网络 driver.network_connection
示例
获取当前网络类型,并打印
核心代码
print(driver.network_connection)
执行结果
6
结果对照
设置手机网络
方法名
# 设置手机网络
# 参数:
# connectionType:网络类型
driver.set_network_connection(connectionType)
示例
设置当前设备为飞行模式
核心代码
driver.set_network_connection(1)
执行效果
设备变为飞行模式
4. 发送键到设备【掌握】
应用场景
模拟按 “返回键” “home键” 等等操作,比如,很多应用有按两次返回键退出应用的功能,如果这个功能需要我们做自动化,那么一定会用到这个方法
方法名
# 发送键到设备
# 参数:
# keycode:发送给设备的关键代码
# metastate:关于被发送的关键代码的元信息,一般为默认值
driver.press_keycode(keycode, metastate=None)
注意点
按键对应的编码,可以在百度搜索关键字 “android keycode”
例如:https://blog.csdn.net/feizhixuan46789/article/details/16801429
示例
点击三次音量加,再点击返回,再点击两次音量减。
核心代码
driver.press_keycode(24)
driver.press_keycode(24)
driver.press_keycode(24)
driver.press_keycode(4)
driver.press_keycode(25)
driver.press_keycode(25)
5.操作手机通知栏【掌握】
应用场景
测试即时通信类软件的时候,如果 A 给 B 发送一条消息,B 的通知栏肯定会显示对应的消息。我们想通过通知栏来判断 B 是否收到消息,一定要先操作手机的通知栏
方法名
#打开手机通知栏
driver.open_notifications()
注意点
appium官方并没有为我们提供关闭通知的api,那么现实生活中怎么关闭,就怎样操作就行,比 如,手指从下往上滑动,或者,按返回键
示例
打开通知栏,两秒后,关闭通知栏
核心代码
driver.open_notifications()
time.sleep(2)
driver.press_keycode(4)
相关文章:
【笔记】移动端自动化:adb调试工具+appium+UIAutomatorViewer
学习源: https://www.bilibili.com/video/BV11p4y197HQ https://blog.csdn.net/weixin_47498728/category_11818905.html 一、移动端测试环境搭建 学习目标 1.能够搭建java 环境 2.能够搭建android 环境 (一)整体思路 我们的目标是Andr…...
面试复习题--性能检测原理
1、布局性能检测 Systrace,内存优化工具中也用到了 Systrace,这里关注 Systrace 中的 Frames 页面,正常情况下圆点为绿色,当出现黄色或者红色的圆点时,表现出现了丢帧。 Layout Inspector,是 AndroidStudio 自带工具…...
@LoadBalanced 和 @RefreshScope 同时使用,负载均衡失效分析
背景 最近引入了 Nacos Config 配置管理能力,说起来用法很简单,还是踩了三个坑。 Nacos Config 的 nacos 的帐号密码加密配置后,怎么解密而且在 NacosConfigBootstrapConfiguration 真正注入 Nacos Config 注入之前,而且不能触发…...
2023年个人计划
2023年个人计划 可能是最近太清闲,感觉生活很无聊,就胡乱做下新年的规划吧,扰乱下烦闷的心 1 二宝健健康康,活泼可爱 目前老婆已经怀孕5周左右了,二宝将在进行年中降生,希望老婆少受点罪,二宝…...
加拿大访问学者家属如何办理探亲签证?
由于大多数访问学者的访学期限都为一年,家人来访不仅可以缓解访学的寂寞生活,而且也是家人到加拿大体验国外风情的好机会。家属在国内申请赴加签证时,如果材料齐全,一般上午递交了申请,下午就可以拿到签证。以下是家人…...
操作系统基础---多线程
文章目录操作系统基础---多线程1.为何引入线程程序并发的时空开销线程的设计思路线程的状态和线程控制块TCB2.线程与进程的比较3.线程的实现⭐1.内核支持线程KST2.用户级线程3.组合方式操作系统基础—多线程 1.为何引入线程 利用传统的进程概念和设计方法已经难以设计出适合于…...
2022-12-10青少年软件编程(C语言)等级考试试卷(六级)解析
2022-12-10青少年软件编程(C语言)等级考试试卷(六级)解析T1、区间合并 给定 n 个闭区间 [ai; bi],其中i1,2,...,n。任意两个相邻或相交的闭区间可以合并为一个闭区间。例如,[1;2] 和 [2;3] 可以合并为 [1;3…...
太酷了,用Python实现一个动态条形图!
大家好,我是小F~说起动态条形图,小F之前推荐过两个Python库,比如「Bar Chart Race」、「Pandas_Alive」,都可以实现。今天就给大家再介绍一个新的Python库「pynimate」,一样可以制作动态条形图,…...
单元测试junit+mock
单元测试 是什么? 单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。至于“单元”的大小或范围,并没有一个明确的标准,“单元”可以是一个方法、类、功能模块或者子系统。 单元测试通…...
2022Q4手机银行新版本聚焦提升客群专属、财富开放平台、智能化能力,活跃用户规模6.91亿人
易观:2022年第4季度,手机银行APP迭代升级加快,手机银行作为零售银行服务及经营的主阵地,与零售银行业务发展的联系日益紧密。迭代升级一方面可以顺应零售银行发展战略及方向,对手机银行业务布局进行针对性调整优化&…...
YOLO-V1~V3经典物体检测算法介绍
大名鼎鼎的YOLO物体检测算法如今已经出现了V8版本,我们先来了解一下它前几代版本都做了什么吧。本篇文章介绍v1-v3,后续会继续更新。一、节深度学习经典检测方法概述1.1 检测任务中阶段的意义我们所学的深度学习经典检测方法 ,有些是单阶段的…...
SparkSQL 核心编程
文章目录SparkSQL 核心编程1、新的起点2、SQL 语法1) 读取 json 文件创建 DataFrame2) 对 DataFrame 创建一个临时表3) 通过SQL语句实现查询全表3、DSL 语法1) 创建一个DataFrame2) 查看DataFrame的Schema信息3) 只查看"username"列数据4) 查看"username"列…...
Android核心开发【UI绘制流程解析+原理】
一、UI如何进行具体绘制 UI从数据加载到具体展现的过程: 进程间的启动协作: 二、如何加载到数据 应用从启动到onCreate的过程: Activity生产过程详解: 核心对象 绘制流程源码路径 1、Activity加载ViewRootImpl ActivityThread…...
计算机组成原理第七章笔记记录
仅仅作为笔记记录,B站视频链接,若有错误请指出,谢谢 基本概念 演变过程 I/O系统基本组成 I/O软件 包括驱动程序、用户程序、管理程序、升级补丁等 下面的两种方式是用来实现CPU和I/O设备的信息交换的 I/O指令 CPU指令的一部分,由操作码,命令码,设备…...
ORB-SLAM2编译、安装等问题汇总大全(Ubuntu20.04、eigen3、pangolin0.5、opencv3.4.10)
ORB-SLAM2编译、安装等问题汇总大全(Ubuntu20.04、eigen3、pangolin0.5、opencv3.4.10) 1:环境说明: 使用的Linux发行版本为Ubuntu 20.04 SLAM2下载地址为:git clone https://github.com/raulmur/ORB_SLAM2.git ORB_SLAM2 2&a…...
QuickBuck:一款专为安全研究人员设计的勒索软件模拟器
关于QuickBuck QuickBuck是一款基于Golang开发的勒索软件模拟工具,在该工具的帮助下,广大研究人员可以通过更简单的方法来判断反病毒保护方案是否能够有效地预防勒索软件的攻击。 功能介绍 该工具能够模拟下列勒索软件典型行为,其中包括&a…...
【八大数据排序法】堆积树排序法的图形理解和案例实现 | C++
第二十一章 堆积树排序法 目录 第二十一章 堆积树排序法 ●前言 ●认识排序 1.简要介绍 2.图形理解 3.算法分析 ●二、案例实现 1.案例一 ● 总结 前言 排序算法是我们在程序设计中经常见到和使用的一种算法,它主要是将一堆不规则的数据按照递增…...
低代码开发平台|生产管理-生产加工搭建指南
1、简介1.1、案例简介本文将介绍,如何搭建生产管理-生产加工。1.2、应用场景在主生产计划列表中下达加工后,在加工单列表可操作领料、质检。2、设置方法2.1、表单搭建1)新建表单【产品结构清单(BOM)】,字段…...
Python类型-语句-函数
文章目录类型动态类型:变量类型会随着程序的运行发生改变注释控制台控制台输入input()运算符算术关系逻辑赋值总结语句判断语句while循环for循环函数链式调用和嵌套调用递归关键字传参在C/java中,整数除以整数结果还是整数,并不会将小数部分舍弃…...
真兰仪表在创业板开启申购:募资约20亿元,IPO市值约为78亿元
2月9日,上海真兰仪表科技股份有限公司(下称“真兰仪表”,SZ:301303)开启申购,将在深圳证券交易所创业板上市。本次上市,真兰仪表的发行价为26.80元/股,市盈率43.06倍。 据贝多财经了解…...
【2023】Prometheus-Prometheus与Alertmanager配置详解
记录一下Prometheus与Alertmanager的配置参数等内容 目录1.Prometheus1.1.prometheus.yml1.2.告警规则定义2.alertmanager2.1.alertmanager.yml2.1.1.global:全局配置2.1.1.1.以email方式作为告警发送方2.1.1.2.以wechat方式作为告警发送方2.1.1.3.以webhook方式作为…...
华为HCIE学习之openstack基础
文章目录一、Openstack各种文件位置二、Openstack命令操作1.使用帮助三、用命令发放云主机1、创建租户2、创建用户并与租户绑定3、注册镜像4、创建规格5、创建公有网络及其子网(做弹性IP用)6、创建私有网络及其子网7、创建路由并设置网关与端口8、创建安…...
Python实现贝叶斯优化器(Bayes_opt)优化BP神经网络分类模型(BP神经网络分类算法)项目实战
说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。1.项目背景贝叶斯优化器(BayesianOptimization) 是一种黑盒子优化器,用来寻找最优参数。贝叶斯优化器是基…...
Elasticsearch(九)搜索---搜索辅助功能(下)--搜索性能分析
一、前言 上篇文章我们学习了ES的搜索辅助功能的一部分–分别是指定搜索返回的字段,搜索结果计数,分页,那么本次我们来学习一下ES的性能分析相关功能。 二、ES性能分析 在使用ES的过程中,有的搜索请求的响应比较慢,…...
化繁为简|中信建投基于StarRocks构建统一查询服务平台
近年来,在证券服务逐渐互联网化,以及券商牌照红利逐渐消退的行业背景下,中信建投不断加大对数字化的投入,尤其重视数据基础设施的建设,期望在客户服务、经营管理等多方面由经验依赖向数据驱动转变,从而提高…...
2023数字中国创新大赛·数据开发赛道首批赛题启动报名
由数字中国建设峰会组委会主办的2023数字中国创新大赛(DCIC 2023)已正式启幕,本届大赛结合当下数字技术发展的热点和业界关注的焦点,面向产业实际需求设置了九大赛道。其中,数据开发赛道2月8日正式上线首批赛题&#x…...
MySQL数据库
1.MySQL的MyISAM与InnoDB两种存储引擎在,事务、锁级别,各自的适用场景? 1.1事务处理上方面 MyISAM:强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持。 InnoDB:提供事务…...
鸿蒙设备学习|快速上手BearPi-HM Micro开发板
系列文章目录 第一章 鸿蒙设备学习|初识BearPi-HM Micro开发板 第二章 鸿蒙设备学习|快速上手BearPi-HM Micro开发板 文章目录系列文章目录前言一、环境要求1.硬件要求2.软件要求3.Linux构建工具要求4.Windows开发工具要求5.工具下载地址二、安装编译基础环境1.安装Linux编译环…...
软件测试标准流程
软件测试的基本流程大概要经历四个阶段,分别是制定测试计划、测试需求分析、测试用例设计与编写以及测试用例评审。因此软件测试的工作内容,远远没有许多人想象的只是找出bug那么简单。准确的说,从一个项目立项以后,软件测试从业者…...
Python身份运算符
Python身份运算符身份运算符用于比较两个对象的存储单元运算符描述实例isis 是判断两个标识符是不是引用自一个对象x is y, 类似 id(x) id(y) , 如果引用的是同一个对象则返回 True,否则返回 Falseis notis not 是判断两个标识符是不是引用自不同对象x is not y &a…...
asp+sql server典型网站建设案例 光盘/最新旅游热点
如果不看glibc的代码,那么也许你永远也不知道什么叫境界,仅仅认为简单的可读性强的代码就是最好的代码的人也一定停留在应届毕业生的水平,程序很大意义上是给机器看的而不是给人看的,人看程序很大意义上是维护和经验学习ÿ…...
怎么做网站规划书/北京网站优化平台
数据结构在生活中的应用 数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关。 数据结构是指同一数…...
西部数码备案域名购买/win7优化大师官网
为什么80%的码农都做不了架构师?>>> 解决intellij中sPRing boot工程 无法用mainapplication启动问题 一、spring boot 工程 从svn库导出到 intellij idea中 后用mainApplication中的main函数启动时会出现 Failed to introspect annotated methods on cl…...
个人简介网页怎么做/优化设计单元测试卷
导出聊天记录生成词云看看你和对象聊了什么(可惜我没女朋友) 导出聊天记录打开消息管理器导出的格式选择txt格式(我这里选择导出的路径是桌面所以在桌面上生成了一个包含聊天记录的.txt文件) 干货主要有: ① 200 多…...
php网站开发实例教程 源代码/天津优化网络公司的建议
目前,北京、广州、深圳、上海、武汉、郑州、成都等全国90多个城市已实施了车辆限行规定。全国提供限行接口的平台众多,今天就分析一下目前主流的三个平台限行接口特点,聚合数据、极速数据、路帮网。 以下主要从三个方面,即平台涵盖…...
wordpress底部CSS/app推广平台
据统计,全球范围内被投递的钓鱼邮件每天约达到1亿封,经常会遇到一些邮件发送方,被spammer利用于伪造各种钓鱼/诈骗邮件,如:伪造银行、保险等金融企业,支付宝、Paypal等支付商,知名网站、政府网站…...