Day01 软件测试基础总结
Day02 测试用例知识点总结(上)
Day03 测试用例知识点总结(下)
Day04 禅道-从安装到卸载
Day05 MySql的基础使用
Day06 MySql知识点总结
Day07 MySql知识点再总结与多表查询
Day08 redis的基础知识
Day08 VMware的安装、Linux系统安装和Linux基础命令
Day09 Linux常用命令总结
Day10 Linux环境部署和项目构建
Day11 shell脚本基础知识
Day12 接口和协议
Day13 Postman的使用
Day13 Windows环境下的JDK安装与Tomcat的启动
Day14 jenkins部署
Day15 jenkins的简单使用
Day16 charles的基本使用
Day17 考试
Day18 考试
Day19 Fiddler的简单使用
Day20 Python基础
Day21 python 语句基础
Day22 Python数据类型(上)
Day23 Python数据类型(下)
Day24 Python函数
Day25 Python的文件操作和异常处理
Day26 Python面向对象
Day27 Python的部分算法
Day28 单元测试 unittest
Day29 单元测试 pytest
Day30 接口测试requests
Day31 Web端自动化基础
Day32 Web自动化进阶
目录
本篇是Web自动化的进阶,主要使用的 selenium 是第三方插件需要下载。主要使用Edge浏览器。
框架(framework)是一个框子——指其约束性,也是一个架子——指其支撑性。框架是一个基本概念上的结构,用于去解决或者处理复杂问题。
使用selenium除了下载其本身,还需要相应浏览器对应版本的驱动
goole chomd:https://registry.npmmirror.com/binary.html?path=chromedriver/
Edge:https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
Firefox:35版本以下的不需要驱动
注意:selenium不同版本也有区别,如最新的4.4.3没有了直接调用型语句,只有By类型语句
Selenium的IDE(集成开发环境)是一个易于使用的Firefox插件,用于开发Selenium测试案例。它提供了一个图形用户界面,用于记录使用Firefox浏览器,用来学习和使用Selenium用户操作,但它只能用于Firefox浏览器不支持其它浏览器。
- from selenium import webdriver #库的导入
- browser=webdriver.Edge() #创建浏览器对象
- print(dir(browser)) #查看方法
- '''=========================页面尺寸操作======================================'''
- browser.maximize_window() #浏览器窗口最大化
- print(browser.get_window_size()) #得到浏览器窗口尺寸
- browser.set_window_size(100,100) #设置浏览器窗口尺寸
- '''=========================浏览器位置操作======================================'''
- print(browser.get_window_position()) #得到浏览器位置
- browser.set_window_position(100,100) #设置浏览器位置
- '''=========================浏览器关闭操作======================================'''
- browser.close() #关闭当前窗口
- browser.quit() #关闭所有窗口
- '''=========================页面请求操作======================================'''
- browser.get('https://www.baidu.com') #请求某个url对应的响应
- browser.refresh() #刷新页面操作
- browser.back() #退回到之前的页面
- browser.forward() #前进到之后的页面
-
- '''
- ['__abstractmethods__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_abc_impl', '_authenticator_id', '_file_detector', '_get_cdp_details', '_is_remote', '_mobile', '_shadowroot_cls', '_switch_to', '_unwrap_value', '_web_element_cls', '_wrap_value', 'add_cookie', 'add_credential', 'add_virtual_authenticator', 'application_cache', 'back', 'bidi_connection', 'capabilities', 'caps', 'close', 'command_executor', 'create_options', 'create_web_element', 'current_url', 'current_window_handle', 'delete_all_cookies', 'delete_cookie', 'delete_network_conditions', 'desired_capabilities', 'error_handler', 'execute', 'execute_async_script', 'execute_cdp_cmd', 'execute_script', 'file_detector', 'file_detector_context', 'find_element', 'find_elements', 'forward', 'fullscreen_window', 'get', 'get_cookie', 'get_cookies', 'get_credentials', 'get_issue_message', 'get_log', 'get_network_conditions', 'get_pinned_scripts', 'get_screenshot_as_base64', 'get_screenshot_as_file', 'get_screenshot_as_png', 'get_sinks', 'get_window_position', 'get_window_rect', 'get_window_size', 'implicitly_wait', 'launch_app', 'log_types', 'maximize_window', 'minimize_window', 'mobile', 'name', 'orientation', 'page_source', 'pin_script', 'pinned_scripts', 'port', 'print_page', 'quit', 'refresh', 'remove_all_credentials', 'remove_credential', 'remove_virtual_authenticator', 'save_screenshot', 'service', 'session_id', 'set_network_conditions', 'set_page_load_timeout', 'set_permissions', 'set_script_timeout', 'set_sink_to_use', 'set_user_verified', 'set_window_position', 'set_window_rect', 'set_window_size', 'start_client', 'start_desktop_mirroring', 'start_session', 'start_tab_mirroring', 'stop_casting', 'stop_client', 'switch_to', 'timeouts', 'title', 'unpin', 'vendor_prefix', 'virtual_authenticator_id', 'window_handles']
- {'width': 1552, 'height': 832}
- {'x': 8, 'y': 8}
- '''
- from selenium import webdriver
- browser=webdriver.Edge()
- browser.get('https://www.baidu.com')
- '''=====================断言操作============================'''
- url=browser.current_url #获取当前页面的url
- print(url)
- title=browser.title #获取当前页面的标题
- print(title)
- '''======================截图================================'''
- data=browser.get_screenshot_as_png() #保存图片
- with open('p.png','wb') as p:
- p.write(data)
- browser.get_screenshot_as_file('file.png') #直接保存图片
- '''======================源码================================'''
- src=browser.page_source #源码
- print(src)
-
- '''
- https://www.baidu.com/
- 百度一下,你就知道
- ...
- '''
元素定位:
按调用方式分类:
1.直接调用型(新版本的selenium没有直接调用了)
2.使用By类型(需要导入By模块)
按定位方式分类:
id id定位 name name属性值定位 class name 伪类名定位 tag name 标签名定位 link text 连接的文本内容定位 partial link text 部分连接的文本内容定位 xpath xpath路径表达式 css selector css选择器定位
- from selenium import webdriver
- from selenium.webdriver.common.by import By
-
- browser=webdriver.Edge()
- browser.get('http://www.baidu.com')
- '''============================================================'''
- # browser.find_element(By.XPATH,'//*[@id="s-top-left"]/a[1]')
- # browser.find_element(By.CSS_SELECTOR,'#s-top-left > a:nth-child(1)')
- # browser.find_element(By.ID,'kw')
- # browser.find_element(By.NAME,'wd')
- # browser.find_element(By.CLASS_NAME,'s_ipt')
- # browser.find_element(By.TAG_NAME,'h1')
- # browser.find_element(By.LINK_TEXT,'新闻')
- # browser.find_element(By.PARTIAL_LINK_TEXT,'闻')
补充:如果无法定位到元素,怎么操作?
1.使用ide工具,查看脚本如何运行(仅能用于火狐浏览器)
2.联系前端添加特定属性,如id,name,class等
3.使用绝对路径的方式
4.定位元素前加等待时间
- from selenium import webdriver
- from selenium.webdriver.common.by import By
-
- browser=webdriver.Edge()
- browser.get('http://www.baidu.com')
- element=browser.find_element(By.XPATH,'//*[@id="s-top-left"]/a[1]')
- '''============================================================'''
- element.click() #鼠标左击
- element.send_keys('输入内容') #输入数据
- element.clear() #清空输入框
有的时候点击一个链接,新页面并非由当前页面跳转过去,而是重新打开一个新页面,这种情况下,计算机需要识别多标签或窗口。
句柄是windows编程的一个关键性的概念,所谓句柄就是一个4字节长的唯一的数,用以标识许多不同的对象类型,由于windwos是一个多任务操作系统,它可以同时运行多个程序或一个程序的多个副本,这些运行的程序称为一个实例,为了对同一程序的多个副本进行管理,windwos引入了实例句柄,windows为每个应用程序建立一张表,实例句柄就好像是这张表的一个索引。
- from selenium import webdriver
- from selenium.webdriver.common.by import By
-
- browser=webdriver.Edge()
- browser.get('https://bj.58.com/')
- handles_1=browser.window_handles #获取所有窗口的句柄
- print(handles_1)
- browser.find_element(By.LINK_TEXT,'租房').click()
- handles_2=browser.window_handles #获取所有窗口的句柄,更新
- print(handles_2)
- browser.switch_to.window(handles_2[1]) #通过句柄进入其他窗口
- browser.find_element(By.LINK_TEXT,'顺义').click()
-
- '''
- ['CDwindow-CA965C381A2A6C5B591F8D689EA23E52']
- ['CDwindow-CA965C381A2A6C5B591F8D689EA23E52', 'CDwindow-19A507F8046696B01FE37815A18BB795']
- '''
表单实际上就是使用iframe/frame标签,引用了其他页面的链接,真正的页面数据并没有出现在当前源码中,但是在浏览器中我们可以看到表单是当前页面的一部分,简单理解为可以使页面中开了一个窗口显示另一个页面。
进入表单有两种方式
1.直接使用id值切换进表单
2.定位到表单,再切换进入
- from selenium import webdriver
- from selenium.webdriver.common.by import By
-
- browser=webdriver.Edge()
- browser.get('https://qzone.qq.com/')
- '''========================方式1==========================================='''
- # browser.switch_to.frame('login_frame') #使用id跳转倒表单
- # browser.find_element(By.LINK_TEXT,'密码登录').click() #验证是否跳转
- '''========================方式2==========================================='''
- frame=browser.find_element(By.ID,'login_frame') #使用id定位表单
- browser.switch_to.frame(frame) #跳转倒表单
- browser.find_element(By.LINK_TEXT,'密码登录').click() #验证是否跳转
1.进入到弹出框中
element.switch_to.alert
2.接受警告
accept()
3.解除警告
dismiss()
4.发送文本到提示框
send_keys(data)
- from selenium import webdriver
- from selenium.webdriver.common.by import By
-
- browser=webdriver.Firefox()
- browser.get('https://www.baidu.com')
- browser.implicitly_wait(30)
- browser.find_element_by_xpath('//*[@id="s-usersetting-top"]').click()
- browser.find_element_by_xpath('//*[@id="s-user-setting-menu"]/div/a[1]/span').click()
- browser.find_element_by_xpath('//*[@id="se-setting-3"]/span[2]/label').click()
- browser.find_element_by_xpath('//*[@id="se-setting-7"]/a[2]').click()
- browser.switch_to.alert.accept() #接受提示
上述代码使用火狐浏览器Firefox35,selenium2.48.0 (Edge上述步骤不出提示框, 浏览器之间的区别)
js = 'window.scrollTo(0,b)' #b表示距离定位的距离
driver.execute_script(js) #执行js脚本
- from selenium import webdriver
- from selenium.webdriver.common.by import By
-
- browser=webdriver.Edge()
- browser.get('http://www.58.com')
- '''===============================滚动======================================'''
- js1 = 'window.scrollTo(0,10000)' #第二个参数表示距离,定位的距离
- browser.execute_script(js1) #执行js脚本
- '''===============================滚动到顶部======================================'''
- js2='window.scrollTo(0,0)' #方式1
- js3='var q=document.documentElement.scrollTop=0' #方式2
- '''===============================滚动到底部======================================'''
- js4='window.scrollTo(0,document.body.scrollHeight)' #方式1
- js5='var q=document.documentElement.scrollTop=10000' #方式2
- '''===============================滚动到指定位置======================================'''
- target=browser.find_element(By.LINK_TEXT,'猫猫') #定位移动到的元素
- browser.execute_script('arguments[0].scrollIntoView();',target)
-
手动测试时键盘的操作可以通过selenium实现,关于鼠标的操作由ActionChains()类来提供,关于键盘的操作由Key()类来提供
鼠标操作会存在ActionChains中,通过perform()执行
- from selenium import webdriver
- from selenium.webdriver.common.by import By
- import time
- from selenium.webdriver import ActionChains #导入动作链类,动作链可以储存鼠标的动作
-
- browser=webdriver.Edge()
- browser.get('https://www.baidu.com')
-
- element=browser.find_element(By.LINK_TEXT,'更多')
- ActionChains(browser).move_to_element(element).perform() #鼠标悬停
- time.sleep(2) #强制等待2秒用于观察效果
- ActionChains(browser).context_click(element).perform() #点击鼠标右键
- time.sleep(2) #强制等待2秒用于观察效果
- ActionChains(browser).click(element).perform() #点击鼠标左键
键盘操作使用的是Keys类,一般配合send_keys使用
- from selenium import webdriver
- from selenium.webdriver.common.by import By
- import time
- from selenium.webdriver.common.keys import Keys #导入键盘操作需要的包
-
- browser=webdriver.Edge()
- browser.get('https://www.baidu.com')
- InPut=browser.find_element(By.ID,'kw')
- InPut.send_keys('1')
- time.sleep(2)
- InPut.send_keys(Keys.SPACE) #空格键
- InPut.send_keys('1')
- time.sleep(2)
- InPut.send_keys(Keys.BACK_SPACE) #删除键
- time.sleep(2)
- InPut.send_keys(Keys.TAB) #制表键
- InPut.send_keys('1')
- time.sleep(2)
- InPut.send_keys(Keys.ESCAPE) #回退键
- InPut.send_keys('1')
- time.sleep(2)
- InPut.send_keys(Keys.ENTER) #回车键
- InPut.send_keys('1')
- time.sleep(2)
- InPut.send_keys(Keys.CONTROL,'a') #组合键全选
- time.sleep(2)
- InPut.send_keys(Keys.CONTROL,'x') #组合键剪切
- time.sleep(2)
- InPut.send_keys(Keys.CONTROL,'v') #组合键粘贴
- time.sleep(2)
- InPut.send_keys(Keys.F1)
使浏览器等待过设置的时间,再执行代码
等待的原因: 网速慢,网站内容多,可能需要缓冲时间长,缓冲时直接定位元素或者进行操作,可能会抛出异常
selenium中等待的分类:
1.强制等待
2.显示等待
3.隐士等待
导入定时等待库
from time import sleep 或者 import time
time.sleep(10) # 表示强行等待10s在执行下一句代码 这种等待方式时间到了就会执行下个语句,但比较死板,不能保证在等待的时间内元素真正被加载了出来。而且如果等待的元素已经被加载出来,还需要等待到时间才会执行下一句,浪费时间。
browser.implicitly_wait(30) #等待30s
这个等待表示在规定的时间内页面的所有元素都加载完了就执行下一步,否则一直等到时间截止,然后再继续下一步。
这个方法的缺点是你需要的元素已经加载出来了,但页面还没有加载完,再需要继续等待页面加载完才能执行下一步操作。
注:隐式等待的作用域是全局,所以一般设置在整局代码的头几行。
需要导入的包:
from selenium.webdriver.support.wait import WebDriverWait #导入显性等待的包from selenium.webdriver.support import expected_conditions as EC #判断所需要的元素是否已经被加载出来
from selenium.webdriver.common.by import By #定位
WebDriverWait(driver,timeout,poll_frequency=0.3,ignored_exceptions=None)
driver:浏览器驱动
timeout:最长超过时间,默认以秒为单位
poll_frequency:监测的时间间隔,默认为0.3秒
ignored_exceptions:超时后的异常信息,默认情况下抛NoSuchElementException异常
WebDriverWait类是由WebDirver 提供的等待方法。显示等待明确的要等到某个元素的出现,在设置时间内每隔x秒去判断一下指定的元素是否加载完,加载完了就执行下一步,否则继续每隔x秒去判断,指定时间截止。如果超时就会抛出异常。
强制等待:傻瓜式等待,不智能(必须等到时间才走)
隐式等待:全局通用,只需设置一次,很智能(等到了就走,不会浪费时间)显式等待:等待元素处于特定条件的时候使用,很智能(等到了就走,不会浪费时间)
断言语句本身可以参考第二十八天断言,而在web端断言设置可以使用跳转的url是否正确,或者跳转的网页title是否是预期的结果