1.什么是自动化测试:把人为驱动的测试行为转为机器执行的过程
2.自动化测试的优点:
1)回归测试时能够提升效率,节约人力
2)将繁琐的任务自动化,解脱测试人员的精力从而做更多的测试设计工作
3)测试具有可重复性
4)不存在执行过程中的人为疏忽和错误,完全取决于脚本的质量,可以增加软件信任度
5)可以执行一些手工测试困难或不可能完成的任务
3.自动化测试的缺点:
1)不可能取代手工测试
2)对被测系统的质量依赖大,脚本维护成本较高
3)对自动化测试的人员要求较高
4)脚本本身也可能存在缺陷
5)自动化测试有可能会制约软件开发
4.什么样的产品适合做自动化
1)项目周期长
2)需求变动不大
3)回归测试任务重
4)项目进度压力不大
5.自动化测试的分类:
1)功能自动化
接口功能自动化:postman,jmeter,requests
UI功能自动化:
web UI自动化:selenium
APP UI自动化:appium
2)性能自动化:jmeter,loadrunner
3)安全自动化
6.selenium是一个web自动化测试工具,支持多平台,多浏览器,多语言的开源工具
目前selenium常用的版本是3.x和4.x
三部分组成:
1)webdriver — 最主要的,用来操作浏览器
2)selenium IDE — 火狐浏览器的插件,可以用来录制自动化脚本
3)selenium Grid — 实现分布式的辅助工具
7.selenium环境搭建
1)下载浏览器:chrome,安装在默认路径
2)下载selenium第三方库
方法一:cmd输入pip install selenium 下载
方法二:在pycharm
3)下载浏览器版本对应的驱动
1>先在浏览器输入chrome://version/ — 查看自己浏览器的版本
2>选择自己浏览器的驱动地址进行下载
官方下载地址:
Firefox:https://github.com/mozilla/geckodriver/releases
IE:https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
Chrome:https://sites.google.com/a/chromium.org/chromedriver/
谷歌建议去这个地址下载:http://npm.taobao.org/mirrors/chromedriver/
下载的时候要对应自己浏览器的版本,如果没有正好对应的,就下载跟自己本版最接近的
3>下载后解压,把里面的chromedriver.exe文件放到自己的python的安装目录下
查看安装目录地址:cmd 输入where python
4>完成以上步骤后,输入以下三行代码验证环境是否搭建成功:
# 1.先导入webdriver
from selenium import webdriver
# 2.实例化浏览器对象
driver = webdriver.Chrome() #注意这个C是大写
# 打开网址
driver.get("http://www.baidu.com")
如果能成功打开百度首页,说明环境配置成功
默认是输入框
如果type属性的值是submit 提交按钮
如果type属性的值是button 点击按钮
如果type属性的值是radio 单选框
如果type属性的值是checkbox 复选框
如果type属性的值是reset 重置按钮
超链接
行内块元素,默认不会占一整行,下一个标签会在这个span元素的后面
图片标签
# 1.先导入webdriver
from selenium import webdriver
# 2.实例化浏览器对象
driver = webdriver.Chrome() #注意这个C是大写
# 打开网址
driver.get("http://www.baidu.com")
driver.back() # 页面返回
driver.forward() # 页面前进
driver.refresh() # 页面刷新
sleep(2)
driver.quit() # 关闭浏览器
# driver.close() # 关闭当前页面
id是元素的属性,如果要查找的元素有id,哦都优先使用id进行定位,因为id是元素的唯一身份标识
driver.find_element(BY.ID, ‘kw’) 查找,第一个参数是定位的方式
元素.send_keys(‘python自动化’) 输入
元素.click() 点击
元素.get_attribute(‘naem’) 获取这个元素的name属性的值
元素.text 获取这个元素的文本
driver.title 获取页面的标题
from selenium import webdriver
from time import sleep
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
ele = driver.find_element(By.ID,'kw')
ele.send_keys('python') # 输入python
ele.get_attribute('name') # 获取这个元素的name属性的值
driver.find_element(By.ID, 'su').click() # 点击查找
sleep(2) # 程序加载过快,页面还在加载中就开始捕捉,所有用sleep强行等待
res = driver.title # 获取页面的标题
print(res)
if 'python' in res:
print('成功')
else:
print('失败')
ele2 = driver.find_element(By.ID, 's-usersetting-top') # 找到设置的元素
print(ele2.text) # 获取这个元素的文本
sleep(5)
driver.quit()
# name是元素的属性,name一般不会重复,但也有重复的概率;如果有重复的name,默认找到第一个
# find_element() 返回一个元素,如果存在多个重复的,默认返回第一个;如果没有找到元素会报错
# find_elements() 找出页面所有符合的元素属性,返回列表;如果没有找到元素会返回空列表
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('file:///C:/Users/CDLX/Desktop/pages/pages/s1.html')
# driver.find_element(By.NAME, 'button').click() #页面存在多个name=button的元素,默认点击第一个
eles = driver.find_elements(By.NAME, 'button') # 找出页面所有name=button的元素
print(eles)
for i in eles: # 遍历所有的name=button的元素
if i.text == '按钮2':
i.click()
sleep(5)
driver.close()
'''
class_name是元素class的属性,有多个重复的元素,find_element会返回第一个元素
'''
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('file:///C:/Users/CDLX/Desktop/pages/pages/s1.html')
cla = driver.find_elements(By.CLASS_NAME, 'cheese')
# print(cla.text)
for i in cla:
if i.text == 'Gouda':
print(i)
sleep(3)
driver.close()
'''
tag_name是元素的标签名。因为标签名一定会重复,所有通常来说都会使用find_elements找所有
'''
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.get(r'http://www.baidu.com')
father = driver.find_element(By.ID, 's-top-left')
eles = father.find_elements(By.TAG_NAME, 'a')
# print(len(eles))
for i in eles:
if i.text == '贴吧':
i.click()
break;
print(result)
sleep(5)
driver.quit()
'''
link_text是通过元素的文本进行定位,但是只能用来定位超链接的文本,a标签
link_text —— 精致匹配, 只能定位到a标签的文本
partial_link_text —— 模糊匹配, 可以定位到a标签下的所有子标签的文本
'''
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.get(r'http://www.baidu.com')
driver.find_element(By.LINK_TEXT, 'hao123').click() # 定位的a标签里面的文本
driver.find_element(By.PARTIAL_LINK_TEXT, 'hao').click() # 支持模糊匹配
'''
css_selector是通过元素的样式定位
css可以通过元素的id,class和标签直接定位到
1) # 表示id
2) . 表示class
3) 标签名没有任何的符号,直接写标签名即可
css的选择器
1)子选择器:有>符号表示,从页面的任意节点开始,一层一层的往下找,不能忽略中间的任意一层
2)后代选择器:用 空格表示,从页面的任意节点开始,可以忽略中间的层级,直接定位到目标元素
由于后代的子标签有相同,所以可以增加属性
通过父标签找第N个子标签 —— 标签名:nth-child(N)
3)兄弟选择器:用+号表示,直接在+后加标签名
只能从上向下找
模糊匹配
1)匹配包含 *=
2)匹配开头 ^=
3)匹配结尾 $=
补充:
如果一个元素的class的值有空格,代表这个属性的class的值有多个,定位的时候只取其中一个即可
比如class="bg s_btn btn_h btnhover" 代表这个class的值有4个,分别是bg,s_btn,btn_h,btnhover
'''
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.get(r'http://www.baidu.com')
# driver.find_element(By.CSS_SELECTOR, '#kw').send_keys(123) # css 通过id来定位 用#
# driver.find_element(By.CSS_SELECTOR, '.s_ipt').send_keys(456) #css 通过class来定位 用.
# #css 通过标签来定位 直接写标签名;但是因为页面相同的标签太多,所以可以在标签后加元素特有属性
# driver.find_element(By.CSS_SELECTOR, 'inpput[name="wd"]').send_keys(789)
# driver.find_element(By.CSS_SELECTOR, 'inpput[name="wd"][maxlength="255"]').send_keys(789)
# driver.find_element(By.CSS_SELECTOR, '#form>span>input').send_keys('这是通过子选择器输入的内容')
# driver.find_element(By.CSS_SELECTOR, '#form input[maxlength="255"]').send_keys('这是后代选择器')
driver.find_element(By.CSS_SELECTOR, 'a[href="http://map.baidu.com"]+a').click()
driver.find_element(By.CSS_SELECTOR, 'a[href="http://map.baidu.com"]+a+a').click()
driver.find_element(By.CSS_SELECTOR, 'a[href*="map"]') # 匹配包含 *=
driver.find_element((By.CSS_SELECTOR, 'a[href^="http://map"]')) # 匹配开头 ^=
driver.find_element(By.CSS_SELECTOR, 'a[href$=map.baidu.com]') # 匹配结尾 $=
# 通过父标签找第n个子标签
driver.find_element(By.CSS_SELECTOR, '#s-top-left>a:nth-child(3)').click() # 找第3个子标签
sleep(5)
driver.quit()
'''
xpath是通过元素的路径来定位的
1)绝对路径:从节点html开始,一层一层的往下写 用/开头
2)相对路径:从任意一个节点,一层一层的往下写,不能忽略中间的任意一层路径 用//开头
可以通过两种方式定位
1)通过属性来定位,属性前面必须加@符号 //标签名[@属性="值"]
2)通过文本来定位 //标签名[text()="文本"]
xpath模糊匹配:
1)匹配包含:使用contains()函数,里面需要传入两个参数,第一个为匹配方式,第二个为对应的值
包含属性: //标签名[contains(@属性, "值")]
包含文本; //标签名[contains(text(), "文本")]
2)匹配开头:使用starts-with()函数,里面需要传入两个参数,第一个为匹配方式,第二个为对应的值
匹配属性开头: //标签名[starts-with(@属性, "值")]
匹配文本开头: //span[starts-with(text(), "文本")]
xpath通过父标签找子标签:使用/来表示节点
xpath通过子标签找父标签:使用..
'''
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.get(r'http://www.baidu.com')
# driver.find_element(By.XPATH, '//form[@id="form"]/span/input[@maxlength="255"]').send_keys('1234567') # xpath通过属性定位
# driver.find_element(By.XPATH, '//span[text()="设置"]').click() # xpath通过文本定位
# driver.find_element(By.XPATH, '//a[contains(@href, "map")]').click()
# driver.find_element(By.XPATH, '//span[contains(text(), "普京")]').click()
# driver.find_element(By.XPATH, '//span[starts-with(text(), "我国")]').click()
# driver.find_element(By.XPATH, '//div[@id="s-top-left"]/a').click() # 通过父标签找子标签,默认第一个
# driver.find_element(By.XPATH, '//div[@id="s-top-left"]/a[2]').click() # 指定找第二个
# father = driver.find_element(By.XPATH, '//a[text()="新闻"]/..') # 通过新闻返回上一层路径,即找到父标签
# print(father.get_attribute('id'))
# 兄弟选择器
# 从上往下找:following-sibling::标签
driver.find_element(By.XPATH, '//a[text()="贴吧"]/follow-sibling::a').click() # 通过贴吧找第一个弟弟a标签
driver.find_element(By.XPATH, '//a[text()="贴吧"]/follow-sibling::a[2]').click() # 指定第二个
# 从下往上找:preceding-sibling::标签
driver.find_element(By.XPATH, '//a[text()="贴吧"]/preceding-sibling::a').click() # 通过贴吧找第一个哥哥标签
driver.find_element(By.XPATH, '//a[text()="贴吧"]/preceding-sibling::a[2]').click() # 如果指定序号,就从自身向上找
sleep(5)
driver.quit()
# driver.find_element(By.CSS_SELECT, '#one>*:nth-child(3)').text # 不管第三个子标签是什么,只要有第三个,就可以找
# driver.find_element(By.CSS_SELECT, '#one>div:nth-child(3)').text # 必须第三个是div标签,不是就会报错
# driver.find_element(By.CSS_XPATH, '//div[id="one"]/div[3]').text # 找子标签中的第三个div标签
# driver.find_element(By.CSS_XPATH, '//div[id="one"]/*[3]').text # 找第三个子标签
'''
如果要操作的元素在新窗口,就需要先切换窗口的句柄(句柄是窗口的唯一标识),才能对新窗口的元素进行操作
1)直接切换到最新窗口:
1>先获取所有窗口的句柄 driver.window_handles
2>再通过索引-1切换到最新的窗口 driver.switch_to_window(win[-1]) 里面传入句柄win[-1]
2)切换到指定窗口
1>先获取所有窗口的句柄 driver.window_handles
2>通过遍历这些句柄,边切换边判断
'''
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('https://www.baidu.com/')
home = driver.current_window_handle # 提前获取百度首页的句柄
driver.find_element(By.LINK_TEXT, 'hao123').click()
# 切换到新窗口
# 1.先获取所有窗口的句柄
win = driver.window_handles
print(win)
# 2.直接通过索引-1切换到新窗口
driver.switch_to.window(win[-1])
driver.find_element(By.NAME, 'word').send_keys('123\n')
# 切换到指定的窗口
# 1.先获取所有窗口的句柄
win = driver.window_handles
# 2.一边切换,一边判断,直到找到指定的窗口就停止
for i in win:
driver.switch_to.window(i) # 遍历到的句柄,就先切换到这个窗口
if driver.title == '123_百度搜索': #判断当前窗口的title是否的关于需要的窗口title
break
driver.find_element(By.LINK_TEXT, '百度首页').click()
# 通过之前的句柄,直接切换到需要的窗口
driver.switch_to.window(home)
sleep(3)
driver.quit()
'''
如果需要操作的元素嵌套再iframe/frame标签里面,就需要先切换到这个iframe/frame标签里面,才能进行操作
如果有id或者name,可以直接通过driver.switch_to.frame(进行切换)
如果没有,就需要先定位这个元素,再进行切换
如果切换进入frame。又想操作外部的元素,就要切出来driver.switch_to.default_content() 再切进去
如果想要从frame1切换到frame2,也要先退出frame1,再切进frame2
'''
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('https://mail.163.com')
# switch_to.frame() 专门用来切换表单
# 如果这个iframe/frame标签有id或者name属性,就可以直接进行切换
# driver.switch_to.frame('g_iframe') # 通过id的值进行切换
# driver.switch_to.frame('contentFrame') # 通过name的值进行切换
# 如果这个表单没有id和name,就需要先找到这个元素,再进行切换
# FR = driver.find_element(By.CSS_SELECTOR, 'g_iframe') # 先通过其他属性定位到这个表单
# driver.switch_to.frame(FR)
# 如果切换进入frame。又想操作外部的元素,就要切出来
# driver.switch_to.default_content() # 从之前的frame切换出来
# driver.find_element(By.CSS_SELECTOR, 'b[title="等"]').click()
# 怎样操作页面下的元素,需要操作滚动条
# execute_script()用来操作js代码
# window.scroll() 用来操作滚动条;第一个参数为横向滚动条,0代表不操作;第二个参数为纵向滚动条,10000代表底部
# driver.execute_script('window.scroll(0, 10000)')
# driver.find_element(By.CSS_SELECTOR, 'b[title="南风北巷"]').click()
FR = driver.find_element(By.CSS_SELECTOR, 'iframe[frameborder="0"]')
driver.switch_to.frame(FR)
driver.find_element(By.CSS_SELECTOR, 'input[name="email"]').send_keys('L15636717101')
driver.find_element(By.CSS_SELECTOR, 'input[name="password"]').send_keys('19980418Lh!')
driver.find_element(By.CSS_SELECTOR, 'a[data-action="dologin"]').click()
sleep(2)
title = driver.title
if '网易邮箱' in title:
print('登录成功')
else:
print('登录失败')
driver.switch_to.default_content() # 退出之前的frame
driver.find_element(By.CSS_SELECTOR, '.mD0>.oz0').click() # 点击写信
driver.find_element(By.CSS_SELECTOR, '.nui-editableAddr-ipt').send_keys('[email protected]') # 输入收件人
driver.find_element(By.CSS_SELECTOR, '.bz0>.nui-ipt>.nui-ipt-input').send_keys('赵洪禹') # 输入主题
FR_text = driver.find_element(By.CSS_SELECTOR, '.APP-editor-iframe') # 定位到iframe的位置
driver.switch_to.frame(FR_text)
driver.find_element(By.CSS_SELECTOR, 'p[style="margin:0;"]').send_keys('真棒!')
driver.switch_to.default_content() # 退出之前的frame
driver.find_element(By.XPATH, '//div[@class="nui-toolbar-item"]/div[@role="button"]/span[text()="发送"]').click() # 点击发送
sleep(3)
text = driver.find_element(By.LINK_TEXT, '返回收件箱').text
if '返回收件箱' in text:
print('邮件发送成功')
else:
print('邮件发送失败')
sleep(3)
driver.quit()
'''
鼠标操作
需要使用ActionChains类, from selenium.webdriver.common.action_chains import ActionChains
键盘操作
需要使用Keys类
所有的键盘操作,都是使用send_keys()输入的
'''
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
from selenium.webdriver.common.action_chains import ActionChains # 操作鼠标的类
from selenium.webdriver.common.keys import Keys # 操作键盘的类
driver = webdriver.Chrome()
driver.maximize_window()
# driver.get(r'file:///C:/Users/CDLX/Desktop/pages/pages/move_on.html')
# 悬停操作
# xuanting = driver.find_element(By.ID, 'aim')
# 实例化一个AC对象,需要传入实例化浏览器对象driver
# move_to_element 为悬停方法,需要传入要悬停的元素
# perform() 执行前面的操作
# ActionChains(driver).move_to_element(xuanting).perform()
# 双击操作
# shuangji = driver.find_element(By.ID, 'move_to_element')
# ActionChains(driver).double_click(shuangji).perform() # double_click()双击函数
#右击
# youji = driver.find_element(By.ID, 'move_to_element')
# ActionChains(driver).context_click(youji).perform()
# 左击悬停
# zuoji = driver.find_element(By.ID, 'two')
# ActionChains(driver).click_and_hold(zuoji).perform()
# 拖拽
# driver.get(r'https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
# driver.switch_to.frame('iframeResult')
# begin = driver.find_element(By.ID, 'draggable')
# end = driver.find_element(By.ID, 'droppable')
# ActionChains(driver).drag_and_drop(begin, end).perform()
# 键盘操作
driver.get('http://www.baidu.com')
ele = driver.find_element(By.ID, 'kw')
ele.send_keys('1234567890')
ele.send_keys(Keys.BACK_SPACE) # 退格键 删除9
sleep(1)
ele.send_keys(Keys.SPACE) # 空格键
sleep(1)
ele.send_keys(Keys.TAB) # 制表符
sleep(1)
ele.send_keys(Keys.ESCAPE) # 回退键
sleep(1)
# ele.send_keys(Keys.ENTER) # 回车键
# sleep(1)
ele.send_keys(Keys.CONTROL, 'a') # 全选
sleep(1)
ele.send_keys(Keys.CONTROL, 'c') # 复制
sleep(1)
# ele.send_keys(Keys.CONTROL, 'x') # 剪切
# sleep(1)
ele.send_keys(Keys.CONTROL, 'v') # 粘贴
sleep(1)
ele.clear() # 元素直接调用clear()方法,可以将元素的内容清空
sleep(3)
driver.quit()
'''
1)先切换到弹出框 driver.switch_to.alert
2)对弹出框操作:
accept() 点击确定
dismiss() 点击取消
'''
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('file:///C:/Users/CDLX/Desktop/pages/pages/al.html')
driver.find_element(By.ID, 'b2').click() # 点击元素,出现弹出框
al = driver.switch_to.alert # 切换到弹出框
al.accept() # 点击确定
sleep(1)
driver.find_element(By.ID, 'b2').click()
al.dismiss() # 点击取消
sleep(1)
driver.find_element(By.ID, 'b3').click()
al.send_keys('哈哈哈')
print(al.text)
al.accept() # 点击确定
sleep(4)
driver.quit()
'''
通过Select类来操作下拉框(注意:这种方式只适用于select标签下拉框)
1)先导入Select类 from selenium.webdriver.support.select import Select
2)实例化一个Select对象
3)使用三种方式来选择:
1>通过value属性选择: select_by_value()
2>通过文本属性选择: select_by_visible_text()
3>通过索引属性选择: select_by_index() 索引从0开始计算
'''
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
from selenium.webdriver.support.select import Select
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('http://www.51job.com')
# 1.先点击下拉框再操作
# driver.find_element(By.ID, 'choose_car').click() # 先点击下拉框
# driver.find_element(By.CSS_SELECTOR, 'option[value="corolla"]').click() # 再点击选项
# 2.使用Select类来操作
# ele = driver.find_element(By.ID, 'choose_car') # 先找到下拉框的元素
# tag = Select(ele) # 实例化一个Select对象
#
# # 有三种方式可以操作下拉框
# tag.select_by_value('corolla') # 通过value属性来选择
# sleep(1)
# tag.select_by_visible_text('菲亚特') # 通过文本来选择
# sleep(1)
# tag.select_by_index(3) # 通过索引来选择
driver.find_element(By.CSS_SELECTOR, '.more').click() # 点击高级搜索
sleep(1)
driver.find_element(By.CSS_SELECTOR, 'input[placeholder="搜索全文/职位名"]').send_keys('python') # 输入关键字
# 隐藏元素(只是暂时)
# 通过修改元素的display属性的值实现隐藏元素;none为隐藏,block为展示
# driver.execute_script('document.getElementById("KwdSearchResult").style.display="none"')
driver.find_element(By.ID, 'funtype_click').click() # 点击+
driver.find_element(By.ID, 'funtype_click_center_right_list_category_0100_2700').click() # 点击测试
sleep(1)
driver.find_element(By.ID, 'funtype_click_center_right_list_sub_category_each_0100_2720').click() # 点击自动化
driver.find_element(By.ID, 'funtype_click_bottom_save').click() # 点击确定
driver.find_element(By.CSS_SELECTOR, '#cottype_list>.i_arrow').click() # 定位
# tag = Select(company) # 实例化 只使用于select属性的下拉框
# tag.select_by_visible_text('民营公司')
driver.find_element(By.CSS_SELECTOR, 'span[title="民营公司"]').click()
driver.find_element(By.CSS_SELECTOR, '.btnbox>.p_but').click() # 点击搜索
sleep(6)
ele = driver.find_element(By.XPATH, '//div[text()="月薪范围:"]').text
if '月薪' in ele:
print('搜索成功')
else:
print('搜索失败')
sleep(3)
driver.quit()
'''
文件上传直接通过send_keys()方法把文件的路径写入即可
'''
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('http://www.baidu.com')
driver.find_element(By.CSS_SELECTOR, 'a[href="http://image.baidu.com/"]').click()
sleep(3)
driver.switch_to.window(driver.window_handles[-1])
driver.find_element(By.CSS_SELECTOR, '#sttb').click()
driver.find_element(By.CSS_SELECTOR, '#stfile').send_keys(r'C:\Users\CDLX\Desktop\VCG211be3c9c31.jpg')
sleep(1)
title = driver.title
if '搜索结果' in title:
print('搜索成功!')
else:
print('搜索失败!')
driver.get_screenshot_as_file('baidu.png') # 截图
sleep(5)
driver.quit()
冻停页面(js语句)
在Console里面输入setTimeout(function(){debugger;},3000)
'''
元素等待:
1)隐式等待:在规定的时间内等待全局元素, 一旦查找这个元素, 就会继续执行后续代码,不会强制等满设置时间
如果在规定时间内没有查找到这个元素,就会报错
driver.implicitly_wait()
2)显示等待:在规定时间内,等待某一个特定的元素,每隔N秒去检查一次元素是否加载成功,如果成功就继续执行
如果规定时间内,未查到到元素,则报错
需要依赖iverWWebDrait类 from selenium.webdriver.support.wait import WebDriverWait
需要依赖EC模块 from selenium.webdriver.support import expected_conditions as EC
如果脚本同时存在隐式等待和显示等待,以时间更长的为准
'''
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
from selenium.webdriver.support.wait import WebDriverWait # 显示等待需要依赖WebDriverWait类
from selenium.webdriver.support import expected_conditions as EC # 显示等待需要依赖EC模块
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('file:///C:/Users/CDLX/Desktop/pages/pages/example.html')
# driver.implicitly_wait(10) # 隐式等待10s
driver.find_element(By.ID, 'opendoor').click() # 点击传送门
# driver.find_element(By.ID, 'baidu').click() # 点击百度一下
# content = (By.ID, 'baidu') # 把查找元素的方式,和对应的值,组成一个元组
# WebDriverWait()实例化一个对象,里面需要传入三个参数
# 第一个是driver,第二个是最大等待时长,第三个是每隔N秒检查一次(选传)
# until方法用来传入要等待的元素,里面要传入EC模块查找到的元素
# WebDriverWait(driver, 10, 0.1).until(EC.presence_of_element_located(content)).click()
# 使用匿名函数显示等待
WebDriverWait(driver, 10, 0.1).until(lambda x: x.find_element(By.ID, 'baidu')).click()
sleep(5)
driver.quit()
'''
匿名函数/隐藏函数
'''
# 使用匿名函数
# f2 = lambda a, b, c: a + b + c # lambda声明匿名函数;冒号左边是形参,右边是返回值
# print(f2(3, 4, 5))
'''
unittest是单元测试框架,python自带的标准库
1)可以用来组织和管理自动化测试用例
2)提供多种断言方式,用来完成结果的检测 (断言:用预期结果和实际结果比较)
3)提供执行过程中的数据:执行时间,执行数量,通过和失败的数量
unittest的组成部分:
1)TestCase:测试用例,必须以test开头,执行顺序按照用例名称顺序来执行
常用的断言方式:
1> assertEqual(a, b) 判断a(预期结果)和b(实际结果)相等,如果是,用例通过
assertNotEqual(a, b) assertNotEqual(a, b) 判断a!=b 如果不等于,用例通过
2> assertIn(a, b) 判断a in b 如果是,用例通过
assertNotIn(a, b) 判断a not in b 如果是,用例通过
3> assertTrue(b) 只需要传入实际结果,判断实际结果是T,通过
assertFalse(b) 只需要传入实际结果,判断实际结果是F,通过
2)TestFixture:用来测试前的环境初始化(用例执行前)和测试后的环境清理(用例执行后)
环境初始化:
1>setUp:每条用例执行前,自动调用setUp方法 可以在里面准备用例执行的前置条件/测试数据
2>setUpClass:所有用例执行前自动调用,只会执行一次
必须使用@classmethod装饰器
可以用来连接数据库,
环境清理方法:
1>tearDown:每条用例执行后,自动调用tearDown方法 关闭浏览器/清理测试数据
2>tearDownClass:所有用例执行后自动调用,只会执行一次
必须使用@classmethod装饰器
可以关闭数据库连接
3)TestSuite:测试集,可以把所有的测试用例集合起来,批量执行
discover测试套件:自动收集指定目录下的所有测试用例,全部添加到套件中
4)TestRunner:执行对象,用来执行用例
'''
# 1. 导入unittest标准库
import unittest
# 2.新建一个测试类
class Test1(unittest.TestCase): # 必须要继承unittest.TestCase类,否则不能作为一个测试类来调用unittest里面的内容
def test01(self): # 测试用例 必须以test开头
print('这是test01')
response = 8 # 预期结果
result = self.a + self.b
self.assertEqual(response, result) # assertEqual(a, b) 判断a(预期结果)和b(实际结果)相等,如果是,用例通过
def test03(self): # 测试用例
print('这是test03')
response = 7 # 预期结果
result = self.a + self.b
self.assertNotEqual(response, result) # assertNotEqual(a, b) 判断a!=b 如果不等于,用例通过
def test02(self): # 测试用例
print('这是test02')
response = 7 # 预期结果
result = self.a + self.b
self.assertEqual(response, result) # assertEqual(a, b) 判断a(预期结果)和b(实际结果)相等,如果是,用例通过
def test04(self):
print('这是test04')
response = '邮件发送成功' # 手动操作后,自行在页面上节选一段文本做预期结果
result = '您的新邮件发送成功,是否需要通知对方?' # 脚本运行后,查找一个元素的文本,当作实际结果
self.assertIn(response, result) # assertIn(a, b) 判断a in b 如果是,用例通过
def test05(self):
print('这是test05')
response = '邮件发送成功' # 手动操作后,自行在页面上节选一段文本做预期结果
result = '您的新邮件发送成功,是否需要通知对方?' # 脚本运行后,查找一个元素的文本,当作实际结果
self.assertNotIn(response, result) # assertNotIn(a, b) 判断a not in b 如果是,用例通过
def test06(self):
print('这是test06')
result = True # 实际结果
self.assertTrue(result) # assertTrue(b) 只需要传入实际结果,判断实际结果是T,通过
def test07(self):
print('这是test07')
result = '邮件发送成功' # 实际结果
self.assertTrue(result) # 结果是True
def test08(self):
print('这是test08')
result = 0 # 实际结果
self.assertFalse(result) # assertFalse(a), 判断实际结果是False,用例通过
def setUp(self): # 每条用例执行前,自动调用setUp方法
print('setUp')
self.c = 5
self.d = 6
def tearDown(self): # 每条用例执行前,自动调用tearDown方法
print('in tearDown...')
@classmethod
def setUpClass(cls):
print('in setUpClass')
cls.a = 3
cls.b = 4
@classmethod
def tearDownClass(cls):
print('in tearDownClass')
if __name__ == '__main__': # main方法 写在main方法里面的代码,只用在运行当前文件的时候,才会被执行
# 其他文件导入了这个文件,不会执行main里面的代码
unittest.main()
# 1.导入unittest
import unittest
# 2.生成一个测试套件对象 里面装着要执行的用例
# discover里面需要传入两个参数
# 第一个参数是要运行的文件所在的路径。 ./代表当前路径
# 第二个参数是要运行的文件名称, 如果要执行所有文件的用例,需要同一文件的命名规范
dis = unittest.defaultTestLoader.discover('./', 'test*')
# 3.实例化一个执行对象
runner = unittest.TextTestRunner()
# 4.执行
runner.run(dis)
'''
数据驱动需要使用pandas xlrd 两个第三方库
数据驱动:将测试数据和代码进行分离。数据存放在其他文件进行单独的保存和维护
数据保存的三种方式:
1)数据保存在py文件中,使用全局变量来接收
使用时,先import导入
2)数据保存在文本文件中,使用open打开使用
3)数据保存在表格中(大量的测试数据使用)
1> CSV表格:表格版的文本文件
新建CSV表格步骤:
a. 新建记事本 —— 另存为 —— 文件名以.csv结尾 —— 编码格式为utf-8
b。双击打开 —— 录入数据 —— 点击保存 —— 弹出的提示框选择是
调用read_csv()方法来读取
2> Excel表格: 需要依赖xlrd,这个库不需要导入,在读取文件的时候会自动调用。只支持读取.xls的表格文件
调用read_excel()方法来读取
'''
# 数据保存在py文件中,使用全局变量来接收
import testdata # 导入整个模块,里面的所有内容都可以调用
print(testdata.fail_data)
print(testdata.fail_data['username'])
from testdata import success_data
print(success_data['username'])
# 数据保存在文本文件中,使用open打开使用
with open('testdata.txt', 'r') as file:
info = file.read().strip().split('\n') # 去掉前后的空白字符,在按照换行符切割成列表
print(info[0])
# 数据保存在表格中
import pandas # 从表格中读取文件
# read_csv() 用来读取csv文件里面内容
# file = pandas.read_csv(r'C:\Program Files (x86)\Python36-32\自动化测试\单元测试框架\testdata.csv')
file = pandas.read_excel(r'C:\Program Files (x86)\Python36-32\自动化测试\单元测试框架\testdata.xls')
print(file) # 读取后会返回一个pandas对象
print(file.index.values) # 返回数据的索引号,以列表形式
print(file.loc[0]) # loc()返回对应数字索引号的内容
print(file.loc[0].to_dict()) # to_dict()可以把loc读取出来的内容转化为字典
# 把内容处理成列表嵌套成字典的结构
info_list = []
for i in file.index.values:
info_list.append(file.loc[i].to_dict())
print(info_list)
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
import unittest
class BaiduMap(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome()
self.driver.maximize_window()
self.driver.get('https://map.baidu.com/')
self.driver.implicitly_wait(3)
def tearDown(self):
sleep(3)
self.driver.quit()
def test_map(self):
self.driver.find_element(By.CSS_SELECTOR, '.close-btn').click()
self.driver.find_element(By.CSS_SELECTOR, 'div[data-title="路线"]').click()
self.driver.find_element(By.CSS_SELECTOR, '.route-start-input').send_keys('桐梓林')
self.driver.find_element(By.CSS_SELECTOR, '.route-end-input').send_keys('春熙路')
self.driver.find_element(By.CSS_SELECTOR, '#search-button').click()
sleep(3)
result = self.driver.title
self.assertIn('桐梓林至春熙路街道', result)
if __name__ == '__main__':
unittest.main()