软件测试之⾃动化测试常⽤函数(沉淀中)
文章目录
- 重点
- 1. 元素的定位
- 1.1 cssSelector
- 1.2 xpath
- 1.2.1 获取HTML⻚⾯所有的节点
- 1.2.2 获取HTML⻚⾯指定的节点
- 1.2.3 获取⼀个节点中的直接⼦节点
- 1.2.4 获取⼀个节点的⽗节点
- 1.2.5 实现节点属性的匹配
- 1.2.6 使⽤指定索引的⽅式获取对应的节点内容
- 2. 操作测试对象
- 2.1 点击/提交对象
- 2.2 模拟按键输⼊
- 2.3 清除⽂本内容
- 2.4 获取⽂本信息
- 2.5 获取当前⻚⾯标题
- 2.6 获取当前⻚⾯URL
- 3. 窗⼝
- 3.1 切换窗⼝
- 3.2 窗⼝设置⼤⼩
- 3.3 屏幕截图 (非常重要)
- 3.4 关闭窗⼝
- 4. 弹窗
- 4.1 警告弹窗+确认弹窗
- 4.2 提⽰弹窗
- 5. 等待
- 5.1 强制等待
- 5.2 隐式等待 (非常重要)
- 5.3 显⽰等待
- 6. 浏览器导航
- 7. ⽂件上传
- 8. 浏览器参数设置
- 总结
重点
• 元素定位
• 操作测试对象
• 窗⼝
• 等待
• 导航
• 弹窗
• ⽂件上传
• 浏览器参数
自动化测试常见函数
find_element(方式,“元素”) 查找一个元素
find_elements(方式,“元素”) 查找多个元素
查找元素的方式:
选择器,xpath,ID,class_name…
常用的主要由cssSelecttor和xpath
开发者工具快捷键:
1. 元素的定位
web⾃动化测试的操作核⼼是能够找到⻚⾯对应的元素,然后才能对元素进⾏具体的操作。
常⻅的元素定位⽅式⾮常多,如id,classname,tagname,xpath,cssSelector
id选择器:
常⽤的主要由cssSelector和xpath
1.1 cssSelector
选择器的功能:选中⻚⾯中指定的标签元素
选择器的种类分为基础选择器和复合选择器,常⻅的元素定位⽅式可以通过id选择器和⼦类选择器来
进⾏定位
定位百度⾸⻚的“百度热搜”元素,可以使⽤通过id选择器和⼦类选择器进⾏定位: #shotsearch-wrapper > div
“搜索输⼊框元素”: #kw
“百度⼀下按钮”: #su
1.2 xpath
XML路径语⾔,不仅可以在XML⽂件中查找信息,还可以在HTML中选取节点。
xpath使⽤路径表达式来选择xml⽂档中的节点
xpath语法中:
1.2.1 获取HTML⻚⾯所有的节点
//*
eg:
//*[@id=“hotsearch-content-wrapper”]/li[3]/a
1.2.2 获取HTML⻚⾯指定的节点
//[指定节点]
//ul :获取HTML⻚⾯所有的ul节点
//input:获取HTML⻚⾯所有的input节点
1.2.3 获取⼀个节点中的直接⼦节点
/
//span/input
eg:
//[@id=“hotsearch-content-wrapper”]/li[7]/a
li[7]找第三个标签
eg://[@id=“hotsearch-content-wrapper”]/li[7]/a/span[2]
1.2.4 获取⼀个节点的⽗节点
…
//input/… 获取input节点的⽗节点
1.2.5 实现节点属性的匹配
[@…]
//*[@id=‘kw’] 匹配HTML⻚⾯中id属性为kw的节点
1.2.6 使⽤指定索引的⽅式获取对应的节点内容
注意:xpath的索引是从1开始的。
百度⾸⻚通过://div/ul/li[3] 定位到第三个百度热搜标签
更便捷的⽣成selector/xpath的⽅式:右键选择复制"Copy selector/xpath"
案例:如果想要匹配到百度⾸⻚指定的新闻⽂本或者节点集:,直接使⽤ #hotsearch-contentwrapper > li 能够满⾜吗?
问题:既然可以⼿动复制 selector/xpath的⽅式 ,为什么还有了解语法?
⼿动复制的selector/xpath表达式并不⼀定满⾜上⾯的唯⼀性的要求,有时候也需要⼿动的进⾏修改表
达式
案例:百度⾸⻚(需要登陆百度账号)右侧的热搜,复制li标签下的a标签,复制好的的selector为:
#title-content ,xpath为: //*[@id=“title-content”] ,大家可以⼿动操作⼀下,
⼿动复制的表达式是否唯⼀呢?
不是。
鼠标直接复制可以解决问题,但是难免后面会需要手动的修改/编写选择器元素,xpath元素因此我们要对选择器和xpath要有一定的了解
2. 操作测试对象
获取到了⻚⾯的元素之后,接下来就是要对元素进⾏操作了。常⻅的操作有点击、提交、输⼊、清除、获取⽂本。
2.1 点击/提交对象
click()
#找到百度⼀下按钮并点击
##推荐连着写
driver.find_element(By.CSS_SELECTOR, “#su”).click()
#两种点击的写法
#点击事件
#查找元素+点击元素
#连写(更推荐)
#driver.find_element(By.CSS_SELECTOR,"#su").click()
#拆开写
ele = driver.find_element(By.CSS_SELECTOR,"#su")
ele.click()
页面上任意位置/元素都可以实现点击操作
2.2 模拟按键输⼊
send_keys(“”)
driver.find_element(By.CSS_SELECTOR, "#kw").send_keys("迪丽热巴")
连续的send_keys会讲多次输入的内容进行拼接在一起,若想重新输入,需要使用清除方法
2.3 清除⽂本内容
输⼊⽂本后⼜想换⼀个新的关键词,这⾥就需要⽤到 clear()
driver.find_element(By.CSS_SELECTOR, "#kw").send_keys("迪丽热巴")
time.sleep(1)
driver.find_element(By.CSS_SELECTOR,"#kw").clear()
time.sleep(1)
driver.find_element(By.CSS_SELECTOR, "#kw").send_keys("古⼒娜扎")
代码实践:
#3、找到百度输入框,输入关键词“易烊千玺”
driver.find_element(By.CSS_SELECTOR,"#chat-textarea").send_keys("易烊千玺")
time.sleep(2)ele=driver.find_elements(By.CSS_SELECTOR,"#chat-textarea")
ele[1].clear()
time.sleep(2)
ele[1].send_keys("蔡徐坤")
2.4 获取⽂本信息
如果判断获取到的元素对应的⽂本是否符合预期呢?获取元素对应的⽂本并打印⼀下~~
获取⽂本信息: text
text = driver.find_element(By.XPATH,'//*[@id="hotsearch-contentwrapper"]/li[1]/a/span[2]').text
print(f"text:{text}")
eg:```python
text = driver.find_element(By.XPATH,'//*[@id="hotsearch-content-wrapper"]/li[1]/a/span[2]').text
print(f"text:{text}")
问题:是否可以通过 text 获取到“百度⼀下按钮”上的⽂字“百度⼀下”呢?尝试⼀下
注意:⽂本和属性值不要混淆了。获取属性值需要使⽤⽅法 get_attribute(“属性名称”) ;
text = driver.find_element(By.CSS_SELECTOR,"#chat-submit-button").get_attribute("textContent")
print(text)
2.5 获取当前⻚⾯标题
title
title = driver.title
2.6 获取当前⻚⾯URL
current_url
url = driver.current_url
适用场景:页面元素可点击跳转的情况下,用来检测跳转的结果是否是正确的。
title = driver.title
url = driver.current_url
print(title)
print(url)
3. 窗⼝
打开⼀个新的⻚⾯之后获取到的title和URL仍然还是前⼀个⻚⾯的?
当我们⼿⼯测试的时候,我们可以通过眼睛来判断当前的窗⼝是什么,但对于程序来说它是不知道当前最新的窗⼝应该是哪⼀个。对于程序来说它怎么来识别每⼀个窗⼝呢?每个浏览器窗⼝都有⼀个唯⼀的属性句柄(handle)来表⽰,我们就可以通过句柄来切换
3.1 切换窗⼝
1)获取当前⻚⾯句柄:
driver.current_window_handle
3)获取所有⻚⾯句柄:
driver.window_handles
3)切换当前句柄为最新⻚⾯:
driver.switch_to.window(window)
curWindow = driver.current_window_handle
allWindows = driver.window_handles
for window in allWindows:if window != curWindow:driver.switch_to.window(window)
注意:执⾏了 driver.close() 之前需要切换到未被关闭的窗⼝
思考:
是否存在打开了多个标签页,切换到某一个标签页的场景?
这种场景在测试中不常见
1、通常情况下一般会打开两个标签页,实现标签页的切换测试;
2、更多时候直接输入对应页面的链接在当前标签页进行测试。
eg:
点击百度首页的图片搜索功能,跳转到百度图片页面
# 点击百度首页的图片搜索功能,跳转到百度图片页面
print("before:"+driver.title)
print("before"+driver.current_url)
driver.find_element(By.CSS_SELECTOR,"#s-top-left > a:nth-child(6)").click()
#获取当前页面的句柄---第一个标签页
curHandle = driver.current_window_handle
#获取所有句柄
allHandle = driver.window_handles
#遍历所有句柄,切换到新的标签页
for handle in allHandle:if handle != curHandle:driver.switch_to.window(handle)
# 测试跳转结果
print("after:"+driver.title)
print("after:"+driver.current_url)
3.2 窗⼝设置⼤⼩
1)窗⼝的⼤⼩设置
#窗⼝最⼤化
driver.maximize_window()
#窗⼝最⼩化
driver.minimize_window()
#窗⼝全屏
driver.fullscreen_window()
#⼿动设置窗⼝⼤⼩
driver.set_window_size(1024,768)
仅做了解即可,在自动化脚本执行过程中通常测试人员不关注页面的变化。
eg:
百度盘首页进行窗口大小的调整
time.sleep(2)
#最大化
driver.maximize_window()
time.sleep(2)
# 最小化
driver.minimize_window()
time.sleep(2)
# 全屏
driver.fullscreen_window()
time.sleep(2)
# 手动设置尺寸
driver.set_window_size(1024,700)
3.3 屏幕截图 (非常重要)
我们的⾃动化脚本⼀般部署在机器上⾃动的去运⾏,如果出现了报错,我们是不知道的,可以通过抓拍来记录当时的错误场景
driver.save_screenshot('../images/image.png')
代码演⽰
#简单版本
driver.save_screenshot('../images/image.png')
#⾼阶版本
filename = "autotest-"+datetime.datetime.now().strftime('%Y-%m-%d-%H%M%S')+'.png'
driver.save_screenshot('../images/'+filename)
如果用普通版本的写法图片不唯一
由于图片给定的名称是固定的,当我们多次运行自动化脚本时,历史的图片将被覆盖。
eg:
# 简单方式添加屏幕截图
# filename = "./test.png"
filename = "./.venv/images/test.png"
driver.save_screenshot(filename)
![]](https://i-blog.csdnimg.cn/direct/89dca193399d4c7ba4ed723fdf8bdae1.png)
how?
如何将历史的图片文件保存下来:每次生成的图片文件名称都不一样。
why?
当自动化运行报错时,仅仅通过终端的错误提示给到的有用信息是一定的,若能将当时的页面变化截图拍下来,能更好的定位问题并解决问题。
3.4 关闭窗⼝
driver.close()
注意:窗⼝关闭后driver要重新定义
driver.close()与driver.quit()之间的区别:
driver.close():退出一个窗口
driver.quit():退出浏览器;当执行driver.quit()后,所有标签页都会被关闭。
注意:
关闭窗口!=关闭浏览器,因此在执行driver.close()之后还需要调用driver.quit()
4. 弹窗
弹窗是在⻚⾯是找不到任何元素的,这种情况怎么处理?使⽤selenium提供的Alert接⼝
4.1 警告弹窗+确认弹窗
alert = driver.switchTo.alert
//确认
alert.accept()
//取消
alert.dismiss()
当出现弹窗应该怎么解决?
(1)页面上定位不到弹窗元素
(2)出现弹窗,页面其他元素也无法定位
即:页面出现弹窗,必须先处理弹窗之后才能定位到页面元素
1、切换到弹窗
2、关闭弹窗(点击确定/取消)
4.2 提⽰弹窗
alert = driver.switchTo.alert
alert.send_keys("hello")
alert.accept()
alert.dismiss()
5. 等待
通常代码执⾏的速度⽐⻚⾯渲染的速度要快,如果避免因为渲染过慢出现的⾃动化误报的问题呢?可以使⽤selenium中提供的三种等待⽅法:
eg:
==要加转义字符==
driver.find_element(By.CSS_SELECTOR,"#chat-textarea").send_keys("蔡徐坤")
driver.find_element(By.CSS_SELECTOR,"#chat-submit-button").click()
time.sleep(3)#必须要加这个不然会报错
driver.find_element(By.CSS_SELECTOR,"#\\31 > div > div > div > div > div > div.new-tag_4ozgi.new-text-link_3k9GD > div > div.flex-wrapper-top_3ucFS > div.flex-col-left_3trtY.baike-wrapper_6AORN.cu-pt-xs-lg.baike-wrapper-pc_26R04.cu-pt-xl.baike-wrapper-left-pc_5eYY8.cos-space-pb-sm > div > div > p > span:nth-child(1) > span")
脚本执行速度非常快,而页面要加载的资源比较多,因此当脚本执行到改行代码时页面还没有渲染完成,因此找不到该元素,当添加了time.sleep(3)之后,页面已经在3秒之内加载完成,此时再去查找元素就可以找到了。
5.1 强制等待
time.sleep()
参数为秒,当调用该方法时,程序会直接阻塞,等待指定秒数后继续执行后面代码。
优点:使⽤简单,调试的时候⽐较有效
缺点:影响运⾏效率,浪费⼤量的时间
driver.quit()
1个或数量较少的测试脚本时,添加强制等待消耗的时间不过数秒
实际在工作中,业务场景比较复杂时,要添加的自动化脚本非常多,通常来说自动化测试脚本数量可达到上百
eg:
200个脚本,每个脚本添加若干个等待时间,假设平均等待时间为6秒
200*6 = 1200s ;大约20min,这个时间在程序运行时间里算是非常久的,而实际可接受的自动化运行时间为几秒或者几分钟之内。
5.2 隐式等待 (非常重要)
隐式等待是⼀种智能等待,他可以规定在查找元素时,在指定时间内不断查找元素。如果找到则代码继续执⾏,直到超时没找到元素才会报错。
implicitly_wait() 参数:秒
⽰例:
#隐式等待5秒
driver.implicitly_wait(5)
**隐式等待作⽤域是整个脚本的所有元素。**即只要driver对象没有被释放掉( driver.quit() ),隐式等待就⼀直⽣效。
优点:智能等待,作⽤于全局
eg:
#隐式等待
driver.implicitly_wait(3)
driver.find_element(By.CSS_SELECTOR,"#chat-textarea").send_keys("蔡徐坤")
driver.find_element(By.CSS_SELECTOR,"#chat-submit-button").click()
#time.sleep(3)
driver.find_element(By.CSS_SELECTOR,"#\\31 > div > div > div > div > div > div.new-tag_4ozgi.new-text-link_3k9GD > div > div.flex-wrapper-top_3ucFS > div.flex-col-left_3trtY.baike-wrapper_6AORN.cu-pt-xs-lg.baike-wrapper-pc_26R04.cu-pt-xl.baike-wrapper-left-pc_5eYY8.cos-space-pb-sm > div > div > p > span:nth-child(1) > span")driver.quit()
若等待指定秒数后还是查不到元素,则报错。
5.3 显⽰等待
显⽰等待也是⼀种智能等待,在指定超时时间范围内只要满⾜操作的条件就会继续执⾏后续代码
WebDriverWait(driver,sec).until(functions)
functions :涉及到selenium.support.ui.ExpectedConditions包下的 ExpectedConditions
类https://www.selenium.dev/selenium/docs/api/py/webdriver_support/selenium.webdriver.support.expected_conditions.html
⽰例:
from selenium.webdriver.support import expected_conditions as EC ## as后面给个别名
wait = WebDriverWait(driver,2)
wait.until(EC.invisibility_of_element((By.XPATH,'//*
[@id="2"]/div/div/div[3]/div[1]/div[1]/div')))
#检查元素的不可见性
ExpectedConditions 预定义⽅法的⼀些⽰例:
⽅法 | 说明 |
---|---|
title_is(title) | 检查⻚⾯标题的期望值 |
title_contains(title) | 检查标题是否包含区分⼤⼩写的⼦字符串的期望值 |
visibility_of_element_located(locator,str]) | 检查元素是否存在于⻚⾯的DOM上并且可⻅的期望值 |
presence_of_element_located(locator,str]) | ⽤于检查元素是存在于⻚⾯的DOM上的期望值 |
visibility_of(element) | 检查已知存在于⻚⾯DOM上的元素是否⻅的期望 |
alert_is_present() | 检查是否出现弹窗 |
优点:显⽰等待是智能等待,可以⾃定义显⽰等待的条件,操作灵活
缺点:写法复杂
eg:
driver.find_element(By.CSS_SELECTOR,"#chat-textarea").send_keys("蔡徐坤")
driver.find_element(By.CSS_SELECTOR,"#chat-submit-button").click()
#time.sleep(3)#添加显示等待
#创建显示等待对象
wait = WebDriverWait(driver,3);
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,"#\\31 > div > div > div > div > div > div.new-tag_4ozgi.new-text-link_3k9GD > div > div.flex-wrapper-top_3ucFS > div.flex-col-left_3trtY.baike-wrapper_6AORN.cu-pt-xs-lg.baike-wrapper-pc_26R04.cu-pt-xl.baike-wrapper-left-pc_5eYY8.cos-space-pb-sm > div > div > p > span:nth-child(1) > span")))
# driver.find_element(By.CSS_SELECTOR,"#\\31 > div > div > div > div > div > div.new-tag_4ozgi.new-text-link_3k9GD > div > div.flex-wrapper-top_3ucFS > div.flex-col-left_3trtY.baike-wrapper_6AORN.cu-pt-xs-lg.baike-wrapper-pc_26R04.cu-pt-xl.baike-wrapper-left-pc_5eYY8.cos-space-pb-sm > div > div > p > span:nth-child(1) > span")driver.quit()
隐式等待和显⽰等待⼀起使⽤效果如何呢?
测试⼀下
#隐式等待设置为10s,显⽰等待设置为15s,那么结果会是5+10=15s吗?
driver.implicitly_wait(10)
wait = WebDriverWait(driver,15)
start = time.time() #保存当前时间(时间戳)
try:
res = wait.until(EC.presence_of_element_located((By.XPATH,'//*
[@id="2"]/div/div/div[3]/div[1]/div[1]/div/div/div')))
except:
end = time.time() #保存当前时间(时间戳)
print("no such element")
driver.quit()
print(end-start)
#隐式等待设置为10s,显⽰等待设置为15s,那么结果会是5+10=15s吗?
driver.implicitly_wait(10)
wait = WebDriverWait(driver,15)
start = time.time()
try:
res = wait.until(EC.presence_of_element_located((By.XPATH,'//*
[@id="2"]/div/div/div[3]/div[1]/div[1]/div/div/div')))
except:
end = time.time()
print("no such element")
driver.quit()
print(end-start)
结果:重试多次,设置10秒的隐式等待和15秒的显式等待导致20秒后发⽣超时
⼩提⽰:
不要混合隐式和显式等待,可能会导致不可预测的等待时间
强制等待可以任意配合隐式等待或者显示等待来使用
6. 浏览器导航
常⻅操作:
1)打开⽹站
driver.get("https://tool.lu/")
2)浏览器的前进、后退、刷新
driver.back()
driver.forward()
driver.refresh()
案例:百度⾸⻚测试https://tool.lu/标签⼊⼝
eg:
driver.find_element(By.CSS_SELECTOR,"#chat-textarea").send_keys("蔡徐坤")
driver.find_element(By.CSS_SELECTOR,"#chat-submit-button").click()
# 前进
driver.forward()
#后退刷新
driver.back()
driver.refresh()
driver.quit()
7. ⽂件上传
点击⽂件上传的场景下会弹窗系统窗⼝,进⾏⽂件的选择。
selenium⽆法识别⾮web的控件,上传⽂件窗⼝为系统⾃带,⽆法识别窗⼝元素
但是可以使⽤sendkeys来上传指定路径的⽂件,达到的效果是⼀样的
driver.get("file:///D:/file/%E6%AF%94%E7%89%B9%E6%95%99%E5%8A%A1/%E6%B5%8B%E8%AF%95/selenium4html/selenium-html/upload.html")
ele = driver.find_element(By.CSS_SELECTOR,"body > div > div >input[type=file]")
ele.send_keys("D:\\file\\test.txt")#通过send_keys()方法,可以实现将本地文件夹中的文件上传来(注意要写完整的文件路径+文件名)
8. 浏览器参数设置
无头模式:程序在后端运行,界面看不到页面的表现。
1)设置⽆头模式
options = webdriver.ChromeOptions()
options.add_argument("-headless")
driver =
webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()),options
=options)
自动化打开浏览器默认情况下为有头模式。
2)⻚⾯加载策略
options.page_load_strategy = '加载⽅式'
⻚⾯加载⽅式主要有三种类型:
策略 | 说明 |
---|---|
normal | 默认值, 等待所有资源下载 (主题框架,图片,视频等资源) |
eager | DOM 访问已准备就绪, 但诸如图像的其他资源可能仍在加载 |
none | 完全不会阻塞WebDriver |
options = webdriver.ChromeOptions()
options.page_load_strategy = 'eager'
driver =webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()),options=options)
eg:
driver.get 默认情况下等待所有的资源加载完成之后才能继续往下执行,但实际上页面加载完成之后我们就可以继续执行自动化,若一直等待的话可能会造成页面超时,元素无法找到等问题…
总结
以上就是软件测试之⾃动化测试常⽤函数(沉淀中)的全部内容了,非常重要,值得反复阅读。喜欢博主写的内容,可以一键三连支持博主!!!