selenium实现web自动化测试

Web自动化测试

课程大纲

序号 章节 知识点
1 第一章 Web自动化入门 1.认识自动化及自动化测试
2.自动化测试工具选择
3.环境搭建
2 第二章 Selenium-API 1.元素定位方式
2.元素和浏览器的操作方法
3.鼠标和键盘操作
4.元素等待
5.HTML特殊元素处理
6.窗口截图
7.验证码处理
3 第三章 Pytest框架 1.Pytest基本使用
4 第四章 PO模式 1.方法封装
2.PO模式介绍
3.PO模式实战
5 第五章 数据驱动 1.JSON读写
2.数据驱动介绍
3.数据驱动实战
6 第六章 日志收集 1.日志相关概念
2.日志的基本方法
3.日志的高级方法

第一章 Web自动化入门

1 自动化

1.1 概念

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

1.2 优点

  • 减少人工劳动力

  • 提高工作效率

  • 产品规格统一标准

  • 规模化(批量生产)

  • 安全

2 自动化测试

2.1 概念

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

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

2.2 应用场景

  • 解决-回归测试

    回归测试:项目在发新版本之后对项目之前的功能进行验证

  • 解决-压力测试

    压力测试:可以理解多用户同时去操作软件,统计软件服务器处理多用户请求的能力

  • 解决-兼容性测试

    兼容性测试:不同浏览器(IE、Firefox、Chrome)等等,执行的用例都是同一条,只是浏览器不同

  • 解决-冒烟测试

    冒烟测试:针对最基本的功能或者流程进行的测试

  • 提高测试效率,保证产品质量

2.3 正确认识(存在即合理)

优点

  • 较少的时间内运行更多的测试用例
  • 自动化脚本可重复运行
  • 减少人为的错误
  • 克服手工测试的局限性

误区

  • 自动化测试可以完全替代手工测试
  • 自动化测试一定比手工测试厉害
  • 自动化测试可以发掘更多的BUG (自动化脚本执行的用例一般都是重复的,操作都是一致的)
  • 自动化测试适用于所有功能

2.4 分类

  • Web-自动化测试 (本阶段学习)
  • 移动-自动化测试
  • 接口-自动化测试
  • 桌面自动化 (桌面层次的自动化)
  • 单元测试-自动化测试
  • web自动化/移动自动化测试都属于UI自动化

3 Web自动化测试

概念

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

什么是接口自动化测试?

什么是移动自动化测试?

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

  • 需求变动不频繁 (如果需求变动频繁,脚本代码需要变动,将会浪费大量时间精力)
  • 项目周期长 (如果周期过短,整个测试流程的时间有限,优先完成功能测试,编写脚本太费时间)
  • 项目需要回归测试

Web自动化测试什么时候开始

手工测试结束后 (为什么是手工测试结束?)

web自动化测试的场景多为回归测试

Web自动化测试所属分类

属于功能测试 (黑盒)

我们编写了自动化的脚本进行测试为什么不属于白盒或者灰盒?

我们编写的自动化脚本本身不属于程序内部的代码

4 Selenium

4.1 Web自动化工具简介

主流工具

  • QTP

    一个商业化的功能测试工具, 收费, 支持web/ 桌面自动化测试

  • Selenium(重点)

    一个开源的web自动化测试工具, 主要做功能测试(开源)

  • Robot framework

    一个基于python可扩展的关键字驱动的自动化测试框架(运用较少)

    什么是关键字驱动?

    什么是驱动?

Selenium特点

  • 开源软件:源代码开放可以根据需要来增加工具的某些功能
  • 跨平台:linux、windows、mac
  • 支持多种浏览器:Firefox、Chrome、IE、Edge、Opera、Safari等
  • 支持多种语言:Python、Java、C#、JavaScript、Ruby、PHP等
  • 成熟稳定:目前已经被google、百度、腾讯等公司广泛使用
  • 功能强大:能够实现类似商业工具的大部分功能,因为开源性,可实现定制化功能(二次开发)

4.2 环境搭建

4.2.1 搭建步骤

基于python搭建环境:

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

  2. 安装 selenium 包

  3. 安装浏览器

  4. 安装浏览器驱动

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

为什么我们是基于python搭建的,能基于其他语言进行环境搭建吗?

4.2.2 安装selenium包

安装

pip install selenium

验证

pip list
# 或者
pip show selenium

卸载

pip uninstall selenium

离线安装

  • 把下载好的selenium包放到 D:\python\Lib\site-packages\ 下
  • 命令行, 进入到~\python\Lib\site-packages\selenium-3.141.0
  • 执行 python setup.py install
4.2.3 安装浏览器驱动

驱动下载

  • Chrome

    下载地址: http://chromedriver.storage.googleapis.com/index.html

    镜像地址: http://npm.taobao.org/mirrors/chromedriver/

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

  • Firefox

    下载地址: https://github.com/mozilla/geckodriver/releases

  • Edge(ie浏览器的改进版)

    下载地址: https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/

安装步骤

  1. 下载浏览器驱动

    各个驱动下载地址: http://www.seleniumhq.org/download/

    浏览器的版本和驱动版本要一致

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

    或者直接放到Python安装目录,因为Python已添加到Path中

4.3 入门示例

4.3.1 需求
通过程序启动浏览器,并打开百度首页,暂停3秒,关闭浏览器
4.3.2 实现步骤
1.导包
2.创建浏览器驱动对象
3.打开百度首页
4.暂停3秒
5.关闭驱动对象
4.3.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()

第二章 Selenium-API

1 元素定位基础

1.1 为什么进行元素定位

让程序操作指定元素,就必须先找到此元素

什么是元素?

HTML网页实际上就是由许多的HTML元素构成的文本文件,并且任何网页浏览器都可以直接运行HTML文件。所以可以这样说,HTML元素就是构成HTML文件的基本对象,HTML元素可以说是一个统称而已。HTML元素就是通过使用HTML标签进行定义的。

什么是标签?

标签就是、、

等被尖括号“<”和“>”包起来的对象,绝大部分的标签都是成对出现的,如
、。

标签就是用来标记HTML元素的。位于起始标签和结束标签之间的文本就是HTML元素的内容。

什么是属性?

为HTML元素提供各种附加信息的就是HTML属性,它总是以"属性名=属性值"这种名值对的形式出现,而且属性总是在HTML元素的开始标签中进行定义。

1.2 如何进行元素定位

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

html页面由标签构成,标签的基本格式如下:
	<标签名 属性名1="属性值1" 属性名2="属性值2">文本
示例:
    
    
我的购物车

思考:如何快速的查看一个元素的相关信息?

1.3 浏览器开发者工具

概念

浏览器开发者工具就是给专业的web应用和网站开发人员使用的工具。包含了对HTML查看和编辑、Javascript控制台、网络状况监视等功能,是开发JavaScript、CSS、HTML和Ajax的得力助手

作用

定位元素, 查看元素信息

使用

需求:

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

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

1.4 元素定位方式

1.4.1 总体介绍
Selenium提供了八种定位元素方式
1. id
2. name
3. class_name
4. tag_name
5. link_text
6. partial_link_text
7. XPath
8. CSS

id、name、class_name:为元素属性定位
tag_name:为元素标签名称
link_text、partial_link_text:为超链接定位(a标签)
XPath:为元素路径定位
CSS:为CSS选择器定位
1.4.2 id定位
说明:id定位就是通过元素的id属性来定位元素,HTML规定id属性在整个HTML文档中必须是唯一的;
前提:元素有id属性
但是id唯一不是硬性要求,一般情况id都是唯一的

方法

element = driver.find_element_by_id(id)

案例

案例演示环境说明:
受限于网络速度的影响,我们案例采用本地的html页面来演示。这样可以提高学习效率和脚本执行速率

需求:打开注册A.html页面,完成以下操作
1.使用id定位,输入用户名:admin
2.使用id定位,输入密码:123456
3.3秒后关闭浏览器窗口
实现步骤分析:
1. 导入selenium包 --> from selenium import webdriver
2. 导入time包 --> import time
3. 实例化浏览器驱动对象 --> driver = webdriver.Firefox()
4. 打开注册A.html --> driver.get(url)
5. 调用id定位方法 --> element = driver.find_element_by_id("")
6. 使用send_keys()方法输入内容 --> element.send_keys("admin")
7. 暂停3秒 --> time.sleep(3)
8. 关闭浏览器驱动对象 --> driver.quit()

说明:为了更好的学习体验,我们先暂时使用下send_keys()方法来输入内容

代码:

# 1.导包
import time
from selenium import webdriver

# 2.创建浏览器驱动对象
driver = webdriver.Chrome()

# 3.业务操作
driver.get("C:\\Users\\Administrator.USER-20190219YL\\Desktop\\pagetest\\注册A.html")
driver.find_element_by_id("userA").send_keys("admin")
driver.find_element_by_id("passwordA").send_keys("123456")

# 4.暂停3秒
time.sleep(3)

# 5.关闭驱动对象
driver.quit()
1.4.3 name定位
说明:name定位就是根据元素name属性来定位。HTML文档中name的属性值是可以重复的。
前提:元素有name属性

方法

element = driver.find_element_by_name(name)

案例

需求:打开注册A.html页面,完成以下操作
1.使用name定位,输入用户名:admin
2.使用name定位,输入密码:123456
3.3秒后关闭浏览器窗口

代码:

# 1.导包
import time
from selenium import webdriver

# 2.创建浏览器驱动对象
driver = webdriver.Chrome()

# 3.业务操作
driver.get("C:\\Users\\Administrator.USER-20190219YL\\Desktop\\pagetest\\注册A.html")
driver.find_element_by_name("userA").send_keys("admin")
driver.find_element_by_name("passwordA").send_keys("123456")

# 4.暂停3秒
time.sleep(3)

# 5.关闭驱动对象
driver.quit()
1.4.4 class_name定位
说明:class_name定位就是根据元素class属性值来定位元素。HTML通过使用class来定义元素的样式
前提:元素有class属性
注意:如果class有多个属性值,只能使用其中的一个

方法

element = driver.find_element_by_class_name(class_name)

案例

需求:打开注册A.html页面,完成以下操作
1.通过class_name定位电话号码A,并输入:13122223333
2.通过class_name定位电子邮箱A,并输入:[email protected]
3.3秒后关闭浏览器窗口

代码:

# 1.导包
import time
from selenium import webdriver

# 2.创建浏览器驱动对象
driver = webdriver.Chrome()

# 3.业务操作
driver.get("C:\\Users\\Administrator.USER-20190219YL\\Desktop\\pagetest\\注册A.html")
driver.find_element_by_class_name("telA").send_keys("13122223333")
driver.find_element_by_class_name("emailA").send_keys("[email protected]")

# 4.暂停3秒
time.sleep(3)

# 5.关闭驱动对象
driver.quit()
1.4.5 tag_name定位
说明:tag_name定位就是通过标签名来定位;
HTML本质就是由不同的tag组成,每一种标签一般在页面中会存在多个,所以不方便进行精确定位,一般很少使用

方法

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

案例

需求:打开注册A.html页面,完成以下操作
1.使用tag_name定位用户名输入框,并输入:admin
2.3秒后关闭浏览器窗口

代码:

# 1.导包
import time
from selenium import webdriver

# 2.创建浏览器驱动对象
driver = webdriver.Chrome()

# 3.业务操作
driver.get("C:\\Users\\Administrator.USER-20190219YL\\Desktop\\pagetest\\注册A.html")
driver.find_element_by_tag_name("input").send_keys("admin")

# 4.暂停3秒
time.sleep(3)

# 5.关闭驱动对象
driver.quit()
1.4.6 link_text定位
说明:link_text定位是专门用来定位超链接元素(标签),并且是通过超链接的文本内容来定位元素

方法

element = driver.find_element_by_link_text(link_text)
# link_text:为超链接的全部文本内容

案例

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

代码:

# 1.导包
import time
from selenium import webdriver

# 2.创建浏览器驱动对象
driver = webdriver.Chrome()

# 3.业务操作
driver.get("C:\\Users\\Administrator.USER-20190219YL\\Desktop\\pagetest\\注册A.html")
driver.find_element_by_link_text("访问 新浪 网站").click()

# 4.暂停3秒
time.sleep(3)

# 5.关闭驱动对象
driver.quit()
1.4.7 partial_link_text定位
说明:partial_link_text定位是对link_text定位的补充,link_text使用全部文本内容匹配元素,而partial_link_text可以使用局部来匹配元素,也可以使用全部文本内容匹配元素

方法

element = driver.find_element_by_partial_link_text(partial_link_text)
# partial_link_text:可以传入a标签局部文本-能表达唯一性

案例

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

代码:

# 1.导包
import time
from selenium import webdriver

# 2.创建浏览器驱动对象
driver = webdriver.Chrome()

# 3.业务操作
driver.get("C:\\Users\\Administrator.USER-20190219YL\\Desktop\\pagetest\\注册A.html")
driver.find_element_by_partial_link_text("访问").click()

# 4.暂停3秒
time.sleep(3)

# 5.关闭驱动对象
driver.quit()

1.5 定位一组元素

使用上述方法的时候, 发现有一些类似的方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TRn7ywk1-1609329063534)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201222143040129.png)]

方法

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

案例

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

代码:

# 1.导包
import time
from selenium import webdriver

# 2.创建浏览器驱动对象
driver = webdriver.Chrome()

# 3.业务操作
driver.get("C:\\Users\\Administrator.USER-20190219YL\\Desktop\\pagetest\\注册A.html")
#elements = driver.find_elements_by_tag_name("input")
#elements[1].send_keys("123456")
driver.find_elements_by_tag_name("input")[1].send_keys("123456")

# 4.暂停3秒
time.sleep(3)

# 5.关闭驱动对象
driver.quit()

2 元素定位-XPath/CSS

2.1 总体介绍

为什么要学习XPath/CSS定位

1. 如果要定位的元素没有id、name、class属性,该如何进行定位?
2. 如果通过name、class、tag_name无法定位到唯一的元素,该如何进行定位?
示例:
	

2.2 XPath定位

2.2.1 什么是XPath

跟之前学接口测试jmeter中的xpath提取器有什么区别?

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

XML:一种标记语言,用于数据的存储和传递。 后缀.xml结尾


    
        3
        3
        3
        等边三角形
    
    
        4
        4
        5
        等腰三角形
    

XPath之所以强大, 是因为它有非常灵活的定位方式

2.2.2 XPath定位方式
2.2.2.1 总体介绍

四种定位方式

1. 路径-定位
2. 利用元素属性-定位
3. 属性与逻辑结合-定位
4. 层级与属性结合-定位

方法

element = driver.find_element_by_xpath(xpath)
2.2.2.2 路径

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

  1. 绝对路径以/html根节点开始,使用/来分隔元素层级
    如:/html/body/div/fieldset/p[1]/input
  2. 绝对路径对页面结构要求比较严格,不建议使用

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

  1. 相对路径以//开始

  2. 格式://input 或者 //*

    如://input[@id=‘passwordA’] #找input标签,并且查找id是passwordA的元素

    如果是//*input[@id=‘passwordA’] #找所有的标签,并且查找id是passwordA的元素

练习

需求:打开注册A.html页面,完成以下操作
1.使用绝对路径定位用户名输入框,并输入:admin
2.暂停2秒
3.使用相对路径定位密码输入框,并输入:123

核心代码:

driver.find_element_by_xpath("/html/body/div/fieldset/form/p[1]/input").send_keys("admin")
time.sleep(2)
driver.find_element_by_xpath("//*[@id='passwordA']").send_keys("123")
2.2.2.3 利用元素属性
说明:通过使用元素的属性信息来定位元素
格式://input[@id='userA'] 或者 //*[@id='userA']
//input[@id='userA'] 是你知道他的层级是input标签,而且你也知道他的id是userA
//*[@id='userA'] 是你不知道他是哪个层级的标签,*代表全部,但是你知道他的id是userA

练习

需求:打开注册A.html页面,完成以下操作
利用元素的属性信息精确定位用户名输入框,并输入:admin
2.2.2.4 属性与逻辑结合
说明:解决元素之间个相同属性重名问题
格式://*[@name='tel' and @class='tel']

练习

需求:打开注册A.html页面,完成以下操作
使用属性与逻辑结合定位策略,在密码对应的输入框里输入:123

核心代码:

driver.find_element_by_xpath("//*[@type='password' and @id='passwordA']").send_keys("123")
2.2.2.5 层级与属性结合
说明:如果通过元素自身的信息不方便直接定位到该元素,则可以先定位到其父级元素,然后再找到该元素
格式://*[@id='p1']/input

练习

需求:打开注册A.html页面,完成以下操作
使用层级与属性结合定位策略,在test1对应的输入框里输入:test1

核心代码:

driver.find_element_by_xpath("//*[@id='p1']/input").send_keys("test1")
2.2.2.6 XPath扩展
//*[text()="xxx"] 文本内容是xxx的元素
//*[contains(@attribute,'xxx')] 属性中含有xxx的元素    #attribute是属性名
//*[starts-with(@attribute,'xxx')] 属性以xxx开头的元素

举例:

driver.find_element_by_xpath("//*[text()='访问 新浪 网站']").click()
driver.find_element_by_xpath("//*[contains(@placeholder,'用户名')]").send_keys('admin')
driver.find_element_by_xpath("//*[starts-with(@placeholder,'请输入密')]").send_keys('123')

2.3 CSS定位

前端三件宝:html,js,css

html管理布局,js做效果,css做样式

如:html告诉你一个人应该有什么器官,js告诉你一个人能做哪些行为动作,css表示一个人长什么样

如:你想去定义一只手长啥样,你需要先定位到哪只手,才能去定义他的样式

css选择器,是css提供的一种定位方式。

2.3.1 什么是CSS
1. CSS(Cascading Style Sheets)是一种语言,它用来描述HTML元素的显示样式
2. 在CSS中,选择器是一种模式,用于选择需要添加样式的元素
3. 在Selenium中也可以使用这种选择器来定位元素

提示:
1. 在selenium中推荐使用CSS定位,因为它比XPath定位速度要快
2. css选择器语法非常强大,在这里我们只学习在测试中常用的几个
2.3.2 CSS定位方式
2.3.2.1 总体介绍

常用定位方式

1. id选择器
2. class选择器
3. 元素选择器
4. 属性选择器
5. 层级选择器

方法

element = driver.find_element_by_css_selector(css_selector)
2.3.2.2 id选择器
说明:根据元素id属性来选择
格式:#id
例如:#userA <选择id属性值为userA的元素>

练习

需求:打开注册A.html页面,完成以下操作
使用CSS定位方式中id选择器定位用户名输入框,并输入:admin

核心代码:

driver.find_element_by_css_selector("#userA").send_keys("admin")
2.3.2.3 class选择器
说明:根据元素class属性来选择
格式:.class
例如:.telA <选择class属性值为telA的所有元素>

练习

需求:打开注册A.html页面,完成以下操作
使用CSS定位方式中class选择器定位电话号码输入框,并输入:13100000000

核心代码:

driver.find_element_by_css_selector(".telA").send_keys("123456")
2.3.2.4 元素选择器
说明:根据元素的标签名选择
格式:element
例如:input <选择所有input元素>

练习

需求:打开注册A.html页面,完成以下操作
使用CSS定位方式中元素选择器定位注册按钮,并点击

核心代码:

driver.find_element_by_css_selector("button").click()
2.3.2.5 属性选择器
说明:根据元素的属性名和值来选择
格式:[attribute=value] element[attribute=value]
例如:[type="password"] <选择type属性值为password的元素>

练习

需求:打开注册A.html页面,完成以下操作
使用CSS定位方式中属性选择器定位密码输入框,并输入:123456

核心代码:

driver.find_element_by_css_selector("[type='password']").send_keys("123456")
2.3.2.6 层级选择器
说明:根据元素的父子关系来选择
格式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>

练习

需求:打开注册A.html页面,完成以下操作
使用CSS定位方式中的层级选择器定位用户名输入框,并输入:admin

核心代码:

#driver.find_element_by_css_selector("p[id='pa']>input").send_keys("admin")
driver.find_element_by_css_selector("div[class='zc'] input").send_keys("admin")
2.3.2.7 CSS扩展
input[type^='p'] type属性以p字母开头的元素
input[type$='d'] type属性以d字母结束的元素
input[type*='w'] type属性包含w字母的元素

举例:

# 输入用户名
# driver.find_element_by_css_selector("input[type^='t']").send_keys("admin")
driver.find_element_by_css_selector("input[id^='u']").send_keys("admin")
driver.find_element_by_css_selector("input[type$='t']").send_keys("admin")
driver.find_element_by_css_selector("input[type*='ex']").send_keys("admin")

2.4 XPath和CSS对比

定位方式 XPath CSS
元素名 //input input
id //*[@id=‘userA’] #userA
class //*[@class=‘telA’] .telA
属性 1. //[starts-with(@attribute,‘x’)]
2. //
[text()=“x”]
3. //*[contains(@attribute,‘x’)]
1. input[type^=‘x’]
2. input[type$=‘x’]
3. input[type*=‘x’]

3 元素定位总结

3.1 元素定位分类汇总

1. id、name、class_name:为元素属性定位
2. tag_name:为元素标签名称
3. link_text、partial_link_text:为超链接定位(a标签)
4. XPath:为元素路径定位
5. CSS:为CSS选择器定位

3.2 另一种写法

3.2.1 方法介绍

方法

方法:find_element(by=By.ID, value=None)
备注:需要两个参数,第一个参数为定位的类型由By提供,第二个参数为定位的具体方式
导包:from selenium.webdriver.common.by import By

示例

1. driver.find_element(By.CSS_SELECTOR, '#emailA').send_keys("[email protected]")
2. driver.find_element(By.XPATH, '//*[@id="emailA"]').send_keys('[email protected]')
3. driver.find_element(By.ID, "userA").send_keys("admin")
4. driver.find_element(By.NAME, "passwordA").send_keys("123456")
5. driver.find_element(By.CLASS_NAME, "telA").send_keys("13111111111")
6. driver.find_element(By.TAG_NAME, 'input').send_keys("123")
7. driver.find_element(By.LINK_TEXT, '访问 新浪 网站').click()
8. driver.find_element(By.PARTIAL_LINK_TEXT, '访问').click()
3.2.2 区别
    def find_element_by_id(self, id_):
        """Finds an element by id.

        :Args:
         - id\_ - The id of the element to be found.

        :Returns:
         - WebElement - the element if it was found

        :Raises:
         - NoSuchElementException - if the element wasn't found

        :Usage:
            element = driver.find_element_by_id('foo')
        """
        return self.find_element(by=By.ID, value=id_)

4 元素操作

4.1 应用场景

1. 需要让脚本模拟用户给指定元素输入值
2. 需要让脚本模拟人为删除元素的内容
3. 需要让脚本模拟点击操作

4.2 方法

1. click() 单击元素
2. send_keys(value) 模拟输入
3. clear() 清除文本

4.3 案例

需求

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

操作难点分析

1. 修改电话号码,先清除再输入新的号码; 清除 --> clear()
2. 点击按钮 --> click()

5 浏览器操作

5.1 应用场景

脚本启动浏览器窗口大小默认不是全屏?
如何刷新页面?

怎样解决这些问题?

5.2 方法

1. maximize_window() 				最大化浏览器窗口 --> 模拟浏览器最大化按钮
2. set_window_size(width, height) 	设置浏览器窗口大小 --> 设置浏览器宽、高(像素点)
3. set_window_position(x, y) 		设置浏览器窗口位置 --> 设置浏览器位置
4. back() 							后退 --> 模拟浏览器后退按钮
5. forward() 						前进 --> 模拟浏览器前进按钮
6. refresh() 						刷新 --> 模拟浏览器F5刷新
7. close() 							关闭当前窗口 --> 模拟点击浏览器关闭按钮
8. quit() 							关闭浏览器驱动对象 --> 关闭所有程序启动的窗口
9. title 							获取页面title
10. current_url 					获取当前页面URL

close关闭与quit关闭有什么区别?

close关闭的是当前页面,但是浏览器驱动还在,会造成内存泄露,最终导致内存溢出

quit关闭的是当前浏览器驱动

5.3 示例

# 最大化浏览器
driver.maximize_window()
# 刷新
driver.refresh()
# 后退
driver.back()
# 前进
driver.forward()
# 设置浏览器大小
driver.set_window_size(300,300)
# 设置浏览器位置
driver.set_window_position(300,200)
# 关闭浏览器单个窗口
driver.close()
# 关闭浏览器所有窗口
driver.quit()
# 获取title
title = driver.title
# 获取当前页面url
url = driver.current_url

6 获取元素信息

应用场景

1. 如何获取元素的文本?
2. 如何获取元素属性值?
3. 如何让程序判断元素是否为可见状态?

6.2 常用方法

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

提示:
	size、text:为属性,调用时无括号;如:xxx.size

is_displayed() 和is_enabled() 扩展

面试题:如果你定位不到一个元素,请问怎么去排查?

6.3 案例

需求:使用‘注册A.html’页面,完成以下操作:
1.获取用户名输入框的大小
2.获取页面上第一个超链接的文本内容
3.获取页面上第一个超链接的地址
4.判断页面中的span标签是否可见
5.判断页面中取消按钮是否可用
6.判断页面中'旅游'对应的复选框是否为选中的状态

代码:

# 1.获取用户名输入框的大小
print(driver.find_element_by_tag_name("a").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())

7 鼠标操作

7.1 什么是鼠标操作

点击、右击、双击、悬停、拖拽等

7.2 应用场景

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

7.3 常用方法

说明:在Selenium中将操作鼠标的方法封装在ActionChains类中

实例化对象:
action = ActionChains(driver)

方法:
1. context_click(element) 			右击 --> 模拟鼠标右键点击效果
2. double_click(element) 			双击 --> 模拟鼠标双击效果
3. drag_and_drop(source, target) 	拖动 --> 模拟鼠标拖动效果
4. move_to_element(element) 		悬停 --> 模拟鼠标悬停效果
5. perform() 						执行 --> 此方法用来执行以上所有鼠标操作

为了更好的学习其他方法,我们先学习perform()执行方法,因为所有的方法都需要执行才能生效

7.4 鼠标执行-perform()

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

强调:必须调用perform()方法才能执行鼠标事件

7.5 鼠标右键-context_click()

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

练习

需求:打开注册页面A,在用户名文本框上点击鼠标右键

关键点分析

1. 导包:from selenium.webdriver.common.action_chains import ActionChains
2. 实例化ActionChains对象:action = ActionChains(driver)
3. 调用右键方法:action.context_click(element)
4. 执行:action.perform()

核心代码:

element = driver.find_element_by_id("userA")
action = ActionChains(driver).context_click(element)
action.perform()

7.6 鼠标双击-double_click()

说明:模拟双击鼠标左键操作

练习

需求:打开注册页面A,输入用户名admin,暂停3秒钟后,双击鼠标左键,选中admin

核心代码:

element = driver.find_element_by_id("userA")
element.send_keys("admin")
time.sleep(3)
ActionChains(driver).double_click(element).perform()

7.7 鼠标拖动-drag_and_drop()

说明:模拟鼠标拖动动作,选定拖动源元素释放到目标元素

关键点分析

1. 源元素 		 source = driver.find_element_by_id(xxx)
2. 目标元素 	target = driver.find_element_by_id(xxx)
3. 调用方法 	action.drag_and_drop(source, target).perform()

练习

需求:打开‘drag.html’页面,把红色方框拖拽到蓝色方框上

核心代码:

source = driver.find_element_by_id("div1")
target = driver.find_element_by_id("div2")
ActionChains(driver).drag_and_drop(source, target).perform()

7.8 鼠标悬停-move_to_element()

说明: 模拟鼠标悬停在指定的的元素上

练习

需求:打开注册页面A,模拟鼠标悬停在‘注册’按钮上

核心代码:

element = driver.find_element_by_xpath("/html/body/div/fieldset/form/p[5]/button")
ActionChains(driver).move_to_element(element).perform()

扩展:

鼠标操作ActionChains可进行链式调用,单击后可继续调用双击继续调用右键,可执行一连串操作

8 键盘操作

8.1 应用场景

思考:

如何实现复制/ 粘贴的操作?

说明:
1. 模拟键盘上一些按键或者组合键的输入 如:Ctrl+C 、Ctrl+V;
2. Selenium中把键盘的按键都封装在Keys类中

8.2 常用操作

导包:from selenium.webdriver.common.keys import 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)

提示:以上方法就不一个一个讲解了,因为调用方法都一样

8.3 案例

需求:打开注册A页面,完成以下操作
1. 输入用户名:admin1,暂停2秒,删除1
2. 全选用户名:admin,暂停2秒
3. 复制用户名:admin,暂停2秒
4. 粘贴到密码框

8.4 案例代码

# 定位用户名
element = driver.find_element_by_id("userA")
# 输入用户名
element.send_keys("admin1")
# 删除1
element.send_keys(Keys.BACK_SPACE)
# 全选
element.send_keys(Keys.CONTROL, 'a')
# 复制
element.send_keys(Keys.CONTROL, 'c')
# 粘贴
driver.find_element_by_id('passwordA').send_keys(Keys.CONTROL, 'v')

9 元素等待

9.1 概念

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

元素等待一共分为两种类型

  1. 隐式等待
  2. 显式等待

9.2 应用场景

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

  1. 网络速度慢
  2. 服务器处理请求速度慢
  3. 硬件配置原因

是否定位每个元素都应该需要元素等待?

9.3 隐式等待

方法

# 隐式等待为全局设置(只需要设置一次,就会作用于所有元素)
# 参数:
# 	timeout:超时的时长,单位:秒
driver.implicitly_wait(timeout)

案例

需求:打开注册A页面,完成以下操作
使用隐式等待定位用户名输入框,如果元素存在,就输入admin

注意点

单个元素定位超时会报 NoSuchElementException异常

9.4 显式等待

在Selenium中把显式等待的相关方法封装在 WebDriverWait 类中

方法

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

1. 导包 from selenium.webdriver.support.wait import WebDriverWait
2. WebDriverWait(driver, timeout, poll_frequency=0.5)
    1). driver:浏览器驱动对象
    2). timeout:超时的时长,单位:秒
    3). poll_frequency:检测间隔时间,默认为0.5秒
3. 调用方法 until(method):直到...时
    1). method:函数名称,该函数用来实现对元素的定位
    2). 一般使用匿名函数来实现:lambda x: x.find_element_by_id("userA")

如:ele = WebDriverWait(driver, 10, 1).until(lambda x: x.find_element_by_id("userA"))

一般函数的定义:

def test():
	print("test")
#调用方式
test()

匿名函数:

test = lambda x , y : x+y
#调用
test(1,2)
#结果为3
print(test(1,2))

案例

需求:打开注册A页面,完成以下操作
使用显示等待定位用户名输入框,如果元素存在,就输入admin

注意点

单个元素定位超时会报 TimeoutException异常

9.5 隐式和显式区别

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

10 下拉框/弹出框/滚动条操作

10.1 下拉框

10.1.1 方法一

案例

需求:使用‘注册A.html’页面,完成对城市的下拉框的操作
1.选择‘广州’
2.暂停2秒,选择‘上海’
3.暂停2秒,选择‘北京’

核心代码

driver.find_element_by_xpath("//*[@id='selectA']/option[3]").click()
time.sleep(2)
driver.find_element_by_xpath("//*[@id='selectA']/option[2]").click()
time.sleep(2)
driver.find_element_by_xpath("//*[@id='selectA']/option[1]").click()

说明: 下拉框就是 HTML 中的 元素

思路: 先定位到操作的 option 元素, 然后执行点击操作

问题: 操作起来比较繁琐

10.1.2 方法二

Select类

说明:Select类是Selenium为操作select标签特殊封装的

实例化对象:
	select = Select(element)
		element: