测试萌新的Python学习(七)长文直通web自动化脚本,包教包会

web自动化

自动化

概念

由机器设备代替人工自动完成指定目标的过程

优点

  • 减少劳动力
  • 提高工作效率
  • 产品规格统一
  • 批量生产
  • 安全

自动化测试

概念

用程序替代人工去执行测试的过程

软件测试: 对程序进行操作, 以发现程序错误, 并验证其是否满足需求的过程

应用场景

解决重复性操作的问题

  • 解决-回归测试
  • 解决-压力测试
  • 解决-兼容性测试

正确认识

  • 优点
    • 较少的时间内运行更多的测试用例
    • 自动化脚本可以重复运行
    • 减少人为错误
    • 克服手工测试的局限性
  • 误区
    • 自动化测试可以完全代替手工测试
    • 自动化测试一定比手工测试厉害
    • 自动化测试可以发现更多bug
    • 自动化测试适用于所有功能

分类

  • 接口-自动化测试
  • web-自动化测试(本阶段学习)
  • 移动-自动化测试
  • 单元-自动化测试(一般是开发人员进行的)

web自动化测试

概念

用程序代替人工去执行web测试的过程

什么样的项目适合做web自动化测试?

  • 需求变动不频繁
  • 项目周期长
  • 项目需要回归测试

web自动化测试什么时候开始?

手工测试结束后

web自动化测试所属的分类

属于功能测试(黑盒)

web自动化工具简介

主流工具

  • QTP
  • selenium
  • robot framework

selenium特点

  • 开源: 开放源代码
  • 跨平台: linux, windows, mac
  • 支持多种浏览器: Chrome, Firefox, IE, Edge, Opera, Safari等
  • 支持多种语言: python, java, C#, JS, ruby, PHP等
  • 成熟稳定: 被很多500强所使用
  • 功能强大

项目搭建步骤

基于python搭建环境:

  1. python 开发环境 (python v3.x)

  2. 安装selenium包

  3. 安装浏览器(推荐安装 Chrome浏览器)

  4. 安装浏览器驱动

    保证能够用程序驱动浏览器, 实现自动化测试

安装selenium包

安装

pip install selenium

验证

pip list

卸载

pip uninstall selenium

安装浏览器驱动

安装步骤

  1. 下载浏览器驱动(谷歌浏览器驱动)

    地址: https://npm.taobao.org/mirrors/chromedriver/

    谷歌浏览器下载地址: https://www.chromedownloads.net/

  2. 把驱动文件所在目录添加到 Path 环境变量中

    或者直接放到python安装目录, 因为python的安装目录已经添加到了Path中

需求与实现

# 需求: 通过程序, 启动浏览器, 并打开百度首页, 暂停3秒, 关闭浏览器
# 1.导包
import time
from selenium import webdriver
# 2.创建浏览器驱动对象
driver = webdriver.Chrome()
# 3.打开百度首页
driver.get("http://www.baidu.com")
# 4.暂停3秒
time.sleep(3)
# 5.关闭驱动对象
driver.quit()

如何进行元素定位

元素定位就是通过元素的信息或元素的层级结构来定位元素

html 页面由标签构成
标签的基本格式如下:
<标签名 属性名1="属性值1", 属性名2="属性值2">文本</标签名>
<input id="username", type="text", name="username", placeholder="用户名" />
<div id="my_cart">
	<span>我的购物车!</span>
</div>

浏览器开发者工具

概念是给网站开发人员使用的调试工具

作用查看元素信息, 定位元素

使用

需求: 使用浏览器开发者工具, 查看百度输入框的相关信息

  • 安装: 不需要
  • 启动: 一般都是F12
  • 使用方式
    • 方式1: 在要查看的元素上点击右键选择"检查"(Chrome) 或者 “查看元素”(Firefox)
    • 方式2: 先打开浏览器开发者工具, 点击选择元素的图标, 移动鼠标到要查看的元素, 然后点击

总体介绍

八种定位元素的方式:

  1. id
  2. name
  3. class_name
  4. tag_name
  5. link_text
  6. partial_link_text
  7. XPath
  8. CSS

id定位

说明: 就是通过元素的id属性来定位元素, html规定 id 属性在整个 html 文档中必须唯一的
前提: 元素有id属性

方法

driver.find_element(By.ID, "value")

案例

  1. """
        1.导包
            导入selenium包 --> from selenium import webdriver
            导入time包 --> import time
        2.创建浏览器驱动 --> driver = webdriver.Chrome()
        3.打开 注册A.html 页面 --> driver.get(url)
        4.通过id定位 --> element = driver.find_element(By.ID, "value")
        5.使用 send_key() 方法输入内容 --> element.send_keys("admin")
        6.暂停5s --> time.sleep(5)
        7.关闭浏览器 --> driver.quit()
    """
    # 1.导包
    import time
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    # 2.创建浏览器驱动对象
    driver = webdriver.Chrome()
    # 3.业务操作
    driver.get("file:///C:/Users/78418/Desktop/A(1).html")
    driver.find_element(By.NAME,"userA").send_keys("admin")
    driver.find_element(By.ID,"passwordA").send_keys("123456")
    # 4.暂停5秒
    time.sleep(5)
    # 5.关闭驱动对象
    driver.quit()
    

name定位

说明: 就是通过元素的name属性来定位元素, 在html文档中 name 属性值是可以重复的
前提: 元素有name属性

方法: driver.find_element(By.NAME, “value”)

# 1.导包
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建浏览器驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///C:/Users/78418/Desktop/A(1).html")
driver.find_element(By.NAME,"userA").send_keys("admin")
driver.find_element(By.NAME,"passwordA").send_keys("123456")
# 4.暂停5秒
time.sleep(5)
# 5.关闭驱动对象
driver.quit()

class_name定位

说明: 就是通过元素的class属性值来定位元素, html 通过使用class来定义元素的样式
前提: 元素有class属性
注意: 如果class有多个属性值, 只能使用其中一个

方法

element = driver.find_element(By.CLASS_NAME, "value")

案例

# 1.导包
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建浏览器驱动对象
driver = webdriver.Chrome()
#driver.find_element(By.CLASS_NAME, "value")
# 3.业务操作
driver.get("file:///C:/Users/78418/Desktop/A(1).html")
driver.find_element(By.CLASS_NAME,"telA").send_keys("13111111111")
# driver.find_element_by_class_name("emailA").send_keys("123456@qq.com")
driver.find_element(By.CLASS_NAME,"dzyxA").send_keys("123456@qq.com")
# 4.暂停5秒
time.sleep(5)
# 5.关闭驱动对象
driver.quit()

tag_name定位

说明: tag_name定位就是通过标签名来定位
注意: html本质就是由不同的tag组成, 每一种标签一般在页面中会存在多个, 所以不方便进行精准定位, 一般很少使用

方法

element = driver.find_element(By.TAG_NAME, "value")
# 如果存在多个相同的标签, 则会返回符合条件的第一个标签
# 如何获取第二个元素? 后面会讲

代码

# 1.导包
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建浏览器驱动对象
driver = webdriver.Chrome()
#driver.find_element(By.TAG_NAME, "value")
# 3.业务操作
driver.get("file:///C:/Users/78418/Desktop/A(1).html")
driver.find_element(By.TAG_NAME,"input").send_keys("xxxxxx")
# 4.暂停5秒
time.sleep(5)
# 5.关闭驱动对象
driver.quit()

link_text定位

说明: 是专门用来定位超链接元素(<a>内容...</a>), 并且是通过超链接的文本内容来定位元素

方法

element = driver.driver.find_element(By.LINK_TEXT,"访问 新浪 网站")
# link_text: 超链接的全部文本内容

案例

需求: 打开 注册A.html 页面, 完成以下操作
1. 使用link_name定位, 并点击
2. 5s后关闭浏览器

代码

# 1.导包
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建浏览器驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///C:/Users/78418/Desktop/A(1).html")
driver.find_element(By.LINK_TEXT,"访问 新浪 网站").click()
# 4.暂停5秒
time.sleep(5)
# 5.关闭驱动对象
driver.quit()

partial_link_text定位

说明: partial_link_text 定位是对 link_text 定位的补充, link_text 使用全部文本内容匹配元素, 而 partial_link_text 可以使用局部文本内容来匹配元素, 也可以使用全部文本内容匹配元素 

方法

element = driver.find_element(By.LINK_TEXT,"访问 新浪 网站")
# partial_link_text: 可以传入a标签的局部文本, 也可以传入a标签的全部文本

案例

需求: 打开 注册A.html 页面, 完成以下操作
1. 使用partial_link_name定位(访问 新浪 网站)超链接, 并点击
2. 5s后关闭浏览器

代码

# 1.导包
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建浏览器驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///C:/Users/78418/Desktop/A(1).html")
driver.find_element(By.LINK_TEXT,"访问 新浪 网站").click()
driver.find_element(By.PARTIAL_LINK_TEXT,"访问").click()    # 通过局部文本定位超链接
# 4.暂停5秒
time.sleep(5)
# 5.关闭驱动对象
driver.quit()

定位一组元素

方法

elements = driver.find_elements_by_xxx("xxxxxx")
作用:
     1. 查找定位符合条件的所有元素
     2. 返回值是一个列表
说明: 列表数据格式的读取需要指定下标(下标从0开始)

案例

打开 注册A.html 页面, 完成以下操作
1. 使用 tag_name 定位密码输入框(第二个input标签), 并输入123456
2. 5秒后关闭浏览器

代码

# 1.导包
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建浏览器驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///C:/Users/78418/Desktop/A(1).html")
elements = driver.find_elements(By.TAG_NAME,"input")
elements[1].send_keys("123456")
# 4.暂停5秒
time.sleep(5)
# 5.关闭驱动对象
driver.quit()

XPath和CSS

为什么要学习XPath/CSS定位

1.如果要定位的元素没有 id, name, class...属性, 该如何进行定位?
2.如果通过 name, class, tag_name...无法定位到唯一的元素, 该如何进行定位?
示例:
	<input type="submit value="提交" / >

什么是XPath

1.XPath是XML Path的简称, 它是一门在XML文档中查找元素信息的语言
2.HTML可以看做是XML的一种实现, 所以Selenium用户可以使用XPath语法在web应用中定位元素

<?xml version="1.0" encoding="UTF-8" ?>
<node>
    <db id="db" desc="三条边的长度都一样">
        <b1>3</b1>
        <b2>3</b2>
        <b3>3</b3>
        <expect>等边三角形</expect>
    </db>
    <dy>
        <b1>4</b1>
        <b2>4</b2>
        <b3>5</b3>
        <expect>等腰三角形</expect>
    </dy>
</node>

XPath定位方式

四种定位方式

  • 路径
  • 利用元素属性
  • 属性与逻辑结合
  • 层级与逻辑结合

方法

driver.find_element(By.XPATH,"/html/body/div/fieldset/form/p[1]/input").send_keys("admin")

路径

绝对路径: 从最外层元素到指定元素所经过的所有元素层级的路径

  1. 绝对路径以 /html 为开始, 使用 / 来分割元素层级

如: /html/body/div/fieldset/p[1]/input

  1. 不建议使用

相对路径: 匹配任意层级的元素, 不限制元素的位置

  1. 相对路径以 // 开始
  2. 格式: //input 或者 //*
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("file:///C:/Users/78418/Desktop/A(1).html")
# 定位用户名输入框, 输入 admin
driver.find_element(By.XPATH,"/html/body/div/fieldset/form/p[1]/input").send_keys("admin")
# 暂停3s
time.sleep(3)
# 定位密码输入框, 输入 123
driver.find_element(By.XPATH,"//*[@id='passwordA']").send_keys("123")
time.sleep(5)
driver.close()

利用元素属性

说明: 通过使用元素的属性信息来定位元素
格式: //input[@id='userA'] 或者 //*[@id='userA']

练习

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("file:///C:/Users/78418/Desktop/A(1).html")
# 利用元素属性通过XPath 定位用户名输入框, 并输入 admin
# driver.find_element_by_xpath("//*[@name='userA']").send_keys("admin")
# driver.find_element_by_xpath("//*[@id='userA']").send_keys("admin")
# driver.find_element(By.XPATH,"//*[@placeholder='请输入用户名']").send_keys("admin")
driver.find_element(By.XPATH,"//*[@type='text']").send_keys("admin")
time.sleep(5)
driver.close()

属性与逻辑结合

说明: 解决元素之间存在相同属性值的问题
格式: //*[@name='xxx' and @class='yyy']

练习

driver.find_element(By.XPATH,"//*[@type='password' and @name='passwordA']").send_keys("123")

层级与属性结合

说明: 如果通过元素自身的属性不方便直接定位该元素, 则可以先定位到其父元素, 然后再找到该元素
格式: //*[@id='p1']/input

练习

driver.find_element(By.XPATH,"//*[@id='p1']/input").send_keys("test1")

XPath扩展

说明:
不使用函数时:
//*[@id='xxx']
使用函数后
//*[text()='xxx']   文本内容是 xxx 的元素
//*[contains(@attribute, 'xxx')] 属性中含有 xxx 值的元素
//*[starts-with(@attribute, 'xxx')] 属性以xxx开头的元素

练习

driver.find_element(By.XPATH,"//*[starts-with(@placeholder, '请输入密')]").send_keys("1234")

什么是CSS

1.CSS 是一种语言, 它用来描述html元素的现实样式
2.在CSS中, 选择器是一种模式, 用于选择需要添加样式的元素
3.在Selenium中也可以使用这种选择器来定位元素
提示:
1.在Selenium中推荐使用CSS定位, 因为它比XPath定位速度快
2.CSS选择器语法非常强大, 在这里我们只学习在测试中常用的几个

CSS定位方式

常用的定位方式

  • id选择器
  • class选择器
  • 元素选择器
  • 属性选择器
  • 层级选择器

方法

driver.find_element(By.CSS_SELECTOR, “value”)

driver.find_element(By.CSS_SELECTOR,"#userA").send_keys("admin")

id选择器

说明: 根据元素id属性来选择
格式: #id值
例如: #userA (选择id属性值为userA的元素)

class选择器

说明: 根据元素class属性来选择
格式: .class值
例如: .telA  (选择class属性值为 telA的元素)

练习

driver.find_element(By.CSS_SELECTOR,".telA").send_keys("13100000000")

元素选择器

说明: 根据元素的标签名选择
格式: 标签名
例如: input (选择input元素)

练习

driver.find_element(By.CSS_SELECTOR,"button").click()

属性选择器

说明: 根据元素的属性名和值来选择
格式: [attribute=value]
例如: [type='password']   (选择 type 属性值为 password 的元素)

练习

driver.find_element(By.CSS_SELECTOR,"[type='password']").send_keys("123456")

层级选择器

说明: 根据元素的父子关系来选择
格式1: element1>element2  通过element1来定位element2, 并且 element2 必须为 element1 的直接子元素
例如1: p[id='p1']>input     (定位指定p元素下的直接子元素input)
格式2: element1 element2  通过element1来定位element2, 并且 element2 为 element1的后代元素
例如2: p[id='p1'] input      (定位指定p元素下的后代元素 input)

练习

driver.find_element(By.CSS_SELECTOR,"div[class='zc'] input").send_keys("admin")

CSS扩展

input[type^='p']    type属性以p字母开头的元素
input[type$='d']    type属性以d字母结束的元素
input[type*='w']    type属性包含w字母的元素

练习

driver.find_element(By.CSS_SELECTOR,"input[type*='ex']").send_keys("admin")
driver.find_element(By.XPATH, "//*[@placeholder='请输入电子邮箱']").send_keys("123456@qq.com")

CSS扩展

input[type^='p']    type属性以p字母开头的元素
input[type$='d']    type属性以d字母结束的元素
input[type*='w']    type属性包含w字母的元素

XPath和CSS对比

XPath和CSS对比
	通过标签名定位
		XPath
			//input
		CSS
			input
	通过id属性定位
		XPath
			//*[@id='userA']
		CSS
			#userA
	通过class属性定位
		XPath
			//*[@class='telA']
		CSS
			.telA
	通过其他属性定位
		XPath
			//*[starts-with(@type,'x')]
				以x字母开头的type值的元素
			//*[contains(@type, 'x')]
				包含x字母的type值的元素
			//*[text()='x']
				文本内容为 x 的元素
		CSS
			[type^='x']
				以x字母开头的type值的元素
			[type*='x']
				包含x字母的type值的元素
			[type$='x']
				以x字母结尾的type值的元素

元素定位分类汇总

1. id, name, class_name: 元素属性定位
2. tag_name: 元素标签名定位
3. link_text, partial_link_text: 通过文本定位超链接
4. XPath: 通过路径定位元素
5. CSS: 使用CSS选择器定位

元素操作

方法

click()			单击元素
send_keys()		模拟输入
clear()			清除文本

案例

需求:打开注册A页面,完成以下操作
1.通过脚本执行输入用户名:admin;密码:123456;电话号码:18611111111;电子邮件:123@qq.com
2.间隔3秒,修改电话号码为:18600000000
3.间隔3秒,点击‘注册’按钮
4.间隔3秒,关闭浏览器
ps: 元素定位方法不限

代码

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
# 打开注册A页面,完成以下操作
# 1.通过脚本执行输入用户名:admin;密码:123456;电话号码:18611111111;电子邮件:123@qq.com
# 2.间隔3秒,修改电话号码为:18600000000
# 3.间隔3秒,点击‘注册’按钮
# 4.间隔3秒,关闭浏览器
# ps: 元素定位方法不限
driver.get("file:///C:/Users/57769/Desktop/pagetest/%E6%B3%A8%E5%86%8CA.html")
# 1
driver.find_element_by_id("userA").send_keys("admin")
driver.find_element_by_id("passwordA").send_keys("123456")
driver.find_element_by_id("telA").send_keys("18611111111")
driver.find_element_by_name("emailA").send_keys("123@qq.com")
# 2
time.sleep(3)
driver.find_element_by_id("telA").clear()
driver.find_element_by_id("telA").send_keys("18600000000")
# 3
time.sleep(3)
driver.find_element_by_css_selector("body > div > fieldset > form > p:nth-child(5) > button").click()
# 4
time.sleep(3)
driver.close()

浏览器操作

import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("file:///C:/Users/57769/Desktop/pagetest/%E6%B3%A8%E5%86%8CA.html")
## maximize_window() 浏览器窗口最大化
# driver.maximize_window()
## set_window_size() 设置窗口大小(单位:像素点)   set_window_position()  设置窗口的位置
# driver.set_window_size(300, 300)
# driver.set_window_position(300, 300)
## back() 后退 forward() 前进 refresh() 刷新
# driver.back()
# driver.forward()
# time.sleep(3)
# driver.refresh()
## title 获取页面标题     current_url  获取当前页面url
# print("页面标题:", driver.title)
# print("当前页面地址:", driver.current_url)
## driver.close()   关闭当前浏览器窗口  ==> 执行结果, 留下了新浪网站, 关闭了注册A页面
# time.sleep(3)
# driver.find_element_by_link_text("访问 新浪 网站").click()
# time.sleep(3)
# driver.close()
### 序号 30~48 的脚本应该使用 driver.quit() 关闭浏览器驱动 而不是 driver.close()
## driver.quit()    关闭浏览器驱动对象(关闭浏览器)    ==> 执行结果, 关闭所有窗口, 关闭浏览器驱动
time.sleep(3)
driver.find_element_by_link_text("访问 新浪 网站").click()
time.sleep(3)
driver.quit()

获取元素信息

应用场景

用于校验, 判断定位的元素是否准确

常用方法

size					返回元素大小
text					获取元素文本
get_attribute("xxx")	获取属性值, 参数是元素的属性名
is_displayed()			判断元素是否可见
is_enabled()			判断元素是否可用
is_selected()			判断元素是否选中, 用来检查复选框或单选按钮

案例

import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("file:///C:/Users/57769/Desktop/pagetest/%E6%B3%A8%E5%86%8CA.html")
# 需求: 打开A页面, 完成以下操作:
# 1.获取用户名输入框的大小
print(driver.find_element_by_id("userA").size)
# 2.获取页面上第一个超链接的文本内容
print(driver.find_element_by_tag_name("a").text)
# 3.获取页面上第一个超链接的地址
print(driver.find_element_by_tag_name("a").get_attribute("href"))
# 4.判断页面中的span标签是否可见
print(driver.find_element_by_tag_name("span").is_displayed())
# 5.判断页面中的取消按钮是否可用
print(driver.find_element_by_id("cancelA").is_enabled())
# 6.判断页面中的'旅游'对应的复选框是否为选中状态
print(driver.find_element_by_id("lyA").is_selected())
time.sleep(3)
driver.quit()

鼠标操作

什么是鼠标操作 单击, 右击, 双击, 悬停, 拖拽等

为什么要用到鼠标操作

现在web产品中存在丰富的鼠标交互方式, 作为一个web自动化测试框架, 需要应对这些鼠标操作的场景

常用方法

说明: 在Selenium中将鼠标操作的方法封装在 ActionChains 类中
实例化对象: action = ActionChains(driver)
方法:
1. context_click(element)    右击
2. double_click(element)     双击
3. move_to_element(element)    悬停
4. drag_and_drop(source, target)    拖拽
5. perform()     执行
为了更好的学习其他的方法, 我们先学习 perform() 执行方法, 因为ActionChains所有的方法都需要执行才能生效

执行的方法

说明: 在 ActionChains 类中所有提供的鼠标事件方法, 在调用的时候, 所有行为都存储在 ActionChains 对象中, 而 perform() 方法就是真正去执行所有的鼠标事件
强调: 必须调用 perform() 方法才能执行鼠标事件

鼠标右击

说明: 对于点击鼠标右键, 如果弹出的是浏览器的默认菜单, Selenium并没有提供操作菜单的方法
如果是自定义的右键菜单, 则可以通过元素定位来操作菜单中的选项

练习

import time
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
# 需求: 打开A页面, 在用户名文本框上点击鼠标右键
driver.get("file:///C:/Users/78418/Desktop/A(1).html")
# 定位用户名输入框
element = driver.find_element(By.ID,"userA")
# 执行右键点击操作
action = ActionChains(driver)
action.context_click(element).perform()
time.sleep(3)
driver.quit()

鼠标双击

action.double_click(element).perform()

鼠标悬停

action.move_to_element(element).perform()

鼠标拖动

import time
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
# 需求: 打开 drag.html 页面, 把红色方框拖动到蓝色方框上
driver.get("file:///C:/Users/78418/Desktop/drag(1).html")
red = driver.find_element(By.ID,"div1")
blue = driver.find_element(By.ID,"div2")
ActionChains(driver).drag_and_drop(red, blue).perform()
time.sleep(3)
driver.quit()

键盘操作

说明:
1. 模拟键盘上的一些按键或者组合键的输入, 如: 复制/粘贴
2. Selenium中把键盘的按键都封装在 Keys 类中

常用操作

导包
1. send_keys(Keys.BACK_SPACE)	删除键(Backspace)
2. send_keys(Keys.SPACE)		空格键(Space)
3. send_keys(Keys.TAB)			制表键(Tab)
4. send_keys(Keys.ESCAPE)		回退键(ESC)
5. send_keys(Keys.ENTER)		回车键(Enter)
6. send_keys(Keys.CONTROL, 'a')	全选(Ctrl + A)
7. send_keys(Keys.CONTROL, 'c')	复制(Ctrl + C)
提示: 以上方法很多, 不会逐一讲解, 因为调用方法都一样

案例

需求

打开 A 页面, 完成以下操作
1. 输入用户名 admin1, 暂停2s, 删除1
2. 全选用户名 admin 暂停2s
3. 复制用户名 admin 暂停2s
4. 粘贴到电话输入框

代码

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome()
driver.get("file:///C:/Users/78418/Desktop/A(1).html")
# 1. 输入用户名 admin1, 暂停2s, 删除1
element = driver.find_element(By.ID,"userA")
element.send_keys("admin1")
time.sleep(2)
element.send_keys(Keys.BACK_SPACE)
# 2. 全选用户名 admin 暂停2s
element.send_keys(Keys.CONTROL, "a")
time.sleep(2)
# 3. 复制用户名 admin 暂停2s
element.send_keys(Keys.CONTROL, "c")
time.sleep(2)
# 4. 粘贴到电话输入框
driver.find_element(By.ID,"telA").send_keys(Keys.CONTROL, "v")
time.sleep(5)
driver.quit()

元素等待

概念

定位页面元素, 如果未找到, 在指定时间内一直等待的过程

分类

  • 隐式等待
  • 显式等待

应用场景

由于一些原因, 我们想找的元素并没有立刻出来, 此时直接定位会报错, 场景如下:

  1. 网络速度慢
  2. 服务器计算慢
  3. 硬件配置差

隐式等待

方法

  1. 等待时间的设置:隐式等待设置的时间是全局的,对整个WebDriver实例都生效。可以通过driver.implicitly_wait(time_to_wait)来设置等待时间,单位为秒。
  2. 等待条件:隐式等待会在查找元素时等待一定的时间,直到元素出现在DOM中或者超时。它并不会严格等待整个指定时间,而是在找到元素后立即继续执行后续代码。
  3. 全局生效:隐式等待对整个WebDriver实例生效,这意味着无需在每个查找元素的地方都添加等待代码,从而简化了测试脚本的编写。
  4. 潜在的性能影响:由于隐式等待会在每次查找元素时都等待一定时间,所以可能会对测试执行的性能产生一定的影响。因此,在设置等待时间时,需要权衡等待时间和测试执行的速度。
  5. 超时处理:如果在等待时间内未找到元素,隐式等待会抛出NoSuchElementException异常。因此,在编写测试脚本时,需要适当处理这些异常。
# 隐式等待为全局设置 (只需要设置1次,会作用于所有元素)
# 参数:
#		timeout: 超时的时长, 单位: 秒
driver.implicitly_wait(timeout)

案例

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("file:///C:/Users/78418/Desktop/A(1).html")
# 需求: 打开A页面, 使用隐式等待定位 "延时加载的输入框", 并输入 admin
driver.implicitly_wait(5)
driver.find_element(By.CSS_SELECTOR,"input[placeholder='延时加载的输入框']").send_keys("admin")
time.sleep(3)
driver.quit()
# 不使用元素等待时, 如果找不到元素会报 NoSuchElementException 异常
# 使用隐式等待时, 如果找不到元素会报 NoSuchElementException 异常

显式等待

说明: 在Selenium中把显式等待的相关方法封装在 WebDriverWait 类中
  1. 等待条件:显式等待的核心是指定一个条件(如元素可见、元素存在、元素可点击等),WebDriver会等待直到该条件成立。例如,可以等待元素可见、可点击或包含特定文本等。
  2. 等待时间:显式等待会等待一个指定的最长时间(timeout),这段时间内会不断地检查条件是否成立。如果条件在规定的时间内成立,就会立即执行下一步操作;如果超时,就会抛出超时异常(TimeoutException)。
  3. 灵活性:显式等待比隐式等待更加灵活,因为它允许您设置不同的等待条件,而不仅仅是简单地等待元素的出现。这使得显式等待更适合于需要等待特定条件出现的场景。
  4. WebDriverWait:在使用显式等待时,通常会创建一个WebDriverWait对象,并传入一个WebDriver实例和最长等待时间。然后,调用WebDriverWait的until方法,并传入一个ExpectedCondition,以确定等待的条件是否被满足。

方法

# 显式等待, 为定位不同的元素的超时时间设置不同的值

1.导包
2.WebDriverWait(driver, timeout, poll_frequency=0.5)
	1.driver: 浏览器驱动对象
	2.timeout: 超时时长, 单位: 秒
	3.poll_frequency: 检测的间隔时间, 默认为0.5s
3.调用 until(method) 
	1.method: 函数名称, 该函数用来实现元素定位
	2.一般使用匿名来实现: lambda x: x.find_element_by_xxx("xxx")
	
如:element = WebDriverWait(driver,10,1).until(lambda x: x.find_element_by_xxx("xxx"))

案例

import time
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
driver = webdriver.Chrome()
driver.get("file:///C:/Users/57769/Desktop/pagetest/%E6%B3%A8%E5%86%8CA.html")
# 需求: 打开A页面, 使用显式等待定位 "延时加载的输入框", 并输入 admin
wait = WebDriverWait(driver, 10, 1)
element = wait.until(lambda x: x.find_element_by_css_selector("input[placeholder='延时加载的输入框']"))
element.send_keys("admin")
time.sleep(3)
driver.quit()
# 单个元素定位超时会报错 TimeoutException

隐式和显式区别

1. 作用域: 隐式等待为全局有效, 显式等待为单个元素有效
2. 使用方法: 隐式等待直接通过驱动对象调用, 而显式等待方法封装在 WebDriverWait 类中
3. 达到最大超时时长后抛出异常不同: 隐式等待为 NoSuchElementException, 显式等待为 TimeoutException

下拉框

方法一

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
# 需求: 打开A页面,完成以下下拉框操作
# 1. 暂停2s, 选择广州
# 2. 暂停2s, 选择上海
# 3. 暂停2s, 选择北京
driver.get("file:///C:/Users/78418/Desktop/A(1).html")
# 1
time.sleep(2)
driver.find_element(By.XPATH,"//*[@id='selectA']/option[3]").click()
# 2
time.sleep(2)
driver.find_element(By.XPATH,"//*[@id='selectA']/option[2]").click()
# 3
time.sleep(2)
driver.find_element(By.XPATH,"//*[@id='selectA']/option[1]").click()
time.sleep(3)
driver.quit()
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
driver = webdriver.Chrome()
# 需求: 打开A页面,完成以下下拉框操作
# 1. 暂停2s, 选择广州
# 2. 暂停2s, 选择上海
# 3. 暂停2s, 选择北京
driver.get("file:///C:/Users/78418/Desktop/A(1).html")
select = Select(driver.find_element(By.ID,"selectA"))
# 1
time.sleep(2)
select.select_by_index(2)
# 2
time.sleep(2)
select.select_by_value("sh")
# 3
time.sleep(2)
select.select_by_visible_text("北京")
time.sleep(3)
driver.quit()

方法二

说明: Select类是Selenium为操作select标签封装的 
实例化对象:
	select = Select(element)
		element: <select>标签对应的元素, 通过元素定位方式获取
			例如: driver.find_element_by_id("selectA")
操作方法:
1. select_by_index(index)		根据option索引来定位, 从0开始
2. select_by_value(value)		根据option属性 value值来定位
3. select_by_visible_text(text) 根据option显示文本内容来定位

步骤分析

1. 导包
2. 实例化Select类  select = Select(driver.find_element_by_id("selectA"))
3. 调用方法

弹出框

分类

  1. alert 警告框
  2. confirm 确认框
  3. prompt 提示框

方法

说明: Selenium中对弹出框的处理, 有专用的方法, 且处理的方法都一样(alert/confirm/prompt)

1.获取弹出框对象
	alert = driver.switch_to.alert
2.调用
	alert.text		返回alert/confirm/prompt文字信息
	alert.accept()	接受对话框选项(确认)
	alert.dismiss()	取消对话框选项(取消)

下拉框&弹出框&滚动条操作弹出框

案例

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
# 需求: 打开A页面,完成以下弹出框操作
# 1.点击 alert 按钮
# 2.暂停2s, 输入用户名 admin
driver.get("file:///C:/Users/78418/Desktop/A(1).html")
# 1
driver.find_element(By.ID,"alerta").click()
time.sleep(2)
alert = driver.switch_to.alert
print(alert.text)
time.sleep(2)
alert.accept()
# 2
time.sleep(2)
driver.find_element(By.ID,"userA").send_keys("admin")
time.sleep(3)
driver.quit()

实现方法

方法

说明: Selenium中没有提供滚动条的操作方法, 但是它提供了执行 JS 的方法, 所有我们可以通过 JS脚本来操作滚动条

1. 设置 JS 脚本控制滚动条
	js = "window.scrollTO(0,1000)"
		(0:左边距, 1000:上边距   单位:像素(px))
2. Selenium 调用执行 JS 脚本的方法
	driver.execute_script(js)
import time
from selenium import webdriver
driver = webdriver.Chrome()
# 需求: 打开A页面
driver.get("file:///C:/Users/78418/Desktop/A(1).html")
# js1 滚动到最底部
js1 = "window.scrollTo(0, 10000)"
# js2 滚动到最顶部
js2 = "window.scrollTo(0, 0)"
# 执行第一个脚本
time.sleep(2)
driver.execute_script(js1)
# 执行第二个脚本
time.sleep(2)
driver.execute_script(js2)
time.sleep(3)
driver.quit()

frame切换

frame : html页面中的一种框架, 主要作用是在当前页面指定区域显示另一个页面元素

形式一:
	<frameset cols="25%,75%">
		<frame src="a.html">
		<frame src="b.html">
	</frameset>
形式二:
	<iframe name="iframe_a" src="demo.html" width="200" height="200"></iframe>

方法

说明: 在Selenium中封装了如何切换frame框架的方法

步骤:
	1.driver.switch_to.frame(frame_reference)   切换到指定frame
		frame_reference: 可以传frame框架的id,name,定位的frame元素
	2.driver.switch_to.default_content()    恢复默认页面
		必须回到默认页面才能进一步操作

解决方案

  1. 在主页面输入用户名 admin
  2. 切换到A页面, 再输入用户名 adminA
  3. 恢复默认页面
  4. 切换到B页面, 再输入用户名 adminB
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
# 需求: 打开"注册实例"页面
driver.get("file:///C:/Users/78418/Desktop/A(1).html")
# 1.填写主页面的用户名 admin
time.sleep(2)
driver.find_element(By.ID,"userA").send_keys("admin")
# 2.填写注册页面A中的用户名 adminA
time.sleep(2)
# driver.switch_to.frame("idframe1")  # 从主页面, 切换到了A页面, 通过 id
# driver.switch_to.frame("myframe1")  # 从主页面, 切换到了A页面, 通过 name
driver.switch_to.frame(driver.find_element(By.ID,"idframe1"))  # 从主页面, 切换到了A页面, 通过 定位到的元素
driver.find_element(By.ID,"userA").send_keys("adminA")
# 3.回到主页面
time.sleep(1)
driver.switch_to.default_content()
# 4.填写注册页面B中的用户名 adminB
time.sleep(1)
driver.switch_to.frame("idframe2")  # 从主页面, 切换到B页面
driver.find_element(By.ID,"userA").send_keys("adminB")
time.sleep(3)
driver.quit()

多窗口切换

概念

什么是窗口? 窗口类似于浏览器中的标签页, 每个窗口就对应了一个标签页

为什么要切换窗口? 在html页面中, 当点击按钮或超链接时, 有的会在新窗口打开页面

如果点击按钮或超链接在当前窗口打开新页面, 就不需要切换窗口

需求

打开A页面
1.在新窗口打开新浪页面
2.在新浪的搜索框输入"新浪搜索"
3.在A页面输入用户名 admin

方法

说明: 在Selenium中封装了获取当前窗口句柄,获取所有窗口句柄和切换到指定句柄窗口的方法
句柄: 英文handle, 窗口的唯一识别码
方法:
	1.driver.current_window_handle		获取当前窗口句柄
	2.driver.window_handles				获取所有窗口句柄
	3.driver.switch_to.window(handle)	切换到指定句柄的窗口

对于需求的解决方案:

  1. 打开A页面, 获取当前窗口句柄(拿到的是A页面的句柄)
  2. 在A页面点击"访问 新浪 网站" 这个超链接, 获取所有窗口句柄
  3. 根据句柄, 切换到新浪窗口, 对输入框输入 “新浪搜索”
  4. 切换回原本窗口(A页面), 输入用户名 admin

注意: 新浪页面需要访问网络, 可能加载慢, 可能需要用到元素等待

代码

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
# 隐式等待10秒, 以防新浪窗口加载慢, 定位不到输入框
driver.implicitly_wait(10)
# 1. 打开A页面, 获取当前窗口句柄(拿到的是A页面的句柄)
driver.get("file:///C:/Users/78418/Desktop/A(1).html")
print("当前A页面窗口句柄:", driver.current_window_handle)
# 2. 在A页面点击"访问 新浪 网站" 这个超链接, 获取所有窗口句柄
driver.find_element(By.ID,"fw").click()
handles = driver.window_handles
print("所有窗口句柄:", handles)
# 3. 根据句柄, 切换到新浪窗口, 对输入框输入 "新浪搜索"
driver.switch_to.window(handles[1])
time.sleep(1)
driver.find_element(By.CLASS_NAME,"inp-txt").clear()
time.sleep(1)
driver.find_element(By.CLASS_NAME,"inp-txt").send_keys("新浪搜索")
time.sleep(2)
# 4. 切换回原本窗口(A页面), 输入用户名 admin
driver.switch_to.window(handles[0])
driver.find_element_by_id("userA").send_keys("admin")
time.sleep(3)
driver.quit()

窗口截图

概念

什么是窗口截图?

把当前操作的页面, 截图保存到指定的位置

为什么要窗口截图?

有时候打印的错误信息不十分准确, 需要窗口截图辅助定位错误

方法

说明: 在Selenium中提供了截图方法, 我们只需要调用即可

方法:
	driver.get_screenshot_as_file(imgpath)
		imgpath: 图片保存路径 + 图片名

代码

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
# 需求: 打开 A 页面, 完成以下操作
# 1.输入用户名 admin
# 2.截图保存
driver.get("file:///C:/Users/57769/Desktop/pagetest/%E6%B3%A8%E5%86%8CA.html")
# 1
driver.find_element(By.ID,"userA").send_keys("admin")
# 2
time.sleep(1)
# 每次都是用固定文件名, 会股改上一次生成的图片文件
# driver.get_screenshot_as_file("./png/123.png")  # 需要提前创建 png 目录
# 使用时间去格式化文件名, 可以使每次截图保存的文件名都不同, 不会覆盖之前保存的文件, 更有效
imgpath = "./png/test_{}.png".format(time.strftime("%Y%m%d%H%M%S"))
driver.get_screenshot_as_file(imgpath)
time.sleep(3)
driver.quit()

验证码处理

概念

什么是验证码?

一种随机生成的信息 (数字, 字母, 汉字, 图片, 算术题…) 等为了防止恶意的请求行为, 增加应用的安全性

为什么要学习验证码?

在web应用中, 大部分系统在用户登录注册的时候都需要输入验证码, 而我们自动化脚本也要面临处理验证码的问题

常用方法

说明: Selenium中并没有对验证码处理的方法, 在这里我们介绍几种常用的处理方式
方法:
	1.去掉验证码(测试环境下采用)
	2.设置万能验证码(生产和测试环境下采用)
	3.验证码识别技术(通过 python-tesseract 来识别图片类型的验证码: 识别率很难达到100%)
	4.记录 cookie(通过记录 cookie 进行跳过登录)
ps: 
1 和 2, 都是开发人员来完成, 我们不讲解
3 验证码识别技术成功率不高, 不太合适
4 记录cookie 比较实用, 推荐

cookie概念

1. cookie是由web服务器生成的, 并且保存在用户浏览器上的小文本文件, 它可以包含用户信息
2. cookie数据格式: 键值对 (python中的字典)
3. cookie产生: 客户端请求服务器, 如果服务器需要记录该用户状态, 就向客户端浏览器颁发一个cookie数据
4. cookie使用: 当浏览器再次请求该网站时, 浏览器把请求的数据和cookie数据一同提交给服务器, 服务器检查该cookie, 以此来辨认用户

应用场景

1. 实现会话跟踪, 记录用户登录状态
2. 实现记住密码和自动登录的功能
3. 用户未登录状态下, 记录购物车中的商品

cookie方法

说明: Selenium中对cookie操作提供相应的方法

方法:
	1.driver.get_cookies()				获取本网站所有本地cookies
	2.driver.get_cookie(name)			获取指定cookie
		name: 为cookie中键值对数据的 键名
	3.driver.add_cookie(cookie_dict)	添加cookie
		cookie_dict: 一个字典对象, 必选的内容包括: "name" 和 "value"

cookie案例

需求

使用cookie 实现跳过百度登录
1. 手动登录百度, 获取cookie
2.请求百度, 并且带上cookie

步骤分析

BDUSS是登录百度后的唯一身份凭证, 拿到BDUSS就等于拿到了账号的控制权,通行贴吧,知道,文库...主要产品

1.登录百度, 抓取BDUSS
2.添加 BDUSS 的键值对
3.调用刷新的方法

代码

import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.maximize_window()
# 需求: 使用cookie 实现跳过百度登录
# 1.手动登录百度, 获取cookie
# 2.请求百度, 并且带上cookie
# 没有cookie的时候
driver.get("http://www.baidu.com")
# 添加cookie操作  value值要根据你登录百度后 BDUSS所对应的 value去调整
driver.add_cookie({"name": "BDUSS", "value": "VZMUEl0WFJQYkxNSXk0c0VMUk5ZNGYteWVYNG01aVJtZXFCV056alk5M3V3SUZlSVFBQUFBJCQAAAAAAAAAAAEAAAC2KUFmTFhKX0pheQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO4zWl7uM1peQ"})
time.sleep(3)
# 刷新, 再次请求百度首页, 验证是否带上身份信息
driver.refresh()
time.sleep(3)
driver.quit()
  • 30
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值