软件测试知识点和面试题--UI自动化篇_uiautomator自动化测试面试题-程序员宅基地

技术标签: UI自动化  软件测试  

主流自动化测试框架介绍

软件测试的自动化一般可以分为3层 * 代码层的单元测试 * 接口层的集成测试 * UI 层的测试

1)代码层自动化

代码层的自动化一般指针对代码进行的单元测试,比较常用的单元测试框架比如Java的Junit, Python的PyUnit等等,由于这部分并非本教程重点,这里就不详细展开,需要的同学可以自行学习。

2)接口层自动化

接口层的自动化测试主要是对系统和组建之间的接口进行测试,主要目标是校验数据的交换和业务的流程,接口测试可以测试功能、也可以测试性能、测试压力、测试安全等等。由于接口比代码单元要稳定的很多,所以自动化脚本维护成本更低、收益也更大,具有不错的性价比。常用的测试工具有以下:

Jmeter:由Apache组织开发的基于Java的接口测试、压力测试和性能测试工具,起初为Web测试而设计,后来逐步扩展到其他领域,可以用来测试静态或者动态的资源。
​
LoadRunner:HP公司提供的一款性能测试和压力测试工具,可以通过模拟成千上万用户实施并发操作来测试系统性能,并且有详细的测试结果分析,是性能测试和压测的不错选择。
​
Robot Framework: 一款开源的自动化测试框架,具有很好的可扩展性。框架用python编写,同时也提供跨平台支持。
​
Postman:简单方便且功能强大的接口调试工具,API调试首选。

3)UI层自动化

基于UI层的自动化测试框架要复杂很多,从平台种类来讲,有Windows,Linux,Android,Ios,Web,还有最新的小程序等等,下面会简单的和大家捋一遍主流UI层自动化框架的原理、架构以及跨平台能力。

① Appium

Appium是一款开源的自动化测试工具,支持IOS、Android、Windows和Mac应用。

跨平台

appium可以在OSX,Windows以及Linux桌面上运行。

跨语言

appium采用了C/S的设计模式,扩展了WebDriver协议,因此Client用Python、Java、Js/Nodejs、Ruby、OC、C#等各种语言来实现。

原理介绍

Appium的核心是一个遵守REST设计风格的Web服务器,他会用来接受客户端的连接和指令。由于统一的接口设计,客户端便可以用多种语言来实现,从而用自己喜欢的语言来实现测试用例。

服务端收到测试指令后会发送给设备,在设备层则使用了设备商提供的原生测试框架,比如IOS的XCUITest Driver和UIAutomation Driver, 安卓的UIAutomator和UIAutomator2等等。

 

Appium官网: http://appium.io/
​
Appium Github主页: https://github.com/appium/appium

② Selenium

Selenium是一款开源的Web应用自动化测试工具,可以直接运行在多种浏览器平台中,就像用户真实操作一样。

跨平台

        同样,Selenium也可以在OSX,Windows以及Linux桌面上运行。

支持浏览器

        Firefox,Chrome,IE,Edge,Opera,Safari

原理介绍

Selenium 官网:http://seleniumhq.org/
​
Selenium Github 主页:https://github.com/SeleniumHQ/selenium

⑤ Airtest Project介绍

Airtest Project是一款由网易研发并开源的自动化测试框架,相比于其他的自动化测试框架,主要有如下两个优势:

大幅度降低自动化脚本的编写和维护成本
    Airtest Project希望能够通过一种所见即所得的方式完成脚本的录制,即使测试人员不会编程不懂脚本,也可以通过正常用户的点击拖拽等操作,自动完成脚本的录制,从而大幅度降低企业和项目的自动化维护成本。
​
解决游戏测试的痛点
    Airtest Project希望能够通过对游戏的不同引擎做支持,成为一个真正意义上的跨引擎跨平台的自动化测试平台。

架构图

可以看到,底层的主要测试框架主要是Airtest和Poco,二者的区别在于:

Airtest:基于Python的、跨平台的UI自动化测试框架,基于图像识别原理,适用于游戏和App。
Poco:基于UI控件搜索的自动化测试框架,其核心优势是除了对Android、IOS之外,对游戏也是支持的,同时也支持微信小程序、微信小游戏和H5应用。

整套框架配备了非常实用的IDE,通过AirtestIDE, 可以轻松的完成脚本的录制、测试任务的执行以及最后测试报告的生成。

Web UI自动化

Selenium

WebDriver
    如果你开始使用桌面网站或移动网站测试自动化,那么你将使用 webdriverapi。 Webdriver 使用浏览器厂商提供的浏览器自动化 api 来控制浏览器和运行测试。 这就好像是一个真正的用户在操作浏览器。 由于 WebDriver 不需要使用应用程序代码编译其 API,因此它不具有侵入性。 因此,您测试的应用程序与实时推送的应用程序相同。
​
IDE
    Ide (集成开发环境)是您用来开发 Selenium 测试用例的工具。 它是一个易于使用的 Chrome 和 Firefox 扩展,并且通常是开发测试用例的最有效的方法。 它使用现有的 Selenium 命令记录用户在浏览器中的操作,参数由该元素的上下文定义。 这不仅是一个节省时间的方法,也是学习 Selenium 脚本语法的一个很好的方法。
​
Grid
    Selenium Grid 允许您跨不同平台在不同的机器上运行测试用例。 触发测试用例的控制位于本地端,当触发测试用例时,它们将由远程端自动执行。在 WebDriver 测试开发之后,您可能需要在多个浏览器和操作系统组合上运行测试。 这就是Grid出现的地方。

Selenium原理

1.selenium client(Java等语言编写的自动化测试脚本)初始化一个service服务,通过Webdriver启动浏览器驱动程序
2.通过RemoteWebDriver向浏览器驱动程序发送HTTP请求,浏览器驱动程序解析请求,打开浏览器,并获得sessionid,如果再次对浏览器操作需携带此id
3.打开浏览器,绑定特定的端口,把启动后的浏览器作为webdriver的remote server
4.打开浏览器后,所有的selenium的操作(访问地址,查找元素等)均通过RemoteConnection链接到remote server,然后使用execute方法调用_request方法通过urlib3向remote server发送请求
5.浏览器通过请求的内容执行对应动作
6.浏览器再把执行的动作结果通过浏览器驱动程序返回给测试脚本

remote server端的这些功能是如何实现的呢?

浏览器实现了webdriver的统一接口,client就可以通过统一的restful的接口去进行浏览器的自动化操作。

元素等待方法

隐式等待

1.定位元素时,如果能定位到元素则直接返回该元素,不触发等待; 
2.如果不能定位到该元素,则间隔一段时间后再去定位元素; 
3.如果在达到最大时长时还没有找到指定元素,则抛出元素不存在的异常NoSuchElementException。
driver.implicity_wait(timeout)

显示等待

1.定位指定元素时,如果能定位到元素则直接返回该元素,不触发等待;
2.如果不能定位到该元素,则间隔一段时间后再去定位元素; 
3.如果在达到最大时长时还没有找到指定元素,则抛出超时异常 TimeoutException
#导包
from selenium.webdriver.support.wait import WebDriverWait

#创建显示等待类对象
dw = WebDriverWait(driver, timeout, poll_frequency=0.5)

#调用utils方法
dw.until(lambda x:x.find_element(By.ID,'userA'))

隐私等待和显示等待对比

元素定位方法

ID = "id"
XPATH = "xpath"
LINK_TEXT = "link text"
PARTIAL_LINK_TEXT = "partial link text"
NAME = "name"
TAG_NAME = "tag name"
CLASS_NAME = "class name"
CSS_SELECTOR = "css selector"

ID定位

driver.find_element(by=By.ID, value='id属性值')

XPATH定位

绝对路径

概念:从最外层元素到指定元素之间所有经过的元素层级的路径--不建议使用 写法:绝对路径以/html根节点开始,使用/来分隔元素层级
xpath_val= '/html/body/div[2]/div[1]/div/div[1]/div/a/img[1]'
driver.find_element(by=By.XPATH, value='xpath_val')

相对路径

概念:从目标定位元素的任意层级的上级元素开始到目标元素所经过的层级的路径 写法:以//开始,后续每个层级都使用/来分隔
xpath_val= '//*[@id="id_userA"]'
driver.find_element(by=By.XPATH, value='xpath_val')

属性定位

利用元素的属性来进行定位--id/name/class/value
//input[@value='属性值']

属性与逻辑结合

利用元素的多个属性来进行定位
//input[@value='属性值' and @class='属性值']

层级与属性结合

先定位到其父级元素,然后再找到该元素
//div[@id='属性值']/input[@value='属性值']

利用元素的文本定位元素

//*[text()='文本']

利用局部属性值定位元素

//*[contain(@attribute,'局部属性值')]

CSS_SELECTOR定位

find_element(by=By.CSS_SELECTOR, value='#id名')
find_element(by=By.CSS_SELECTOR, value='.class名')
find_element(by=By.CSS_SELECTOR, value='[属性名="属性值"]')
find_element(by=By.CSS_SELECTOR, value='标签名[属性名="属性值"]')

层级选择器

父子策略

driver.find_element(by=By.CSS_SELECTOR, value='#pa>input')

祖辈策略

driver.find_element(by=By.CSS_SELECTOR, value='fieldset [id="id_userA"]')

利用局部属性值定位元素

driver.find_element(by=By.CSS_SELECTOR, value='tagName[attribute*='局部属性值']')

NAME定位

driver.find_element(by=By.NAME, value='name属性值')

CLASS_NAME定位

driver.find_element(by=By.CLASS_NAME, value='class属性值')

TAG_NAME定位

driver.find_element(by=By.TAG_NAME, value='标签名')

LINK_TEXT定位

driver.find_element(by=By.LINK_TEXT, value='链接文本')

PARTIAL_LINK_TEXT定位

driver.find_element(by=By.PARTIAL_LINK_TEXT, value='部分链接文本')

元素常用的操作方法

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver = webdriver.Firefox()

driver.get('url')
element = driver.find_element(By.XPath, 'xxx')
模拟点击 element.click()
模拟输入 element.send_keys(value)
模拟清除 element.clear()
获取元素大小 element.size
获取元素文本 element.text
获取元素属性值 element.get_attribute('属性名')
判断元素是否可见 element.is_displayed()
判断元素是否可用 element.is_enabled()

浏览器常用操作方法

窗口最大化 dirver.maxmize_window()
设置窗口大小 dirver.set_window_size(width, height) 
设置窗口位置 dirver.set_window_position(x, y)
页面后退操作 dirver.back()
页面前置操作 dirver.forword()
设置窗口位置 dirver.refresh( 	)
关闭当前窗口 dirver.close()
关闭浏览器 dirver.quit()
获取标题 dirver.title
获取网页地址 dirver.current_url

鼠标操作

#导包
from selenium.webdriver import ActionChains

#实例化鼠标对象
action = ActionChains(driver)

#调用鼠标方法
# 鼠标悬停
action.move_to_element(element)
#鼠标右击
action.context_click(element)
#鼠标双击
action.double_click(element)
#拖拽
action.drag_and_drop(source,target)

#执行鼠标操作
action.perform()

Select下拉框

1.导包
from selenium.webdriver.support.select import Select

2.创建select对象
select = Select(element)

3.选择选项
select.select_by_index(index) 根据下标
select.select_by_value(value) 根据选项value属性值
select.select_by_visible_text(text) 根据选项文本

弹出框

当界面存在弹出框时,必须先处理掉弹出框才能继续其它操作!

自定义弹出框

可以直接通过web浏览器开发者工具查看到具体的元素信息 通过元素定位后直接可以处理掉

JS弹出框

通过JS函数实现,通过web浏览器开发者工具无法查看到元素信息;
常见JS弹出框形式:alert(警告框)、confirm(确认框)、prompt(提示框) 不能通过元素定位进行处理
#获取弹出框对象
alert = driver.switch_to.alert #alert(警告框)、confirm(确认框)、prompt(提示框)

#弹出框处理方法
alert.text #获取弹出框文本
alert.accept() #接受弹出框
alert.dismiss() #取消弹出框

滚动条

#定义Js字符串
js = "window.scrollTo(0,1000)"

#执行Js字符串
driver.execute_script(js)

Frame切换

HTML页面中的一种框架,主要作用是在当前页面中指定区域显示另一页面元素 多个iframe时,需要切换到默认页面,再切换另一个iframe,才能获取对应iframe的元素

切换方法

driver.switch_to.frame(iframe标签元素对象)

恢复默认页面

driver.switch_to.default_content()

多窗口切换

多窗口:在HTML页面中,当点击超链接或者按钮时,有的会在新的窗口打开页面。 
Selenium只能定位当前窗口的元素,需要切换窗口才能定位其他窗口元素

切换方法

selenium需要通过窗口的句柄来实现窗口的切换! 
句柄:窗口的唯一标识码
#获取所有窗口句柄
handles = driver.window_handles

#切换指定窗口
driver.switch_to.window(handles[n])

截图

driver.get_screenshot_as_file(图片的路径)
1. 图片的格式 使用 png
2. 如果路径包含目录,目录必须存在

验证码处理

1.去掉验证码、万能验证码 
2.验证码识别技术 
3.记录cookie

Cookie操作方法

driver.get_cookie(name) --> 获取指定cookie

driver.get_cookies() --> 获取本网站所有本地cookies

driver.add_cookie(cookie_dict) --> 添加cookie
	cookie_dict:一个字典对象,必选的键包括:"name" and "value"

APP UI自动化

原生APP、H5、小程序

APP H5 小程序
运行环境 在操作系统的单独进程中(在 Android 中还可以开启多进程) 依托手机浏览器,包括 WebView 运行在微信的进程中,基于浏览器内核完全重构的一个内置解析器
开发成本 Android/iOS 多个平台、开发工具、开发语言、不同设备的适配等问题 涉及开发工具、前端框架、模块管理工具、任务管理工具,还有 UI 库选择、接口调用工具、浏览器兼容性等等 微信团队提供了开发者工具,并且规范了开发标准
系统权限 调用的是系统资源,也就是说系统提供给开发的的 API 都可以使用;可以给用户推送消息 H5作为一个网页,被封闭在浏览器这个沙箱内 微信可以赋予微信小程序更多特殊权限,比如录音,视频,罗盘,扫一扫,模板消息,客服消息,分享等;不允许主动给用户发送消息,只能回复模版消息
运行流畅度 所有的原生组件可以直接调用 GPU 进行渲染 运行速度慢,用户体验受限 小程序运行在微信的进程中,只能通过 WebView 进行渲染

Appium设计原理

 1.C/S架构,appium的核心是一个web服务器,提供了一套接口。他会接收客户端发送过来的命令,然后在移动设备上运行命令,最后把运行结果通过HTTP响应包返回给客户端。 2.session,每个client连接到server以后都会创建一个session,自动化始终围绕一个session进行。

adb工作原理

UIAutomatorViewer

用来获取APP的元素特征

基础Api

初始化配置项

from appium import webdriver

capabilities = {
    "platformName": "Android",	#需要连接的手机的平台(不限制大小写)
    "platformVersion": "7.1.2",	#需要连接的手机的版本号
    "deviceName": "模拟器",	#需要连接的手机的设备号(andoird平台下,可以随便写,但是不能不写)
    "appPackage": "com.android.settings",	#需要启动的程序的包名
    "appActivity": ".Settings"	#需要启动的程序的界面名
}

driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_capabilities=capabilities)

应用跳转

driver.start_activity(appPackage, appActivity)

获取包名和界面名

# 获取包名
driver.current_package

# 获取界面名
driver.current_activity

关闭驱动和app

# 关闭当前操作的app,不会关闭驱动对象
driver.close_app()

# 获取界面名
driver.quit()

安装和卸载以及是否安装 app

# 安装app,app_path为安装文件完整路径名
driver.install_app(app_path)

# 卸载app,app_id为app包名
driver.remove_app(app_id)

# 判断app是否安装,app_id为app包名
driver.is_app_installed(app_id)

置于后台

# 置于后台,seconds表示秒数
driver.background_app(seconds)

获取手机分辨率

driver.get_window_size()

获取手机截图

driver.get_screenshot_as_file(本地路径/图片名.png)

获取手机网络

driver.network_connection

设置手机网络类型

driver.set_network_connection("connectionType")

0 None
1 飞行模式
2 WiFi
4 数据流量
6 数据流量和WiFi

发送键到设备

driver.press_keycode(keycode)
keycode:表示手机设备的默认键码

Home 键(返回主页)	3
返回键	4
音量增加键	24
音量减少键	25
回车键	66

打开通知栏

appium官方没有关闭通知的api,现实怎么关闭就怎样操作,比如手指从下往上滑动,或者按返回键

#打开通知栏
driver.open_notifications()
#关闭通知栏
driver.press_keycode(4)

高级手势Api

swipe滑动

swipe滚动从一个坐标位置滑动到另一个坐标位置,只能是两个点之间的滑动

driver.swipe(start_x, start_y, end_x, end_y, duration=None)

start_x: 起点X轴坐标
start_y: 起点Y轴坐标
end_x: 终点X轴坐标
end_y: 终点Y轴坐标
duration: 滑动这个操作一共持续的时间长度,单位:ms

scroll滑动

scroll滑动是两个元素之间的滑动,从一个元素滑动到另一个元素,直到页面自动停止,惯性大速度快

driver.scroll(origin_el, destination_el)

origin_el:滑动开始的元素
destination_el: 滑动结束的元素

drag_and_drop拖拽

从一个元素滑动到另一个元素,第二个元素替代第一个元素原本屏幕上的位置,速度慢

driver.drag_and_drop(origin_el, destination_el)
origin_el:滑动开始的元素
destination_el: 滑动结束的元素

TouchAction-轻敲

模拟手指对某个元素或坐标按下并快速抬起

#创建TouchAction对象
touch_action = TouchAction(driver)
#调用轻敲,元素对象或坐标二选一
touch_action.tap(element=None,x=None,y=None)
#执行手势
touch_action.perform()

TouchAction-按下和抬起

模拟手指一直按下,模拟手指抬起。可以用来组合成轻敲或长按的操作

#创建TouchAction对象
touch_action = TouchAction(driver)
#调用按下,元素对象或坐标二选一
touch_action.press(el=None,x=None,y=None)
#调用抬起
touch_action.release()
#执行手势
touch_action.perform()

TouchAction-长按

模拟手指对元素或坐标的长按操作

TouchAction(driver).long_press(el=None,duration=1000).perform()
TouchAction(driver).long_press(x=None,y=None,duration=1000).perform()

TouchAction-移动和等待时间

模拟手指移动操作

#模拟手指对元素或坐标的移动操作。
TouchAction(driver).move_to(el=None,x=None,y=None).perform()
#模拟手指暂停到当前动作指定时间。
TouchAction(driver).wait(ms=time).perform()

定位单个元素

ID定位

driver.find_element(by=By.ID, value='resource-id属性值')

class定位

driver.find_element(by=By.CLASS_NAME, value='class属性值')

xpath定位

driver.find_element(by=By.XPATH, value='//*[@content-desc="xxx"]')

name定位

driver.find_element_by_accessibility_id("content-desc属性值")

定位一组元素

ID定位

driver.find_elements(by=By.ID, value='resource-id属性值')

class定位

driver.find_elements(by=By.CLASS_NAME, value='class属性值')

xpath定位

driver.find_elements(by=By.XPATH, value='//*[@content-desc="xxx"]')

name定位

driver.find_elements_by_accessibility_id("content-desc属性值")

元素模拟操作

模拟点击

element.click()

模拟输入

element.send_keys(value)

清除文本

element.clear()

获取元素信息

获取文本

element.text

获取位置

element.location	#xy值

获取大小

element.size

获取元素属性值

element.get_attribute("属性名")

获取resource-id > resourceId
获取content-desc > name
获取class > className
获取text > text

toast信息

 

安装实现

1.安装node.js。
node-v8.11.3-x64.msi(windows) 或 node-v8.10.0.pkg(mac) 进行安装

2.安装cnpm (使用cnpm验证)
npm install -g cnpm --registry=https://registry.npm.taobao.org

3.下载 appium-uiautomator2-driver
cnpm install appium-uiautomator2-driver

获取Toast并验证

desired_capabilities = {
    "platformName": "android",
    "platformVersion": "6",
    "deviceName": "emulator-5554",
    "appPackage": "com.amaze.filemanager",  # 包名
    "appActivity": ".activities.MainActivity",  # 界面名
    "automationName": "Uiautomator2"
}

# 连接(获取) driver
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_capabilities)
driver.implicitly_wait(10)
# 操作
# 点击返回键 触发 toast
driver.press_keycode(4)
# 获取
# toast_info = driver.find_element(By.XPATH, '//*[contains(@text, "返回键")]').text
# print(toast_info)

def get_toast_info(driver, message, timeout=2, poll=0.5):
    try:
        el = WebDriverWait(driver, timeout, poll).until(lambda x: x.find_element(By.XPATH, f'//*[contains(@text, "{message}")]'))
        return el.text
    except Exception as e:
        print(f'未获取到: {message} 相关的 toast 信息')

print(get_toast_info(driver, '返回键'))

WebView App测试

手机架浏览器页面上的元素不能直接通过UiAutoMatorView查看元素或定位,可以通过拷贝手机浏览器页面的网址,到PC端浏览器,元素定位通过web浏览器开发者工具查看
确定 Android System WebView 版本

在cmd 中输入:
adb shell am start -a android.intent.action.VIEW -d https://liulanmi.com/labs/core.html
在手机中查看: https://liulanmi.com/labs/core.html
环境搭建: 1.查看手机/模拟器内置浏览器版本,下载web端对应的浏览器驱动; 2.配置Appium工具驱动配置项Chromedriver Binary Path,直接填入下载的浏览器驱动程序完整文件路径名
# 1. 在手机浏览器中打开 百度
# 定位输入地址的 元素
driver.find_element(By.ID, 'com.android.browser:id/url').send_keys('www.baidu.com')
# 回车
driver.press_keycode(66)
time.sleep(15)
# 切换上下文
driver.switch_to.context(driver.contexts[-1])
# 2. 在搜索框输入 传智
driver.find_element(By.ID, 'index-kw').send_keys('传智')
time.sleep(2)
# 3. 点击搜索
driver.find_element(By.ID, 'index-bn').click()
# 4. 查看结果
time.sleep(3)

面试题

在你的项目中做过UI自动化,简单说说你是如何做的?

 

该问题根据自己的实际情况还选择实施的程度:1、只会Selenium基本API编写面向过程脚本;2、能使用单元测试框架组织测试用例,不需要任何封装;3、能编写完整的自动化测试框架

程度1:有简单的了解过Web自动化脚本的编写,使用的是Selenium工具,在之前的项目里面基于***功能编写了一些自动化面向过程的脚本,利用元素定位和常用API实现模拟手工操作。利用这些脚本可以在测试过程中去代替一些手工构造测试数据的过程。对于单元测试框架Unittest/Pytest有一定得了解,可以参考一些文案写出简单的单元测试用例。

程度2:在***项目中,基于自己所负责的模块有利用自己的时间,使用单元测试框架Pytest+Selenium编写过一些功能的自动化测试脚本,例如实现主流程的自动化测试用例,***功能的测试用例。并使用单元测试框架中Parameter实现了参数化,以及assert断言。可以利用Pytest实现批量执行测试用例,结合Allure插件生成测试报告。

程度3:在***项目中,由于经常有版本迭代,回归测试任务还是比较多的。部分核心的功能模块界面也比较稳定,为了提供回归测试效率,团队采用了UI自动化测试技术来解决回归测试的问题。我们使用的实现技术框架为:pytest单元测试框架+Selenium/Appium+PO页面对象的封装模式+Allure测试报告的框架来实现的UI自动化。整个项目过程中,也没有专门规划一段时间去一次性完成整体的自动化,而是测试经理规划好整体实现框架后,在版本迭代空闲时间,分配一些脚本编写的任务。在我离开公司时,UI自动化测试用例库已经基本覆盖到了项目核心功能点和流程。如***流程、***功能模块。其中***是我编写的。

最常用的元素定位方法是什么?如果元素定位不到你会如何分析?

最常用的元素定位方法是XPATH,当然也会根据实际情况用一些其它的定位方式,例如:CSS等

定位不到元素无非以下几种情况,一般情况下我会从简单的开始分析:1、先确认是否定位信息写错,2、再确认是否有窗口切换;3、查看元素是否在iframe标签中;4、元素等待的问题;5、定位代码前面的步骤就有问题,导致没有到所要定位元素界面等等。基本上定位不到元素的问题都可以解决掉。

显示等待和隐式等待的区别是什么?哪个用的多?为什么?

显示等待和隐式等待的核心区别在于:隐式是一个全局设置,显示只针对单个元素;隐式等待受整个页面加载的影响,而显示等待只要所要定位的元素加载到就可以继续运行。还有实现方法、超时异常有区别。

其实都会用,隐式等待本身就只有设置一次,在创建浏览器驱动对象的时候就会加上。而显示等待会基于对Selenium元素定位的方法进行二次封装,后续调用元素定位方法时都会调用二次封装后的元素定位代码.所有的元素定位都会对于显示等待生效。而有隐式等待多了一重元素等待的保障。

有没有做过二次封装?封装了哪些方法?简单的描述下?

有的!例如元素定位方法,会进行显示等待,会兼容8种元素定位的方法的封装;如模拟输入:基于原有的send_keys方法输入之前,加上模拟清除的操作;再例如窗口切换、Select下拉框等多行实现的操作方法都会进行二次封装。这些封装的代码我们都会放在一个基类中统一的进行管理。

UI自动化解决了什么问题?你觉得其价值大不大?主要体现在哪里?

个人觉得UI自动化测试核心解决的问题还是解决手工回归测试,基于历史功能或流程进行回归,代替绝大部分的回归测试工具,缩减测试工程的重复的工作。第二:UI自动化的脚本还可以通过运行来准备测试数据,例如我要测试生成订单后的各种流程,就可以通过运行生成订单的测试用例。

我觉得UI自动化测试脚本如果编写的比较全面的话,价值还是很大的。就例如上面说的回归测试和构造数据,不过前提是项目适合做UI自动动。否则就是白白投入。

微信小程序如何执行UI自动化测试?

方式一:(微信小程序依托微信基于WebView渲染,采用WebView APP UI自动化测试的方式)
	1.开启微信X5调试开关;
	2.科学上网,PC端Chrome输入chrome://inspect/#devices;
	3.打开APP的微信小程序,PC端Chrome的inspect功能,可以显示小程序界面,并定位元素;
	4.下载APP端Chrome版本号对应的webdriver驱动;
	5.appium配置界面设置webdriver驱动,或者在UI自动化初始化链接代码里,设置webdriver驱动路径
	6.通过切换上下文的方式,使用inspect定位到的元素开展UI自动化;

方式二:
	使用网易的AirTest UI自动化测试框架,其支持微信小程序和小游戏,AirTest支持录制、元素定位、执行测试脚本、生产测试报告。

简单的说下PO模式的设计思想?

所谓的PO吧,就是Page Object页面对象,利用面向对象的思维来封装我们的UI自动化测试用例。

PO模式就是把我们测试过程中每个页面都当做对象,在我们的UI自动化测试框架中,每个页面都有一个独立的封装py文件,分为三层来管理:第一层是对象库层,将测试用例在该页面所有用到的元素对象统一找到并进行管理,第二层操作层:基于每个元素定义好其对应的操作方法,第三层:业务层,组装多个操作方法即可形成完整的业务操作。

例如:登录页面:对象库层找到用户名、密码等元素,操作层封装用户名输入、密码输入等方法,业务层连续调用操作层方法,那调用业务层的登录方法传递输入参数即可完成登录。这样无论哪个测试用例需要进行登录,都只需要调用该页面py文件业务层的登录方法,即可完成登录。这样整个UI自动化测试代码中,对应的元素定位代码只会存在一份了,方便了维护,也减少了代码的冗余。

如何定位属性动态变化的元素?

一般看到元素属性里有拼接一串数字的,就很有可能是动态的

xpath中提供了三个非常好的方法来为我们定位部分属性值:

driver.find_element(By.XPATH,"//div[contains(@id, 'auto-id')]") 
driver.find_element(By.XPATH,"//div[starts-with(@id, 'auto-id')]") 
driver.find_element(By.XPATH,"//div[ends-with(@id, 'auto-id')]")

contains(a, b) 如果a中含有字符串b,则返回true,否则返回false
starts-with(a, b) 如果a是以字符串b开头,返回true,否则返回false
ends-with(a, b) 如果a是以字符串b结尾,返回true,否则返回false

webdriver client的原理?

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ShylockJIE/article/details/122946993

智能推荐

攻防世界_难度8_happy_puzzle_攻防世界困难模式攻略图文-程序员宅基地

文章浏览阅读645次。这个肯定是末尾的IDAT了,因为IDAT必须要满了才会开始一下个IDAT,这个明显就是末尾的IDAT了。,对应下面的create_head()代码。,对应下面的create_tail()代码。不要考虑爆破,我已经试了一下,太多情况了。题目来源:UNCTF。_攻防世界困难模式攻略图文

达梦数据库的导出(备份)、导入_达梦数据库导入导出-程序员宅基地

文章浏览阅读2.9k次,点赞3次,收藏10次。偶尔会用到,记录、分享。1. 数据库导出1.1 切换到dmdba用户su - dmdba1.2 进入达梦数据库安装路径的bin目录,执行导库操作  导出语句:./dexp cwy_init/[email protected]:5236 file=cwy_init.dmp log=cwy_init_exp.log 注释:   cwy_init/init_123..._达梦数据库导入导出

js引入kindeditor富文本编辑器的使用_kindeditor.js-程序员宅基地

文章浏览阅读1.9k次。1. 在官网上下载KindEditor文件,可以删掉不需要要到的jsp,asp,asp.net和php文件夹。接着把文件夹放到项目文件目录下。2. 修改html文件,在页面引入js文件:<script type="text/javascript" src="./kindeditor/kindeditor-all.js"></script><script type="text/javascript" src="./kindeditor/lang/zh-CN.js"_kindeditor.js

STM32学习过程记录11——基于STM32G431CBU6硬件SPI+DMA的高效WS2812B控制方法-程序员宅基地

文章浏览阅读2.3k次,点赞6次,收藏14次。SPI的详情简介不必赘述。假设我们通过SPI发送0xAA,我们的数据线就会变为10101010,通过修改不同的内容,即可修改SPI中0和1的持续时间。比如0xF0即为前半周期为高电平,后半周期为低电平的状态。在SPI的通信模式中,CPHA配置会影响该实验,下图展示了不同采样位置的SPI时序图[1]。CPOL = 0,CPHA = 1:CLK空闲状态 = 低电平,数据在下降沿采样,并在上升沿移出CPOL = 0,CPHA = 0:CLK空闲状态 = 低电平,数据在上升沿采样,并在下降沿移出。_stm32g431cbu6

计算机网络-数据链路层_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输-程序员宅基地

文章浏览阅读1.2k次,点赞2次,收藏8次。数据链路层习题自测问题1.数据链路(即逻辑链路)与链路(即物理链路)有何区别?“电路接通了”与”数据链路接通了”的区别何在?2.数据链路层中的链路控制包括哪些功能?试讨论数据链路层做成可靠的链路层有哪些优点和缺点。3.网络适配器的作用是什么?网络适配器工作在哪一层?4.数据链路层的三个基本问题(帧定界、透明传输和差错检测)为什么都必须加以解决?5.如果在数据链路层不进行帧定界,会发生什么问题?6.PPP协议的主要特点是什么?为什么PPP不使用帧的编号?PPP适用于什么情况?为什么PPP协议不_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输

软件测试工程师移民加拿大_无证移民,未受过软件工程师的教育(第1部分)-程序员宅基地

文章浏览阅读587次。软件测试工程师移民加拿大 无证移民,未受过软件工程师的教育(第1部分) (Undocumented Immigrant With No Education to Software Engineer(Part 1))Before I start, I want you to please bear with me on the way I write, I have very little gen...

随便推点

Thinkpad X250 secure boot failed 启动失败问题解决_安装完系统提示secureboot failure-程序员宅基地

文章浏览阅读304次。Thinkpad X250笔记本电脑,装的是FreeBSD,进入BIOS修改虚拟化配置(其后可能是误设置了安全开机),保存退出后系统无法启动,显示:secure boot failed ,把自己惊出一身冷汗,因为这台笔记本刚好还没开始做备份.....根据错误提示,到bios里面去找相关配置,在Security里面找到了Secure Boot选项,发现果然被设置为Enabled,将其修改为Disabled ,再开机,终于正常启动了。_安装完系统提示secureboot failure

C++如何做字符串分割(5种方法)_c++ 字符串分割-程序员宅基地

文章浏览阅读10w+次,点赞93次,收藏352次。1、用strtok函数进行字符串分割原型: char *strtok(char *str, const char *delim);功能:分解字符串为一组字符串。参数说明:str为要分解的字符串,delim为分隔符字符串。返回值:从str开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。其它:strtok函数线程不安全,可以使用strtok_r替代。示例://借助strtok实现split#include <string.h>#include <stdio.h&_c++ 字符串分割

2013第四届蓝桥杯 C/C++本科A组 真题答案解析_2013年第四届c a组蓝桥杯省赛真题解答-程序员宅基地

文章浏览阅读2.3k次。1 .高斯日记 大数学家高斯有个好习惯:无论如何都要记日记。他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?高斯出生于:1777年4月30日。在高斯发现的一个重要定理的日记_2013年第四届c a组蓝桥杯省赛真题解答

基于供需算法优化的核极限学习机(KELM)分类算法-程序员宅基地

文章浏览阅读851次,点赞17次,收藏22次。摘要:本文利用供需算法对核极限学习机(KELM)进行优化,并用于分类。

metasploitable2渗透测试_metasploitable2怎么进入-程序员宅基地

文章浏览阅读1.1k次。一、系统弱密码登录1、在kali上执行命令行telnet 192.168.26.1292、Login和password都输入msfadmin3、登录成功,进入系统4、测试如下:二、MySQL弱密码登录:1、在kali上执行mysql –h 192.168.26.129 –u root2、登录成功,进入MySQL系统3、测试效果:三、PostgreSQL弱密码登录1、在Kali上执行psql -h 192.168.26.129 –U post..._metasploitable2怎么进入

Python学习之路:从入门到精通的指南_python人工智能开发从入门到精通pdf-程序员宅基地

文章浏览阅读257次。本文将为初学者提供Python学习的详细指南,从Python的历史、基础语法和数据类型到面向对象编程、模块和库的使用。通过本文,您将能够掌握Python编程的核心概念,为今后的编程学习和实践打下坚实基础。_python人工智能开发从入门到精通pdf

推荐文章

热门文章

相关标签