赞
踩
软件测试的自动化一般可以分为3层 * 代码层的单元测试 * 接口层的集成测试 * UI 层的测试
代码层的自动化一般指针对代码进行的单元测试,比较常用的单元测试框架比如Java的Junit, Python的PyUnit等等,由于这部分并非本教程重点,这里就不详细展开,需要的同学可以自行学习。
接口层的自动化测试主要是对系统和组建之间的接口进行测试,主要目标是校验数据的交换和业务的流程,接口测试可以测试功能、也可以测试性能、测试压力、测试安全等等。由于接口比代码单元要稳定的很多,所以自动化脚本维护成本更低、收益也更大,具有不错的性价比。常用的测试工具有以下:
- Jmeter:由Apache组织开发的基于Java的接口测试、压力测试和性能测试工具,起初为Web测试而设计,后来逐步扩展到其他领域,可以用来测试静态或者动态的资源。
-
- LoadRunner:HP公司提供的一款性能测试和压力测试工具,可以通过模拟成千上万用户实施并发操作来测试系统性能,并且有详细的测试结果分析,是性能测试和压测的不错选择。
-
- Robot Framework: 一款开源的自动化测试框架,具有很好的可扩展性。框架用python编写,同时也提供跨平台支持。
-
- Postman:简单方便且功能强大的接口调试工具,API调试首选。
基于UI层的自动化测试框架要复杂很多,从平台种类来讲,有Windows,Linux,Android,Ios,Web,还有最新的小程序等等,下面会简单的和大家捋一遍主流UI层自动化框架的原理、架构以及跨平台能力。
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是一款开源的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和Poco,二者的区别在于:
Airtest:基于Python的、跨平台的UI自动化测试框架,基于图像识别原理,适用于游戏和App。 Poco:基于UI控件搜索的自动化测试框架,其核心优势是除了对Android、IOS之外,对游戏也是支持的,同时也支持微信小程序、微信小游戏和H5应用。
整套框架配备了非常实用的IDE,通过AirtestIDE, 可以轻松的完成脚本的录制、测试任务的执行以及最后测试报告的生成。
WebDriver 如果你开始使用桌面网站或移动网站测试自动化,那么你将使用 webdriverapi。 Webdriver 使用浏览器厂商提供的浏览器自动化 api 来控制浏览器和运行测试。 这就好像是一个真正的用户在操作浏览器。 由于 WebDriver 不需要使用应用程序代码编译其 API,因此它不具有侵入性。 因此,您测试的应用程序与实时推送的应用程序相同。 IDE Ide (集成开发环境)是您用来开发 Selenium 测试用例的工具。 它是一个易于使用的 Chrome 和 Firefox 扩展,并且通常是开发测试用例的最有效的方法。 它使用现有的 Selenium 命令记录用户在浏览器中的操作,参数由该元素的上下文定义。 这不仅是一个节省时间的方法,也是学习 Selenium 脚本语法的一个很好的方法。 Grid Selenium Grid 允许您跨不同平台在不同的机器上运行测试用例。 触发测试用例的控制位于本地端,当触发测试用例时,它们将由远程端自动执行。在 WebDriver 测试开发之后,您可能需要在多个浏览器和操作系统组合上运行测试。 这就是Grid出现的地方。
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.浏览器再把执行的动作结果通过浏览器驱动程序返回给测试脚本
浏览器实现了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"
driver.find_element(by=By.ID, value='id属性值')
绝对路径
概念:从最外层元素到指定元素之间所有经过的元素层级的路径--不建议使用 写法:绝对路径以/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,'局部属性值')]
- 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*='局部属性值']')
driver.find_element(by=By.NAME, value='name属性值')
driver.find_element(by=By.CLASS_NAME, value='class属性值')
driver.find_element(by=By.TAG_NAME, value='标签名')
driver.find_element(by=By.LINK_TEXT, value='链接文本')
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()
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- 窗口最大化 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()
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- 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函数实现,通过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)
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 | H5 | 小程序 | |
---|---|---|---|
运行环境 | 在操作系统的单独进程中(在 Android 中还可以开启多进程) | 依托手机浏览器,包括 WebView | 运行在微信的进程中,基于浏览器内核完全重构的一个内置解析器 |
开发成本 | Android/iOS 多个平台、开发工具、开发语言、不同设备的适配等问题 | 涉及开发工具、前端框架、模块管理工具、任务管理工具,还有 UI 库选择、接口调用工具、浏览器兼容性等等 | 微信团队提供了开发者工具,并且规范了开发标准 |
系统权限 | 调用的是系统资源,也就是说系统提供给开发的的 API 都可以使用;可以给用户推送消息 | H5作为一个网页,被封闭在浏览器这个沙箱内 | 微信可以赋予微信小程序更多特殊权限,比如录音,视频,罗盘,扫一扫,模板消息,客服消息,分享等;不允许主动给用户发送消息,只能回复模版消息 |
运行流畅度 | 所有的原生组件可以直接调用 GPU 进行渲染 | 运行速度慢,用户体验受限 | 小程序运行在微信的进程中,只能通过 WebView 进行渲染 |
1.C/S架构,appium的核心是一个web服务器,提供了一套接口。他会接收客户端发送过来的命令,然后在移动设备上运行命令,最后把运行结果通过HTTP响应包返回给客户端。 2.session,每个client连接到server以后都会创建一个session,自动化始终围绕一个session进行。
用来获取APP的元素特征
- 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,不会关闭驱动对象
- driver.close_app()
-
- # 获取界面名
- driver.quit()
- # 安装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)
- 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滑动是两个元素之间的滑动,从一个元素滑动到另一个元素,直到页面自动停止,惯性大速度快
-
- driver.scroll(origin_el, destination_el)
-
- origin_el:滑动开始的元素
- destination_el: 滑动结束的元素
- 从一个元素滑动到另一个元素,第二个元素替代第一个元素原本屏幕上的位置,速度慢
-
- driver.drag_and_drop(origin_el, destination_el)
- origin_el:滑动开始的元素
- destination_el: 滑动结束的元素
- 模拟手指对某个元素或坐标按下并快速抬起
-
- #创建TouchAction对象
- touch_action = TouchAction(driver)
- #调用轻敲,元素对象或坐标二选一
- touch_action.tap(element=None,x=None,y=None)
- #执行手势
- touch_action.perform()
模拟手指一直按下,模拟手指抬起。可以用来组合成轻敲或长按的操作
- #创建TouchAction对象
- touch_action = TouchAction(driver)
- #调用按下,元素对象或坐标二选一
- touch_action.press(el=None,x=None,y=None)
- #调用抬起
- touch_action.release()
- #执行手势
- touch_action.perform()
模拟手指对元素或坐标的长按操作
- TouchAction(driver).long_press(el=None,duration=1000).perform()
- TouchAction(driver).long_press(x=None,y=None,duration=1000).perform()
模拟手指移动操作
- #模拟手指对元素或坐标的移动操作。
- TouchAction(driver).move_to(el=None,x=None,y=None).perform()
- #模拟手指暂停到当前动作指定时间。
- TouchAction(driver).wait(ms=time).perform()
driver.find_element(by=By.ID, value='resource-id属性值')
driver.find_element(by=By.CLASS_NAME, value='class属性值')
driver.find_element(by=By.XPATH, value='//*[@content-desc="xxx"]')
driver.find_element_by_accessibility_id("content-desc属性值")
driver.find_elements(by=By.ID, value='resource-id属性值')
driver.find_elements(by=By.CLASS_NAME, value='class属性值')
driver.find_elements(by=By.XPATH, value='//*[@content-desc="xxx"]')
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
- 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
- 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, '返回键'))
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
手机架浏览器页面上的元素不能直接通过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)
该问题根据自己的实际情况还选择实施的程度: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自动动。否则就是白白投入。
方式一:(微信小程序依托微信基于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吧,就是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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。