目录:
- selenium多浏览器处理
- 执行 javascript 脚本
- headless无头浏览器使用
- capability配置参数解析
- 企业微信实战
- cypress测试框架介绍
- Playwright测试框架介绍
1.selenium多浏览器处理
多浏览器测试背景
- 用户使用的浏览器(firefox,chrome,IE 等)
- web 应用应该能在任何浏览器上正常的工作,这样能吸引更多的用户来使用
多浏览器测试概述
- 是跨不同浏览器组合验证网站或 web 应用程序功能的过程
- 是兼容性测试的一个分支,用于保持功能和质量的一致性
- 适用于面向客户的网站和组织内部使用的站点
多浏览器的实现方案
pytest hook 函数
pytest_addoption
添加命令行参数组/命令行参数pytest_configure
解析命令行选项,每个插件都会用到这个hook函数
pytest_addoption 与 pytest_configure
- pytest_addoption:
- parser.getgroup 创建/获取组名
- addoption 添加一个命令行选项
- pytest_configure:
- 通过config 对象的getoption()方法获取命令行参数
- 将命令行获取到的内容赋值给变量
代码示例:
def pytest_addoption(parser: Parser):
hdc = parser.getgroup("hdc")
hdc.addoption("--browser")
运行结果:
代码示例:
conftest.py
from _pytest.config.argparsing import Parser
def pytest_collection_modifyitems(session, config, items: list):
print(items)
for item in items:
item.name = item.name.encode('utf-8').decode('unicode-escape')
item._nodeid = item.nodeid.encode('utf-8').decode('unicode-escape')
def pytest_addoption(parser:Parser):
# group 将下面所有的 option都展示在这个group下。
mygroup = parser.getgroup("hdc")
# 注册一个命令行选项
mygroup.addoption("--browser",
# 参数的默认值
default='Chrome',
# 存储的变量(起别名)
dest='wo_shi_bie_ming',
# 参数的描述信息
help='set your browser,such as:Chrome, Firefox, Headless...'
)
global_env = {}
def pytest_configure(config):
#使用别名
browser = config.getoption("wo_shi_bie_ming", default='Chrome')
# browser = config.getoption("--browser", default='Chrome')
print(f"通过命令行获取的浏览器为{browser}")
tmp = {"browser": browser}
global_env.update(tmp)
test_demo.py
import time
from selenium import webdriver
from web_automation_testing.test_multi_brower.conftest import global_env
class TestSearch:
def setup_class(self):
self.browser = global_env.get("browser")
if self.browser == 'firefox':
self.driver = webdriver.Firefox()
else:
self.driver = webdriver.Chrome()
self.driver.maximize_window()
self.driver.implicitly_wait(3)
def teardown_class(self):
self.driver.quit()
def test_get(self):
self.driver.get("https://www.baidu.com/")
time.sleep(2)
assert True
运行结果:
2.执行 javascript 脚本
JavaScript简介
- JavaScript 是一种具有函数优先的轻量级,解释型或即时编译型的编程语言
- 可以嵌入到HTML页面对浏览器事件做出响应
- 也可以基于Node.js技术进行服务器端编程
自动化测试中使用JavaScript脚本
使用场景:部分场景使用selenium原生方法无法解决
- 修改时间控件
- 滚动到某个元素
- 其他场景
JavaScript 使用思路
- 页面调试 js 脚本
- Selenium执行js
JavaScript调试方法
- 进入 console 调试
- js 脚本如果有返回值则会在浏览器返回
JS 脚本-元素操作
- 通过 css 查找元素
- 点击元素(对应click)
- input标签对应的值(对应send_keys)
- 元素的类属性
- 元素的文本属性
// 百度首页:https://www.baidu.com/
// 修改属性值
document.querySelector("#kw").value = "邯郸学院"
// 点击操作
document.querySelector("#su").click()
// 淘宝首页: https://www.taobao.com/
// 修改元素的类属性
document.querySelector("#J_SiteNavMytaobao").className
="site-nav-menu site-nav-mytaobao site-nav-multi-menu J_MultiMenu site-nav-menu-hover"
// 测试人首页:https://ceshiren.com/
// 获取元素内的文本信息
document.querySelector("#ember63").innerText
JS脚本滚动操作
- 页面滚动到底部
- 指定到滚动的位置
document.documentElement.scrollTop=10000
document.querySelector('css表达式').scrollIntoView();
Selenium执行js
- Selenium执行js
- 调用执行js方法
- 在 js 语句中添加 return:代码可以获取js的执行结果
- 结合 find_element 方法
代码示例:
from time import sleep
from selenium import webdriver
from selenium.webdriver.common.by import By
def test_select_down():
driver = webdriver.Chrome()
driver.implicitly_wait(3)
driver.maximize_window()
# 打开网址
driver.get("https://www.taobao.com/")
# 修改下拉框属性
sleep(1)
driver.execute_script('document.querySelector("#J_SiteNavMytaobao").'
'className="site-nav-menu site-nav-mytaobao '
'site-nav-multi-menu J_MultiMenu '
'site-nav-menu-hover"')
driver.find_element(By.XPATH, "//*[text()='已买到的宝贝']").click()
sleep(5)
driver.quit()
def test_data_time():
# 打开网址
driver = webdriver.Chrome()
driver.implicitly_wait(3)
driver.maximize_window()
driver.get("https://www.12306.cn/index/")
sleep(1)
# 修改出发日期
driver.execute_script('document.querySelector("#train_date").value="2022-12-22"')
sleep(1)
# 打印出发日期, 返回值的使用
train_data = driver.execute_script('return document.querySelector("#train_date").value')
print(train_data)
sleep(3)
3.headless无头浏览器使用
- 是一个配置浏览器启动的选项类,用于自定义和配置Driver会话
- 常见使用场景:
- 设置无头模式:不会显示调用浏览器,避免人为干扰的问题。
- 设置调试模式:调试自动化测试代码(浏览器复用)
- https://sites.google.com/a/chromium.org/chromedriver/capabilities
添加启动配置(arguments)-Python版本
- 无头模式:
--headless
- 窗体最大化
start-maximized
- 指定浏览器分辨率
window-size=1920x3000
from selenium import webdriver
from selenium.webdriver.common.by import By
def test_chrome_pref():
options = webdriver.ChromeOptions()
# 无头模式
options.add_argument('--headless')
# 窗体最大化
options.add_argument('start-maximized')
# 指定浏览器分辨率
options.add_argument('window-size=1920x3000')
driver = webdriver.Chrome(chrome_options=options)
# 打开测试人页面
driver.get("https://ceshiren.com/")
# 点击登录
login_button_text = driver.find_element(By.CSS_SELECTOR, ".login-button").text
print(login_button_text)
driver.quit()
4.capability配置参数解析
capability概述
- Capabilities是WebDriver支持的标准命令之外的扩展命令(配置信息)
- 配置web驱动的属性,如浏览器名称、浏览器平台等。
- 结合Selenium Grid完成分布式、兼容性等测试
- 官网地址: https://www.selenium.dev/zh-cn/documentation/webdriver/capabilities/shared/
Selenium Grid
-
Selenium Grid 允许我们在多台机器上并行运行测试,并集中管理不同的浏览器版本和浏览器配置(而不是在每个单独的测试中)。
-
官网地址:https://www.selenium.dev/documentation/grid/
演示环境:https://selenium-node.hogwarts.ceshiren.com/ui#
- 保证本地可以正常调通
- 实例化Remote()类并添加相应的配置
- 远程地址
- 设备配置
代码示例:
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
def test_capabilitie1():
# 切换成 windows 就会报错
capabilities = {"browserName":"chrome","platformName":"windows"}
# 通过 desired_capabilities 添加配置信息
driver = webdriver.Chrome(desired_capabilities=capabilities)
driver.implicitly_wait(5)
driver.get("https://ceshiren.com/")
text = driver.find_element(By.CSS_SELECTOR, ".login-button").text
print(text)
time.sleep(30)
driver.quit()
def test_capabilitie2():
hogwarts_grid_url = "https://selenium-node.hogwarts.ceshiren.com/wd/hub"
capabilities = {"browserName":"chrome","browserVersion":"101.0"}
# 配置信息
# 实例化Remote,获取可以远程控制的driver实例对象
# 通过 command_executor 配置selenium hub地址
# 通过 desired_capabilities 添加配置信息
driver = webdriver.Remote(
command_executor=hogwarts_grid_url,
desired_capabilities=capabilities)
driver.implicitly_wait(5)
driver.get("https://ceshiren.com/")
text = driver.find_element(By.CSS_SELECTOR, ".login-button").text
print(text)
time.sleep(3)
driver.quit()
5.企业微信实战
6.cypress测试框架介绍
cypress简介
- 基于 JavaScript 的前端测试工具
- 可以对浏览器中运行的任何内容进行快速、简单、可靠的测试
- 对每一步操作都支持回看
- 覆盖了测试金字塔模型的所有测试类型【界面测试,集成测试,单元测试】
- 底层协议不采用 WebDriver > Cypress官网:https://www.cypress.io/
cypress与selenium对比
项目 | Cypress | Selenium |
---|---|---|
支持语言 | Javascript | Java, Python, Javascript, Ruby, C#等 |
支持浏览器 | Chrome、Electron | 各种主流浏览器 |
主要使用者 | 前端开发人员 | QA |
使用的测试框架 | Mocha | 无限制 |
是否需要浏览器驱动器 | 否 | 需要 |
测试速度 | 快 | 略慢 |
录制测试视频、快照 | 支持 | 支持,但需要写代码 |
社区支持 | 略显薄弱 | 强大 |
cypress环境部署
- 安装node.js 官网地址:https://nodejs.org/zh-cn/
- 安装cypress
- 初始化项目:npm init
- 配置淘宝镜像:npm config set registry http://registry.npm.taobao.org
- 安装cypress:npm install cypress --save-dev
- 打开cypress
- npx cypress open
cypress基本用法
- describe 声明一个测试用例集合
- beforeEach 测试用例前置操作,相当于setup
- it 声明一个测试用例
- cy.get 定位元素,用css定位
- type 输入文本
- click 点击操作
- should 断言
使用vscode装一下插件:
npm init
npm install cypress –-save-dev
7.Playwright测试框架介绍
Playwright 简介
- Playwright 官网:https://playwright.dev/python/docs/intro
- Web 自动化测试框架。
- 跨平台多语言支持。
- 支持 Chromium、Firefox、WebKit 等主流浏览器自动化操作。
Playwright 的优点
- 支持所有流行的浏览器。
- 速度更快,更可靠的执行。
- 更强大的自动化测试配置。
- 强大的工具库:Codegen、Playwright inspector、Trace Viewer。
Playwright 原理
Playwright 与 selenium 对比
项目 | Playwright | Selenium |
---|---|---|
是否需要驱动 | 否 | 需要对应浏览器 webdriver |
支持语言 | Java, Python, Javascript | Java, Python, Javascript, Ruby, C#等 |
支持浏览器 | Chrome、Firefox 等 | Chrome、Firefox 等 |
通讯方式 | websocket 双向通讯协议 | http 单向通讯协议 |
使用的测试框架 | 无限制(pytest,unittest) | 无限制(pytest,unittest) |
测试速度 | 快 | 慢 |
录制测试视频、快照 | 支持 | 支持 |
社区支持 | 微软 | thoughtworks 公司 |
Playwright 核心工具
- Codegen:通过记录你的操作来生成测试。 将它们保存为任何语言。
- Playwright inspector: 检查页面、生成选择器、逐步执行测试、查看点击点、探索执行日志。
- Trace Viewer:捕获所有信息以调查测试失败。 Playwright 跟踪包含测试执行截屏、实时 DOM 快照、动作资源管理器、测试源等等。
Playwright 环境安装
- 安装 playwright 插件
- pip install pytest-playwright
- 安装所需的浏览器
- playwright install
- 官网介绍:https://playwright.dev/python/docs/intro
Codegen
# 设定展示窗口大小
playwright codegen --viewport-size=800,600 地址
# 指定设备
playwright codegen --device="iPhone 11" 地址
- 其他参数:https://playwright.dev/python/docs/codegen
Codegen-保存登录状态
- 场景:单点登录、验证码问题
# 保存登录状态
playwright codegen --save-storage=auth.json
# 加载认证信息
playwright codegen --load-storage=auth.json 地址
Playwright 常用API Actions | Playwright Python
常用API | 含义 |
---|---|
start() | 实例化playwright |
chromium().launch() | 打开chrome浏览器 |
new_page() | 打开一个窗口页面 |
page.goto() | 跳转到某个地址 |
page.locator(““) | 定位某个元素 |
click() | 点击元素 |
fill() | 输入内容 |
keyboard().down() | 键盘事件 |
screenshot() | 截图操作 |
Playwright 使用实例
from playwright.sync_api import sync_playwright, expect
def test_playwright():
# 实例化playwright
playwright = sync_playwright().start()
# 打开chrome浏览器,headless默认是True,无头模式,这里设置为False方便查看效果
browser = playwright.chromium.launch(headless=False)
# 打开一个窗口页面
page = browser.new_page()
# 在当前窗口页面打开测试人网站
page.goto("https://ceshiren.com/")
# 定位搜索按钮并点击
page.locator("#search-button").click()
# 定位搜索框并输入web自动化
page.locator("#search-term").fill("web自动化")
# 使用keyboard.down模拟键盘的enter事件
page.keyboard.down("Enter")
# 断言搜索结果
result = page.locator(".list>li:nth-child(1) .topic-title>span")
expect(result).to_contain_text("自动化")
# 截图
page.screenshot(path='./datas/screenshot/screenshot.png')
# 用例完成后先关闭浏览器
browser.close()
# 然后关闭playwright服务
playwright.stop()
Trace Viewer 简介 Trace viewer | Playwright Python
Trace Viewer 使用
from playwright.sync_api import sync_playwright, expect
def test_playwirght_trace():
# 实例化一个playwright对象
playwright = sync_playwright().start()
# 启动谷歌浏览器,模式使用无头模式
browser = playwright.chromium.launch(headless=False)
# =========== trace 的配置
# 1. 生成 一个 context 实例
context = browser.new_context()
# 2. 添加 trace 的配置信息
context.tracing.start(screenshots=True, snapshots=True, sources=True)
# 3. 使用填加了trace 配置的 context 实例,去实例化一个page对象
page = context.new_page()
# 跳转到ceshiren页面
page.goto("https://ceshiren.com/")
# 点击搜索按钮, 输入css定位
page.locator("#search-button").click()
# 输入搜索的内容, 输入css定位
page.locator("#search-term").fill("appium")
# 按下回车键
page.keyboard.down("Enter")
# time.sleep(3)
result = page.locator(".results .item:nth-child(1) .topic-title")
expect(result).to_contain_text("appium")
# 4. 在关闭浏览器之前,一定要结束trace
context.tracing.stop(path="./datas/playwirght_trace.zip")
browser.close()
- # 打开trace playwright show-trace trace.zip