UI -Selenium自动化测试
什么是自动化测试
-
什么是测试
-
测试的分类
-
什么是自动化测试
-
自动化测试的技术选型
什么是测试:
-
测试就是运行程序,并发现程序中的错误
-
验证软件的正确性 ,完整性,安全性和质量的过程
-
用程序员的话就是找bug
-
软件测试是一个过程
什么是自动化测试
- 自动化测试就是,假定一些预设值,由机器自动完成的测试: 机器+设定=自动化
web自动化的技术选型
-
发展趋势要稳定上升
-
活跃的社区
-
开源软件
-
支持主流编程语言
-
支持主流浏览器
Selenium
-
Selemium WebDriver
-
Selenium IDE
-
Selenium Grid
Selenium WebDriver
- Selenium 、webDriver 是客户端API接口,测试人员通过调用这些接口,来访问浏览器驱动,浏览器驱动再访问浏览器
WebDriver <------>Remote WebDriver<--->Driver<----->Browser
WebDriver<------>Selenium Server or Grid<--------->Driver<------->Browser
Selenium IDE
- 帮助初学者建立简单的测试用例代码
Selenium Grid
- 分布式的测试环境
环境搭建
- Selenium
pip install selenium
-
浏览器驱动
-
https://www.selenium.dev/documentation/en/webdriver/driver_requirements/
-
设置环境变量:把下载的浏览器器驱动所在的目录添加到系统path 中
-
Selenium 核心技术
-
Selenium实现元素定位
-
Seenium WebDriver属性
-
Selenium WebDriver方法
Selenium实现元素定位
# | 方法名称 | 方法描述 |
---|---|---|
1 | find_element_by_id | 通过ID定位元素 |
2 | find_element_by_xpath | 通过xpath定位 |
3 | find_element_by_link_text | 通过连接文本定位 |
4 | find_element_by_partial_link_text | 通过连接部分文本定位 |
5 | find_element_by_name | 通过标签名称定位 |
6 | find_element_by_tag_name | 通过标签名称定位 |
7 | find_element_by_class_name | 通过CSS Class定位 |
Selenium WebDriver方法
# | 方法 | 描述 |
---|---|---|
1 | driver.back() | 浏览器后退 |
2 | driver.forward() | 浏览器前进 |
3 | driver.refresh() | 浏览器刷新 |
4 | driver.close() | 关闭当前窗口 |
5 | driver.quit() | 退出浏览器 |
6 | driver.switch_to.frame() | 切换到frame |
7 | driver.switch_to.alert | 切换到alert |
8 | driver.switch_to.active_element | 切换到活动元素 |
Selenium WebElement
-
我们使用WebDriver的find方法定位到元素后,会返回一个WebElement对象
# 属性 属性描述 1 ID 标示 2 size 宽高 3 rect 宽高和坐标 4 tag_name 标签名称 5 text 文本内容 # 方法 方法描述 1 send_keys() 输入内容 2 clear() 清空内容 3 click() 单击 4 get_attribute() 获得属性值 5 is_selected() 是否被选中 6 is_enabled() 是否可用 7 is_displayed() 是否显示 8 value_of_css_property() css属性值
Selenium 操作form
-
操作流程
-
定位表单元素
-
输入测试值
-
判断表单元素属性
-
获得表单元素属性
-
提交表单进行验证
-
Selenium 操作CheckBox和radiobutton
-
from表单中也会用到checkbox和radiobutton
-
checkbox
-
如果checkbox有id 属性可以直接通过id定位,如果没有可以通过input标签名称定位,然后通过type属性过滤
-
选择或反选checkbox,使用click()方法
-
-
radiobutton
-
radiobutton有相同的名称,多个值,可以先通过名称获得,然后通过值判断
-
选择或者反选checkbox,使用click()方法
-
-
Selenium 操作下拉列表
# | 方法/属性 | 方法/属性描述 |
---|---|---|
1 | select_by_value() | 根据值选择 |
2 | select_by_index() | 根据索引选择 |
3 | select_by_visible_text | 根据文本选择 |
4 | deselect_by_value | 根据值反选 |
5 | deselect_by_index | 根据索引反选 |
6 | deselect_by_visibile_text | 根据文本反选 |
7 | deselect_all | 反选所有 |
8 | options | 所有选项 |
9 | all_selected_options | 所有选中项 |
10 | first_selected_option | 第一个选择选项 |
Selenium 处理弹窗
-
页面弹窗有三种
-
alert:用来提示
-
confirm:用来确认
-
prompt: 输入内容
-
# 方法/属性 方法/属性描述 1 accept() 接受 2 dismiss() 取消 3 text 显示的文本 4 sends_keys 输入内容
-
-
Selemium 三种等待方式
-
time.out(固定等待)
- 方便快捷,在正式项目不建议使用
-
implicitly_wait(隐式等待)
-
设置了一个最长等待时间,如果在规定时间内网页加载完成,则执行下一步,否则一直等到时间结束为止
-
页面元素加载完成但javasc代码未加载完
-
隐式等待对整个driver周期都起作用,在最开始设置一次就够了
-
-
WebDriverWait(显式等待)
- WebDriverWait是Selenium 提供得到显式等待模块引入路径:
from selenium.webdriver.support.wait import WebDriverWait
-
WebDriverWait参数
# 参数 参数说明 1 driver 传入WebDriver实例 2 timeout 超时时间,等待的最长时间 3 poll_frequency 调用until 或until_not中的方法的间隔时间,默认是0.5秒 4 ignored_exceptions 忽略的异常 在这个模块中一共只有两种方法until ,until_not
# 参数 参数说明 1 method 在等待期间,每个一段时间调用这个传入的方法,直到返回值不是false 2 message 如果超时,抛出TimeoutException, 将message 传入异常
Seleium 等待条件
-
1 title_is 判断title,是否出现 2 title_contains 判断title,是否包含某些字符 3 presence_of_element_located 判断某个元素是否被添加到了DOM树里,并不代表该元素一定可见 4 visibility_of__element_located 判断某元素是否被添加到了DOM中并且可见,宽高都大与0 5 visibility_of 判断元素是否可见,如果可见就返回这个元素 6 presence_of_all_elements_located 判断是否至少有一个元素存在dom树种 7 visibility_of_any_elements_located 判断是否至少有一个元素在页面中可见 8 text_to_present_in_element 判断指定元素是否包含了预期的字符串 9 text_to_present_in_element_value 判断指定元素的属性值是否包含了预期的字符串 10 frame_to_present_available_and_switch_to_it 判断frame是否可以switch进去 11 invisibility_of_element_located 判断某个元素是否存在于DOM或不可见 12 element_to_be_clickable 判断某个元素是否是可见并且是enable的,代表可点击 13 staleness_of 等待某元素从dom树中移除 14 element_of_to_be_selected 判断某元素是否被选中 15 element_selection_state_to_be 判断某元素选中状态是否符合预期 16 element_located_selection_state_to_be 判断某元素选中状态是否符合预期 17 alert_is_present 判断页面上是否存在alert
Selenium鼠标和键盘事件
-
Selenium 中的鼠标和键盘事件被封装在ActionChains 类中,正确的使用方法是:
-
ActionChains(driver).click(btn).perform()
# 方法 方法描述 1 click(on_element=None) 单击鼠标左键 2 click_and_hold(on_element=None) 点击鼠标左键不松开 3 context_click(on_element=None) 点击鼠标右键 4 double_click(on_element=None) 双击鼠标左键 5 drag_and_drop(source, taeget) 拖拽某个元素然后松开 6 drag_and_drop_by_offset(source, xoffset, yoffset) 拖拽某个元素到某个坐标后松开 7 key_down(vlaue, element=None) 按下键盘上的某个键 8 key_up(value,element=None) 松开某键 9 move_by_offset(xoffset, yoffset) 鼠标从当前位置移到某个坐标 10 move_to_element(to_element) 鼠标移到某个元素 11 move_to_element_with_offset(to_element, xoffset, yoffset) 移到某个元素多少距离的位置 12 perform() 执行链中的所有动作 13 rekease(on_element =None) 在某个元素位置松开鼠标左键 14 send_keys(*keys_to_send) 发送某个键到当前焦点元素 15 send_keys_to_element(element, *keys_to_send) 发送某个键到指定元素
Selenium 执行JavaScript脚本
-
execute_script :同步执行
-
execute_async_script : 异步执行
Selenium 屏幕截图
# | 方法 | 方法描述 |
---|---|---|
1 | save_screenshot(filename) | 获取当前屏幕截图,保存为指定文件,filename指定保存路径或者文件名 |
2 | get_screenshot_as_base64 | 获取当前屏幕截图base64编码字符串 |
3 | get_screenshot_as_file(fimename) | 获取当前屏幕截图,使用完整的路径 |
4 | get_screenshot_as_png() | 获取当前屏幕截图的二进制文件数据 |
Selenium 定位frame iframe
# | 方法 | 方法描述 |
---|---|---|
1 | switch_to.frame(reference) | 切换frame,reference时传入参数,用来定位frame,可以传入id, name, index ,以及Selenium的WebElement对象 |
2 | switch_to.default_content() | 返回主文档 |
3 | switch_to.parent_frame() | 返回父文档 |
项目重构
使用unittest重构
什么是unittest
-
unittest 是Python 单元测试框架,类似于JUnit
-
5个重要的概念:test fixture, test case, test suite, test runner, test loader
-
TestCase
-
一个TestCase的实例就是一个从测试用例
[测试用例] 一个完整的测试流程,包括测试前准备环境的搭建(setup),执行测试代码(run),以及测试后环境的还原(tearDown)。一个测试用例就是一个完整的测试单元,通过运行这个测试单元,可以对某一个问题进行验证
-
Test suite
- 多个测试用例集合在一起,就是TestSuite,而且TestSuite 也可以嵌套TestSuite
-
Test runner
- 执行测试用例,run(test) 会执行TestSuite/TestCase 中的run(result)方法
-
TestLoader
- 加载TestCase 到TestSuite 中,loadTestsFrom__()就是从各个地方寻找TestCase,创建它们的实例,然后add 到TestSuite中,再返回一个TestSuite实例
-
Test fixture
- 对一个测试用例环境的搭建和销毁是一个fixture,通过覆盖TestCase 的setUp()和tearDown()方法来实现
-
-
unittest中的方法
-
方法分类:
-
类方法:只执行一次
-
实例方法:每次运行用例都执行
-
-
执行顺序
-
setUpClass--> setUP---->testA----->tearDown----->setup------>testB--->tearDown----->tearDownClass
-
用例之间按用例名称ASCII码的顺序加载,0~9, AZ,az
-
断言
方法 | 检查 |
---|---|
assertEqual(a,b) | a==b |
assertNotEqual(a,b) | a!=b |
assertTrue(x) | bool(x) is True |
asserFalse(x) | bool(x) is False |
assertIs(a,b) | a is b |
assertIsNot(a,b) | a is not b |
assertIsNone(x) | x is None |
assertIsNotNone(x) | x is not None |
assertIn(a,b) | a in b |
assertInNot(a,b) | a not in b |
assertIsInstance(a,b) | isinstance(a,b) |
assertNotIsInstance(a,b) | not isinstance(a,b) |
加载测试用例的四种方法
-
实例化
-
suite = unittest.TestSuite()
-
loader = unittest.TestLoader()
-
-
通过测试用例类进行加载
-
suit.addTest(loader.loadTestFromTestCase(MyTest1))
-
suit.addTest(loader.loadTestFromTestCase(MyTest2))
-
-
通过测试模板
-
suit.addTest(loader.loadTestFromTestMoudle(MyTest1))
-
suit.addTest(loader.loadTestFromTestMoudle(MyTest2))
-
-
通过路径加载
import os
path = os.path.dirname(os.path.abspath(__file__))
suit.addTEst(loader.discover(path))
-
逐条加载测试用例
-
case1 = MyTest1("test1")
-
case2 = MyTest2("test2")
-
suite.addTest(case1)
-
suite.addTest(case2)
-
重构
- 习惯测试用例基础: unittest.TestCase
- 将init 修改为 setup
- 将assert 断言修改为unittest断言
- 关掉浏览器放到teardown
- 测试顺序要加序号 :test1、test2
网友评论