1.怎么判断元素是否存在?
判断元素是否存在和是否出现不同, 判断是否存在意味着如果这个元素压根就不存在, 就会抛出NoSuchElementException
这样就可以使用try catch,如果catch到NoSuchElementException 就返回false。通常在项目中会把这个功能封装在isElementPresent方法中。
2.如何判断元素是否出现?
判断元素是否出现,存在两种情况,一种是该元素压根就没有,自然不会出现;另外一种是有这样的元素,但是是hidden状态
可以通过先判断是否存在,如果不存在返回false;如果存在再去判断是否displayed。
5. 如何去定位页面上动态加载的元素?
触发动态事件,然后findElemnt
如果是动态菜单,需要一级一级find(JS实现)
6.如何去定位属性动态变化的元素?
属性动态变化是指该element没有固定的属性值,所以只能通过相对位置定位
比如通过xpath的轴, parent/following-sibling/precent-sibling等
另外也可以尝试findbyelements遍历
8.自动化测试的时候是否需要连接数据库做数据校验?
一般来说1、 UI自动化不需要(很少需要);2、接口测试会需要:从数据库层面来进行数据校验可以更方便验证系统的数据处理方面是否正确;
9.有几种元素常用定位方式,分别是?你最偏爱哪一种,为什么?
8种:id、name、class name、tag name、link text、partial link text、xpath、css selector 偏爱哪一种?答:
我最常用的是xpath(或CssSelector)因为很多情况下,html标签的属性不够规范,无法通过单一的属性定位,这个时候就只能使用xpath可以去重实现定位唯一element
事实上定位最快的是Id,因为id是唯一的,然而大多数开发并没有设置id。
10.怎么提高selenium脚本的自动化执行效率?
1.优化测试用例,尽可不使用 sleep,减少使用ImplicitlyWait
2.多使用selenium的WebDriverWait/FluentWait,这样可以优化等待时间
3.减少不必要的操作步骤,如经过三四步才能打开我们要测试的页面的话,我们就可以直接通过网址来打开,减少不必要的操作。
4.中断页面加载,如果页面加载的内容过多,我们可以查看一下加载慢的原因,如果加载的内容不影响我们测试,就设置超时时间,中断页面加载。
5.使用性能好的电脑
11.用例在运行过程中经常会出现不稳定的情况,也就是这次可以通过,下次无法通过了,如何提高用例的稳定性?
1,查找元素前先做判断:ExpectedConditions里面的各种方法;
2,显式等待:多使用WebDriverWait,加上显式等待时间,等要操作的元素出现之后再执行下面的操作;
3、多用try catch捕获异常;
4,多线程的时候,减少测试用例耦合度,因为多线程的执行顺序是不受控制的;
5,尽量使用测试专用环境,避免其他类型的测试同时进行,对数据造成干扰。
12.你的自动化用例的执行策略是什么?
1.自动化测试用例是用来监控的。集成到jenkins,创建定时任务定时执行;
2.有些用例在产品上线前必须回归。jenkins上将任务绑定到开发的build任务上,触发执行;
3.有些用例不需要经常执行。jenkins创建一个任务,需要执行的时候人工构建即可。
13.什么是持续集成?
频繁的将代码集成到主干,持续性的进行项目的构架,以便能能够快速发现错误,防止分支大幅度偏离主干
14.webdriver client的原理是什么?
在selenium启动以后,driver充当了服务器的角色,跟client和浏览器通信,client根据webdriver协议发送请求给driver。driver解析请求,并在浏览器上执行相应的操作,并把执行结果返回给client.
15.webdriver的协议是什么?
The Wire Protocol
16.启动浏览器的时候用到的是哪个webdriver协议?
http
18.怎样去选择一个下拉框中的value=xx的option?
1.select类里面提供的方法:selectByValue(“xxx”)
2.xpath的语法也可以定位到
9 Appium 与 Selenium的关系
selenium是web端的自动化,appium是app端的自动化,appium继承了webdriver(也就是selenium 2)
10 appium原理(加载流程)
调用Andorid adb完成基本的系统操作
2)向Andriod上部署bootstrap.jar包并启动
3)Forward Android 的端口到PC的机器上
4)PC上监听端口接受请求,使用webdriver协议
5)分析命令并转通过forward的端口发给bootstrap.jar包
6)bootstrap接受请求并把命令发给UiAutomator或插桩体系
一、Appium adb命令和问题
1、手机和电脑连接,打开手机的开发者模式打开USB调试
2、CMD中查看手机UDID:
adb devices
3、CMD启动appium服务:
appium -a 127.0.0.1 -p 4723 –U 手机的UDID --no-reset
3、CMD中查看安卓版本号:
adb shell getprop ro.build.version.release
4、获取apppackage和appactivite
Ⅰ 通过打印日志获取:通过CMD(管理员运行)adb logcat>C:log.txt;点击真机或者模拟器中的应用后,按ctrl+c终止会生成的log日志;在日志中查找 Displayed定位元素
Ⅱ 通过CMD获取:打开应用后输入:adb shell dumpsys activity | findstr "mFocusedActivity 或者 adb shell dumpsys window w |findstr / |findstr name=
5、解决代码完善运行后,程序无响应问题
Ⅰ 直接CMD输入命令 adb shell 进入手机
Ⅱ 进入手机之后,进入cd data/local/tmp
III 进入data/local/tmp 后输入 ls 查看全部目录,应该有一个AppiumBootstrap.jar,可能你的名字是AppiumBoots或者AppiumBootstrap.j
Ⅳ 输入 mv 加上查到的文件名 AppiumBootstrap.jar 命令解决,将你的文件名改为 AppiumBootstrap.jar
6、uiautomat程序元素定位报错:
打开CMD输入 adb kill-server 然后输入 adb start-server
二、Appium基础API
1、连接手机前置代码,缺一不可
from appium import webdriver
desired_caps = {}
desired_caps[‘platformName’] = ‘Android’ # 系统
desired_caps[‘platformVersion’] = ‘5.1’ # 系统版本号
desired_caps[‘deviceName’] = ‘8681-M02-0x14074b65’ # 手机UDID
desired_caps[‘appPackage’] = ‘com.android.settings’ # 应用包名、启动名
desired_caps[‘appActivity’] = ‘.Settings’
解决中文不能输入问题
desired_caps[‘unicodeKeyboard’] = True
desired_caps[‘resetKeyboard’] = True
声明driver对象
driver = webdriver.Remote(‘http://localhost:4723/wd/hub’, desired_caps)
2、获取包名启动名
current_XXXXX
3、启动其他程序
driver.start_activity(’ com.android.mms’,’.ui.ConversationList’)
4、置于后台
backround_app(秒)
5、定位元素
又分为id、class、xpath
其中,element获取到的是一个元素,如果有相同的特征获取到的是第一个
其中,element获取到的是一个列表,如果想用其中的元素,需要通过下标的形式
ele = driver.find_element_by_id(‘miui:id/arrow_right’) id 定位
black_buttion = driver.find_element_by_xpath("//*[contains(@text,‘canshuID’)]") xpath 模糊定位
black_buttion = driver.find_element_by_class_name(‘android.widget.ImageView’)fing_elements class 定位
6、显示等待
ele = WebDriverWait(driver,超时时间,频率) # 每10s查找1次
导入工具包:from selenium.webdriver.support.wait import WebDriverWait
如果找到元素返回,否则会报超时错误
7、元素的操作
以下操作都是使用某个元素调用某个函数/属性(不是driver)
点击:click()
输入文字:send_keys(’’)
清空:clear
定时时间:time.sleep(秒) 导入工具包 import time
获取元素的文本内容:元素.text
获取元素的属性值:元素.attr
获取元素的坐标:元素.location (元素左上角到屏幕右上角的内容)
三、Appium的滑动和拖拽
1、获取时间戳
含义:从1970到现在过了多少秒
print(time.time())
导入工具包:import.time
2、swipe坐标滑动
从一个坐标位置滑动到另一个坐标位置,只能是两个点之间的滑动
swipe是通过driver使用的
传入起始的位置X和Y 和 结束的位置X和Y;时间参数越长滑动的越精准
s wipe(self,start_x: int,start_y: int,end_x: int,end_y: int,滑动时间)
driver.swipe(100,100,100.100,3000)
3、scroll元素滑动
从一个元素滑动到另一个元素,直到页面静止
方法:scroll(origin_el,destination_el)
参数:origin_el:滑动开始的元素 destination_el:滑动结束的元素
代码:
el1 = driver.find_element_by_xpath("//[contains(@text,‘存储’)]")
el2 = driver.find_element_by_xpath("//[contains(@text,‘蓝牙’)]")
driver.scroll(el1,el2)
4、drag拖拽
从一个元素滑动到另一个元素,第二个元素代替第一个元素原本屏幕上的位置
方法:drag_and_drop(origin_el,destination_el)
代码:
el1 = driver.find_element_by_xpath("//[contains(@text,‘存储’)]")
el2 = driver.find_element_by_xpath("//[contains(@text,‘蓝牙’)]")
driver.drag_and_drop(el1,el2)
driver.drag_and_drop(el1,el2) #会记录原来的位置,划三次屏
driver.drag_and_drop(el1,el2)
scroll和drag的区别 drag没有惯性
相同点:都是使用元素进行传参;当swipe的时间足够长的时候,和drag的效果相同
四、高级手势TouchAction (导入模块import…)
主要针对手势的操作,比如滑动、长按、拖动等
所有手势都要通过perform()函数才会运行
1、手指轻敲操作
模拟手指轻敲一下屏幕操作
方法:tap(element=None,x=None,y=None)
perform() # 发送命令到服务器执行操作
参数:1、element:被定位到的元素
2、x:相当于元素左上角的坐标,通常会使用元素的x轴坐标
3、y:通常会使用元素的Y轴坐标
代码:
1、通过元素定位方式敲击屏幕
el = driver.find_element_by_xpath("//*[contains(@text,‘存储’)]")
TouchAction(driver).tap(el).perform()
2、通过坐标方式敲击屏幕
TouchAction(driver).tap(x=155,y=250).perform()
2、手指按下和抬起
模拟手指按下屏幕和离开
方法:press(el=None,x=None,y=None)
release() # 结束动作,手指离开屏幕
参数:1、element:被定为到的元素
2、x:相当于元素左上角的坐标,通常会使用元素的x轴坐标
3、y:通常会使用元素的Y轴坐标
代码:
1、通过元素定位方式敲击屏幕
el = driver.find_element_by_xpath("//*[contains(@text,‘存储’)]")
TouchAction(driver).press(el).release().perform()
2、通过坐标方式按下屏幕
TouchAction(driver).press(x=155,y=250).release().perform()
3、等待时间
TouchAction(driver).press(x=155,y=250).wait().release().perform()
4、手指长按操作
模拟手机按下屏幕一段时间和离开
方法:long_press(el=None,x=None,y=None,duration=1000)
参数:1、element:被定为到的元素
2、x:相当于元素左上角的坐标,通常会使用元素的x轴坐标
3、y:通常会使用元素的Y轴坐标
4、duration:持续时间,默认为1000ms
代码:
button = driver.find_element_by_xpath("//*[contains(@text,‘WLAN’)]")
button.click()
el = driver.find_element_by_id(‘android:id/title’)
TouchAction(driver).long_press(el,duration=1000).release().perform()
5、手指移动操作
模拟手指滑动操作
方法:move_to(el=None,x=155,y=250)
参数:1、element:被定为到的元素
2、x:相对于前一个元素的X轴偏移量
3、y:相对于前一个元素的Y轴偏移量
代码:
el = driver.find_element_by_xpath("//[contains(@text,‘存储’)]")
el1 = driver.find_element_by_xpath("//[contains(@text,‘更多’)]")
TouchAction(driver).press(x=240,y=600).wait(100).move_to(x=100,y=100).release().perform()
五、手机操作API
1、获取时间
方法:device_time
代码:print(driver.device_time)
2、获取手机的宽高
获取手机的高度,可以根据宽高做一些坐标操作
方法:get_window_size()
代码:print(driver.get_window_size())
3、发送键到设备 (可参照百度Android keycode)
模拟系统键值的操作,比如操作home键,音量键,返回键等
方法:keyevent(keycode,metastatate=None):
press_keycode(keycode,metastatate=None):
参数:1、keycode:发送给设备的关键代码
2、metastatate:关于被发送的关键代码的源信息,一般为默认值
代码:
for i in range(3)
driver.keyevent(24) 24为+ 25为-
4、操作手机通知栏
打开手机的通知兰,可以获取通知栏的相关信息和元素操作
方法:open_notifications()
代码:driver.open_notifications()
5、获取手机当前网络
获取手机当前连接网络
方法:network_connection
代码:print(driver.network_connection)
6、设置手机网络
更改手机网络模式,模拟特殊网络情况下的测试用例
方法:set_network_connection(connectionType)
参数:1、connectionType:需要被设备成为的网络类型
代码:
driver.set_network_connection(1)
7、手机截图
截取手机当前屏幕,保存指定格式图片到指定位置
方法:get_screenshot_at_file(filename)
参数:filename:制定路径下,制定格式的图片
代码:
import os
driver.get_screenshot_as_file(’./XXXX.png’)