自动化测试是相对于手工测试而言的,指把人为驱动的手工测试过程转化为机器/工具执行的一个测试过程。自动执行编写好的测试用例脚本,自动对比实际结果和预期结果,生成输出报告等。适用于在需要重复执行机械化的操作、计算等场合,实现更快速的回归,提高效率。
介绍 | 内容 |
---|---|
目标 | 减少测试当中的重复性工作 提高测试用例的执行效率 节省企业人力成本 弥补手工测试很难实现或实现成本很高的地方 方便定位缺陷出现的原因 |
优点 | 快速高效 可靠可重复使用 可以执行一些手工测试困难或不可能执行的测试 适合对程序的回归测试,方便 |
缺点 | 工具本身无法进行主观判断,如界面色彩和布局 有技术门槛 变更频繁的软件,开发维护成本更高,要求环境相对稳定 自动化测试工具本身是一个产品,会有兼容性问题局限 |
阶段 | 类型 | 应用 |
---|---|---|
UT单元测试 | 单元自动化 | unittest、PyUnit、junit |
IT集成测试 | 接口自动化 | requests、urllib |
ST系统测试 | UI自动化 | selenium、UFT、appium、alltest |
selenium基于UI界面在ST(系统测试阶段)进行Web应用的功能测试自动化框架(专指B/S结构web应用)
API:构造API、解析API
UI:定位元素、操作元素
多浏览器支持:Chrome、Firefox、Edge、Opera 、Safari …
多平台的支持:Linux、Windows、Mac …
多语言的支持:Java、Python、Ruby、JavaScript、Perl、C# …
参考《Python+Pycharm+Selenium+WebDriver自动化环境搭建》
pip install selenium
# C:\Users\username\pip\pip.ini
[global]
timeout = 6000
index-url = https://repo.huaweicloud.com/repository/pypi/simple
trusted-host = repo.huaweicloud.com
# 国内源
http://pypi.douban.com/simple/
http://mirrors.aliyun.com/pypi/simple/
https://pypi.tuna.tsinghua.edu.cn/simple
# python交互环境
python
import selenium
Selenium WebDriver 通过原生浏览器的驱动直接控制浏览器
(1) 获取浏览器版本对应驱动,追加该驱动路径到环境变量Path
(2) 禁用浏览器更新/保持驱动与版本匹配
(3) 浏览器包括 chrome、firefox、edge、ie、safari
from selenium import webdriver
# 配置对象
opt = webdriver.FirefoxOptions()
# 配置参数
opt.add_argument('--headless') # 开启无头
opt.add_argument('--disable-gpu') # 禁用GPU
# 实例化有配置的webdriver对象
wd = webdriver.Firefox(options=opt)
# 操作
wd.get('https://www.vmall.com/')
wd.save_screenshot("capture.png")
print(wd.title)
wd.quit()
其他配置参数:
opt.add_argument('--start-maximized') # 最大化防止取元素报错
opt.add_argument('--incognito') # 隐身模式
opt.add_argument('--blink-settings=imagesEnabled=false') # 禁用加载图片提升速度
Selemnium
自动化测试应用程序编程接口(API)如下:
首先,导入 webdriver
基类
from selenium import webdriver
然后,创建 webdriver
对象 wd
1,继承 webdriver
基类方法与属性;
wd = webdirver.Browser() # Browser 须大写 Firefox,Chrome,Edge,Ie,Safari
例如,在 unittest
的 setUp()
测试固件中,继承webdriver
基类:
import unittest
from selenium import webdriver
class TestSth(unittest.TestCase):
def setUp(self) -> None:
# self.wd继承webdriver基类
self.wd = webdriver.Firefox()
按以下方法,也可以导入 WebDriver
基类,browser
须小写 firefox,chrome,edge,ie,safari
from selenium.webdriver.browser.webdriver import WebDriver
例如,在 unittest
的 setUpClass()
测试固件中,继承WebDriver
基类:
import unittest
from selenium.webdriver.firefox.webdriver import WebDriver
class TestSth(unittest.TestCase):
@classmethod
def setUpClass(self) -> None:
# self.wd继承WebDriver基类
self.wd = WebDriver()
在 unittest
框架 test_sth()
测试方法中,可以把 self.wd
赋给自定义变量(web,dr,driver 均可),便于书写
def test_sth(self):
wd = self.wd
# wd 继承基类中获取DOM元素的方法
wd.find_element(By.XPATH,"//ul/li[3]/a[@class='item']").click()
import unittest
from selenium.webdriver.firefox.webdriver import WebDriver
class TestSth(unittest.TestCase):
def test_sth(self):
self.wd = WebDriver()
# wd是WebDriver的实例化对象
wd = self.wd
wd.get("url")
wd.quit()
# wd.find_element_by_xx("str") 或 wd.find_element(By.XX,"str")
# return WebElementObj (返回一个web元素对象)
# 定位一个DOM元素
find_element_by_id() # 通过id值
find_element_by_name() # 通过name值
find_element_by_class_name() # 通过class类名
find_element_by_tag_name() # 通过标签名
find_element_by_link_text() # 通过链接文本
find_element_by_partial_link_text() # 通过部分链接文本
find_element_by_css_selector() # 通过css选择器
find_element_by_xpath() # 通过xpath路径
find_element(By.XX,"str") # XX可取以上8种方式的名字,作为策略字段
# XX 可取 ID,NAME,CLASS_NAME,TAG_NAME,LINK_TEXT,PARTIAL_LINK_TEXT,CSS_SELECTOR,XPATH
# 将以上9种的 element 改为 elements 可以定位一组的多个元素
其中 find_element(By.XX,'str')
和 find_elements(By.XX,'str')
须引入 By
from selenium.webdriver.common.by import By
wd.find_elements(By.CLASS_NAME, 'title-content-title') # 百度首页热搜标题元素
wd.find_element(By.XPATH, '//input[@id="kw"]') # 百度搜索输入框
xpath
xpath | 含义 |
---|---|
/ | 代表从根标签开始的路径,一个/只代表下一级 |
// | 代表任意一级的路径 |
[] | 谓语,对元素的限定条件,[]包含条件,写标签名之后 |
@ | @属性名 |
label[2] | 索引 |
//label[text() = “str”] | 函数,text() = “文本” |
//label[contains(text(), “str”)] | 函数,contains(属性, 值) |
and or not | 逻辑运算符 |
查看器:Xpath
//input[contains(@placeholder,"用户")]
//*[contains(@placeholder,"用户")]
//div[@class="container"]/button[contains(text(),"确认")]
控制台:$x('Xpath')
$x('//input[contains(@placeholder,"用户")]')
$x('//*[contains(@placeholder,"用户")]')
$X('//div[@class="container"]/button[contains(text(),"确认")]')
对应“定位符驱动层”
wd.maximize_window()
wd.back()
wd.forward()
wd.refresh()
import time
t = time.strftime("%Y-%m-%d-%H_%M_%S", time.localtime())
wd.get_screenshot_as_file("D:\\capture-{}.png".format(t))
wd.save_screenshot("capture-{}.png")
有时候需要验证浏览器cookie
是否正确,或需要对其做一些操作
处理的cookie信息是字典 dictionary
,如{"name": "a", "value": "b"}
wd.get_cookies() # 获取所有cookie信息
wd.get_cookie(name) # 获取特定cookie信息
wd.add_cookie(dictionary) # 添加cookie信息
wd.delete_cookie(name) # 删除特定cookie信息
wd.delete_all_cookies() # 删除所有cookie信息
wd.implicitly_wait(9) # 设置在接下来定位元素时,最长的等待元素加载时间为9秒
# 通过JS设置浏览器滚动条位置
js = "window.scrollTo(100,450);"
wd.execute_script(js)
shadow-root
内的元素属于 shadowDOM(隐藏的DOM)是前端的页面封装;
H5很多通过 shadowDOM 实现,selenium xpath定位不到其中内部元素
像:处理 angular
框架根标签
,可以通过调用JS切换到内部的DOM
js ='''return document.evaluate("app-root的Xpath", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.value'''
wd.execute_script(js)
wd.title # 网页标题
wd.current_url # 当前页的url地址
Wd.page_source # 源代码
Wd.current_window_handle # 返回当前指向的窗口句柄 str
Wd.windows_handles # 返回所有窗口句柄的列表 list
Wd.switch_to.xxx() # 切换到某个window/frame/alert
wd.switch_to.window(句柄编号) # 切换到指定“窗口句柄“的窗口
wd.window_handles # 返回一个所有窗口句柄的列表list
wd.current_window_handle # 返回WebDirver当前指向的窗口句柄str
可以写一个解决”发生页面跳转,而导致指向的句柄不是当前句柄“的方法
# self.wd = WebDriver()
# wd = self.wd
def switch_new_window():
for i in wd.window_handles:
if i != wd.current_window_handle:
wd.switch_to.window(i)
# 从外部页面,切换到内部框架,参数为标签id、name、索引值、WebElement对象
wd.switch_to.frame(xx)
# 从当前框架,切回最外部页面,即第1次WebDriver打开的页面
wd.switch_to.default_content()
# 从当前框架,切回到父级页面或框架
wd.switch_to.parent_frame()
# 切到页面上的对话框
dialog = wd.switch_to.alert
# 操作对话框
dialog.text # 返回对话框上的提示文本
dialog.accept() # 点击对话框上“确定”按钮
dialog.dismiss() # 点击对话框上“取消”按钮
dialog.send_keys('str') # 向“输入对话框”中输入内容
WebDriverObj.find_element(By.XX,'str')
定位元素方法 return
是 WebElementObj
对象即
elem = WebDriverObj.find_element(By.XX,'str')
elem.send_keys("str") # 输入内容到页面元素
elem.clear() # 清空元素内容
elem.click() # 点击页面元素
elem.is_displayed() # 元素是否被显示
elem.is_enabled() # 元素是否被启用
elem.is_selected() # 元素是否被选中
elem.text # 元素内文本内容
elem.size # 元素的大小
elem.tag_name # 元素的标签名
from selenium.webdriver.support.select import Select #导入Select基类
Select
基类接收一个 WebElementObj
作为参数,得到一个实例化的 Select
对象
elem = wd.find_element(By.ID,'xx') # WebDriver的方法,返回一个WebElement对象
sel = Select(elem) # 把定位到的web元素作为参数传入Select基类
提供选中下拉列表中某一项的方法
sel = Select(elem) # 传入定位到的元素
sel.select_by_index(index) # 通过下标选择(0开始)
sel.select_by_value(value) # 通过value属性值
sel.select_by_visible_text("text") # 通过文本内容
取消选中下拉列表中某一项的方法是 select 加前缀 de deselect
sel.deselect_by_index()
sel.deselect_by_value()
sel.deselect_by_visible_text()
# 返回Select控件中下拉列表的所有项
# return WebElements
sel.options
sel.options[i]
# 下拉列表每一项 = WebElement对象,附带 is_selected() 方法
sel.options[i].is_selected()
from selenium.webdriver import ActionChains #导入ActionChains基类
ActionChains
类接收一个 WebDriverObj
作为参数,得到一个实例化的 ActionChains
对象
wd = WebDriver()
act = ActionChains(wd)
elem = wd.find_element(By.ID,'xx') # WebDriver方法,返回一个WebElement对象
act.move_to_element(elem).perform() # 悬停到某元素,像能触发:hover的元素
act.double_click(elem).perform() # 双击某元素
act.context_click(elem).perform() # 右击某元素
# .perform()为执行所有存储的action
from selenium.webdriver.common.keys import Keys
pwd = wd.find_element(By.ID,"password") # WebDriver方法,返回一个WebElement对象
WebElementObj.send_keys()
传入Key.ATTRIBUTES
参数
pwd.send_keys("blogg") # 输入blogg
pwd.send_keys(Keys.BACK_SPACE) # 删除行末多余的g
pwd.send_keys(Keys.CONTROL,'a') #(CTRL,a) 全选
pwd.send_keys(Keys.CONTROL,'x') #(CTRL,x) 剪切
pwd.send_keys(Keys.CONTROL,'v') #(CTRL,v) 粘贴
pwd.send_keys(Keys.ENTER) #(Enter) 回车
BY 博主CSDN@崔同学
wd 是 webdriver缩写,可以为 dr/driver/web等 ↩︎