0


Web自动化测试入门-(Python+Pytest+selenium的基础用法)

第一章、Web自动化入门


1、自动化

1.1 概念

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

1.2 优点

  • 减少人工劳动力
  • 提高工作效率
  • 产品规格统一标准
  • 规模化(批量生产)
  • 安全

2、自动化测试

2.1 概念

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

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

2.2 应用场景

解决-冒烟测试

冒烟测试:每个版本提测前,验证其是否达到可测标准

解决-回归测试

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

解决-压力测试

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

解决-兼容性测试

兼容性测试:不同浏览器(IE、Firefox、Chrome) 等等

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

2.3 正确认识

优点

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

误区

  • 自动化测试可以完全代替手工测试
  • 自动化测试一定比手工测试厉害
  • 自动化测试可以发掘更多BUG
  • 自动化测试适用于所有功能

分类

  • Web自动化测试
  • 移动自动化测试
  • 接口自动化测试
  • 单元测试-自动化测试

3、Web自动化测试

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

  • 什么样的项目适用于Web自动化测试呢?
  • 需求变动不频繁
  • 项目周期长
  • 项目需要回归测试/冒烟测试/兼容性测试/压力测试等

Web自动化测试所属分类:功能测试(黑盒)

4、Selenium

4.1 Web自动化工具简介

主流工具

  • QTP:一个商业化功能测试工具,收费,支持Web/桌面自动化测试
  • Selenium:开源Web自动化测试工具,主要做功能测试
  • Robot Framework:一个基于python的可拓展关键字驱动的自动化测试框架

Selenium特点

  • 开源软件:源代码开放可以根据需求增加工具的某些功能
  • 跨平台:linux、windows、mac
  • 支持多种浏览器:firefox、Chrome、IE、edge、Safari等
  • 支持多种语言:Python、Java、C#、Javascript、PHP等
  • 成熟稳定:已被Google、百度、腾讯等公司广泛使用
  • 功能强大:能够实现商业工具的大部分功能,因为开源,可实现定制化功能

4.2 环境搭建

4.2.1 搭建步骤

基于python搭建环境:

1、Python开发环境(3.x以上)

2、安装Selenium包

3、安装浏览器

4、安装浏览器驱动

4.2.2 安装selenium包

  • 安装:pip install selenium
  • 验证:pip show selenium
  • 卸载:pip uninstall selenium

4.2.3 安装浏览器驱动

驱动下载

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

Firefox下载地址:

Edge下载地址:Microsoft Edge WebDriver | Microsoft Edge Developer

安装步骤

  • 1、下载浏览器驱动,浏览器版本要与驱动版本一致
  • 2、把驱动文件所在目录添加到Path环境变量中,或者直接放到python安装目录,因为python已添加到Path中

4.3 入门示例

4.3.1 需求

通过程序启动浏览器,并打开百度首页,暂停3秒,关闭浏览器

4.3.2 实现步骤

  • 导包
  • 创建浏览器驱动对象
  • 打开百度首页
  • 暂停3s
  • 关闭驱动对象
# 1、导包
import time
from selenium import webdriver

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

# 3、打开百度首页
driver.get("http://baidu.com")

# 4、暂停3s
time.sleep(3)

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

第二章、Selenium框架-基础入门

1 元素定位基础

1.1 为什么进行元素定位

让程序操作指定元素,就必须先定位到该元素

1.2 如何进行元素定位

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

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

1.3 浏览器开发者工具

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

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

使用:浏览器按F12或右键检查,选中要查看的元素

1.4 元素定位方式

1.4.1 总体介绍

Selenium提供了八种元素定位方法:id、name、class_name、tag_name、link_text、partial_link_text、XPath、CSS

1.4.2 id定位

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

前提:元素有id属性

方法

element = driver.find_element_by_id(id)

1.4.3 name定位

说明:name定位就是根据元素name属性定位。HTML文档中name的属性值是可以重复的。

前提:元素有name属性

**方法 **

element = driver.find_element_by_name(name)

1.4.4 class_name定位

说明:class_name定位是根据元素class属性值来定位元素。HTML通过使用class来定义元素的样式

前提:元素有class属性

注意:如果class有多个属性值,只能使用其中一个

方法

element = driver.find_element_by_class_name(class_name)

1.4.5 tag_name定位

说明:tag_name定位是通过标签名来定位;

HTML本质是由不同tag组成,每一种标签一般在页面中存在多个,所以不方便精确定位,一般很少用

方法

element = driver.find_element_by_tag_name(tag_name)
# 如果存在多个相同标签,则返回符合条件的第一个

1.4.6 link_text定位

说明:link_text专门定位超链接元素(标签),通过超链接的文本内容来定位元素

**方法 **

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

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标签局部文本-能表达唯一性

1.5 定位一组元素

使用上述方法发现一些类似方法

方法

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

2 元素定位-XPath/CSS

2.1 总体介绍

为什么要学习XPath/CSS定位

1、如果定位元素没有id、name、class属性,该如何定位?

2、如果通过name、class、tag_name无法定位到唯一的元素,该如何定位?
示例:<input type="submit" value="提交" /input>

2.2 XPath定位

2.2.1 XPath是什么?
1.XPath即为XML Path的简称,它是一门在 XML 文档中查找元素信息的语言
2.HTML可以看做是XML的一种实现,所以Selenium用户可以使用这种强大的语言在web应用中定位元素
XML:一种标记语言,用于数据的存储和传递。后缀.xm结尾
<?xm1 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>
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或者//*

2.2.2.3 利用元素属性

说明:通过使用元素属性信息来定位元素

格式://input[@id='userA']或者//*[@id='userA']

2.2.2.4 属性与逻辑结合

说明:解决元素之间相同属性重名问题

格式://*[@name='tel' and @class='tel']

2.2.2.5 层级与属性结合

说明:如果通过元素自身信息不发包

格式://*[@id='p1']/input

2.2.2.6 XPath拓展

//*[text()="xxx"]文本内容是xxx的元素

//*[contains(@attribute,'xxx')]属性中含有xxx的元素

//*[starts-with(@attribute,'xxx')]属性以xxx开头的元素

2.3 CSS定位

1、CSS是一种语言,用来描述HTML元素的显示样式

2、在CSS中,选择器是一种模式。用于选择需要添加样式的元素

3、Selenium中也可以使用这种选择器来定位元素

提示:

1、Selenium中推荐使用CSS定位,因为它比XPath定位速度快

2、CSS选择器语法强大,本文只说明几个在测试中常用的

2.3.1 CSS定位方式
2.3.1.1 总体介绍

常用定位方式

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

方法

element = driver.find_element_by_css_selector(css_selector)
2.3.1.2 id选择器

说明:根据元素id属性来选择

格式:#id

例如:#userA <选择id属性值未userA的元素>

2.3.1.3 class选择器

说明:根据元素class属性来选择

格式:.class

例如:.telA <选择class属性值为“telA”的所有元素>

2.3.1.3 class选择器

说明:根据元素class属性来选择

格式:.class

例如:.telA <选择class属性值为“telA”的所有元素>

2.3.1.4 元素选择器

说明:根据元素的标签名来选择

格式:element

例如:input <选择所有input元素>

2.3.1.5 属性选择器

说明:根据元素的属性名和值来选择

格式:[attribute=value] element[attribute=value]

例如:[type="password"] <选择type属性值为password的元素>

2.3.1.5 层级选择器

说明:根据元素的父子关系来选择

格式1:element1>element2 通过element1来定位element2,并且element2必须为element1的直接子元素

例如1:p[id='p1']>input <定位指定p元素下的直接子元素input>

格式2:element1 element2 通过e1ement1来定位element2,并且element2为element1的后代元索

例如2:p[id='p1']input <定位指定p元素下的后代元素input>

2.3.1.7 CSS拓展

input[type^='p'] type属性以p字母开头的元素

input[types='d'] type属性以d字母结束的元素

input[type*='w'] type属性包含w字母的元素

2.4 XPath和CSS对比

定位方式XPathCSS元素名//inputinputid//[@id='userA']#userAclass//[@class='telA'].telA属性

  1. //[starts-with(@attribute,'x’)]

  2. //[text()="x"]

  3. //*[contains(@attribute,'x’)]

  4. input[type^='x']

  5. input[type$='x']

  6. 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 另一种写法

**方法 **

方法: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()

4、元素操作

4.1 应用场景

1、需要让脚本模拟用户给指定元素输入值

2 、需要让脚本模拟人为删除元素的内容

3、需要让脚本模拟点击操作

4.2 方法

1、click() 单击元素

2、send_keys(value) 模拟输入

3、clear() 清除文本

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

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
# 获取当前页面ur1
url= driver.current_url

6、获取元素信息

6.1 应用场景

1、如何获取元素的文本

2、如何获取元素属性值

3、如何让程序判断是否为可见状态

6.2 常用方法

1.size 返回元素大小
2.text 获取元素的文本
3. get_attribute("xxx") 获取属性值,传递的参数为元素的属性名

  1. is_displayed() 判断元素是否可见

5.is_enabled() 判断元素是否可用

6.is_selected() 判断元素是否选中,用来检查复选框或单选按钮是否被选中

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

7、鼠标操作

7.1 鼠标操作是什么?

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

7.2 应用场景

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

7.3 常用方法

说明:在Se1enium中将操作鼠标的方法封装在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()

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

7.6 鼠标双击-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()

7.6 鼠标悬停-move_to_element()

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

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)

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

9、元素等待

9.1 概念

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

元素等待一共分为两种类型:1.隐式等待 2.显示等待

9.2 应用场景

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

1、网络速度较慢

2、服务器处理请求速度慢

3、硬件配置原因

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

9.3 隐式等待

方法

隐式等待为全局设置(只需要设置一次,就会作用于所有元素)

#参数:

timeout:超时的时长,单位:秒

driver.implicitly_wait(timeout)

注意点

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

9.3 显式等待

在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)一般使用匿名函数来实现:lamda x:x.find_element_by_id("userA")

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

注意点

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

9.5 隐式和显式区别

1、作用域:隐式为全局元素,显式等待为单个元素有效

2、使用方法:隐式等待直接通过驱动对象调用,而显式等待方法封装在WebDriverWait类中

3、达到最大超时时长后抛出的异常不同:隐式为NoSuchElementException,显式等待为TimeoutException

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

10.1 下拉框

10.1.1 方法一

需求:使用'注册A.htm1’页面,完成对城市的下拉框的操作

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()
10.1.2 方法二
说明:select类是selenium为操作select标签特殊封装的
实例化对象:
select=select(element)
e1ement:<se1ect>标签对应的元素,通过元素定位方式获取例如: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显示文本来定位

核心代码

select = Select (driver.find_element_by_id("selecta"))
select.select_by_index(2)
time.sleep(2)
select.select_by_value("sh")
time.sleep(2)
select.select_by_visible_text("北京")

10.2 弹出框

10.2.1 分类

网页中常见的弹出框有三种

1、alert 警告框

2、confirm 确认框

3、prompt 提示框

10.2.2 方法

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

1、获取弹出框对象

alert = driver.switich_to.alert

2、调用

alert.text 返回alert、confirm、prompt的文字信息

alert.accept() 接受对话框选项(确认)

alert.dismiss() 取消对话框选项(取消)

代码

#需求:打开A界面,完成以下弹出框操作
#1、点击alert按钮
#2、暂停2s,输入用户名admin
#1、
driver.find_element_by_id("alerta").click()
time.sleep(2)
alert = driver.switich_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()

10.3 滚动条

应用场景:在html中,由于前端技术更新,很多网站内容都是动态加载的,如页面注册同意条款,需要滚动条到最底层才能点击“同意”

实现方式:selenium没有提供操作滚动条的方法,但是提供了操作JavaScript的方法,可以通过JS脚本来操作滚动条。

1、设置JS脚本操作滚动条

js = "window.scrollTo(0,1000)"

    (0:左边距,1000:上边距         单位:像素px)

2、selenium调用执行JS脚本的方法

    driver.execute_script(js)

** 代码:**

#需求:打开页面
driver.get("A.html")
#js1滚动到最底部
js1 = "winddow.scrollTo(0,10000)" #电脑显示器很难超过10000像素的长度
#js2滚动到最顶部
js2 = "window.scrollTo(0,0)"
#调用js1代码
time.sleep(2)
driver.execute(js1)
#调用js2代码
time.sleep(2)
driver.execute(js2)

time.sleep(3)
driver.quit()

11、frame切换

11.1 frame框架概念

HTML页面中的一种框架,在当前页面指定区域显示另一个区域的元素

形式一:
    <frameset cols="25%,75%">
        <frame src="A.html">  
        <frame src="B.html">    
    </frameset>
形式二:
    <iframe name="iframe_a" scr="demo.html" wdith="200" height="200">

11.2 selenium切换frame方法

步骤:

1.driver.swtich_to.frame(frame_reference) 切换到指定frame

    frame_reference:可以传frame框架的id,name,定位的frame元素

2.driver.switch_to.default_content() 恢复默认页面

    必须回到默认页面才能进一步操作

例如frame框架中有A、B两个页面,切到A后,要先恢复默认才能再切到B

案例实战:注册实例页面有一个主注册页面,一个frame1-注册页面A,一个frame2-注册页面B,需要在主页面填入admin,A页面填入adminA,B页面填入adminB

import time
from selenium import webdriver
driver = webdriver.Edge()

driver.get("注册实例.html")
#1、填写主界面的用户名admin
time.sleep(2)
drver.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("userA"))    #切换到A页面,通过frame对象

driver.find_element_by_id("userA").send_keys(adminA)
#3、回到主界面
time.sleep(1)
driver.switch_to.default_content()
#4、填写注册界面B的用户名adminB
time.sleep(2)
driver.switch_to.frame("idframe2")    #切换到A页面
driver.find_element_by_id("userA").send_keys(adminB)

time.sleep(3)
driver.quit()

12、多窗口切换

12.1 概念

窗口:类似浏览器的标签页,每个窗口对应一个标签页

为什么要切换窗口? 在html页面中,如果点击按钮或超链接跳转到了新的页面,有的会在新窗口打开页面

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

需求

打开A页面

1、在新的窗口打开新浪页面

2、在新浪页面搜索框输入“新浪搜索”

3、在A页面输入用户名"admin"

12.2 多窗口切换-方法

说明:在selenium中封装了获取当前窗口句柄,获取所有窗口句柄和切换到指定句柄的方法

句柄:英文handle,窗口的唯一识别码

方法:

    1.driver.current_window_handle        获取当前窗口句柄

    2.driver.window_handles        获取所有窗口句柄

    3.driver.swtich_to.window(handle)        切换到指定句柄的窗口  

对案例需求的解决方案:

1、打开A页面,获取A页面的窗口句柄

2、在A页面点击访问新浪网站后,获取所有窗口句柄

3、根据句柄切换到新浪窗口,对输入框输入“新浪搜索”

4、切换回A页面,输入用户名admin

** 代码:**

import time
from selenium import webdriver

driver = webdriver.Edge()
#因为网络问题可能加载不出来页面,定位不到元素,所以设置一个隐式等待10s
driver.imlicitly_wait(10)

#1、打开A页面,获取当前页面窗口句柄
driver.get("A页面.html")
print("当前页面窗口句柄:",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(2)
driver.find_element_by_class("inp-txt").clear()
time.sleep(2)
driver.find_element_by_class("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()

13、窗口截图

13.1 概念

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

为什么要窗口截图:

  • 自动化脚本是由程序去执行的,因此有时打印的错误信息不明确
  • 如果在执行出错的时候,对窗口进行截图保存了,那么就可以直观看出错误原因,定位错误

13.2 方法

说明:selenium中提供了截图方法,只需要调用即可

方法:driver.get_screenshot_as_file(imgpath)

            imagpath:图片路径+名称

代码:

import time
from selenium import webdriver

driver = webdriver.Edge()

#1、打开A页面
driver.get("A页面.html")
driver.find_element_by_id("userA").send_keys("admin")
driver.sleep(2)
#driver.get_screenshot_as_file("./img/123.png") #目录需要提前创建好
#每次都是相同的文件名,会覆盖上一次的截图,因此可以进行优化
#使用时间格式化文件名,可以使截图保存文件名不同,不会覆盖之前保存的文件,更有效
imgpath = "./img/test_{}.png".format(time.strftime("%Y%m%d%H%M%S"))
driver.get_screenshot_as_file(imgpath)
time.sleep(3)
driver.quit()

14、验证码处理

14.1 概念

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

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

14.2 常用方法:

1、去掉验证码(测试环境下采用)

2、设置万能验证码 (生产和测试环境下采用)

3、验证码识别技术(通过python-tesseract来识别图片验证码:识别率很难达到100%)

**4、(推荐方法)记录cookie **(服务器发送的身份信息,通过记录cookie进行跳过登录)

cookie:由web服务器产生,并且保存在浏览器上的小文本文件,它可以包含用户相关的信息

数据格式:键值对组成(Python中的字典)

产生:客户端请求服务器,如果服务器需要记录用户状态,就向客户端颁发一个cookie数据

cookie的使用:当浏览器再次请求该网站时,浏览器把请求的数据和cookie数据一起提交给服务器,服务器检查该cookie,以此辨认用户状态

应用场景:

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

**14.3 Selenium操作cookie **

方法

  • 获取本地所有cookies
  • 获取指定cookie
  • 添加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实现跳过百度的登录

1、手动登录百度,获取cookie

2、请求百度,并且带上cookie

步骤分析

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

1、登录百度,抓取BDUSS

2、添加BDUSS的键值对

3、调用刷新的方法

** 代码**

import time
from selenium import webdriver

driver = webdriver.Edge()
#案例需求:使用cookie实现跳过百度的登录
#1、手动登录百度,获取cookie
#2、请求百度,并且带上cookie

#没有cookie的时候
driver.get("www.baidu.com")
#添加cookie操作
driver.add_cookie("name":"BDUSS","value":"VJWa05pMFI1NnZpaXdlcUhBZmJ-TXdQVmFaVHp5eGtpa1VnYVFEZVhYcHJBdVJtSUFBQUFBJCQAAAAAAQAAAAEAAAAfbSRqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGt1vGZrdbxmZ")
time.sleep(3)
#刷新,再次请求百度首页,验证是否带上身份信息
driver.refresh()

time.sleep(3)
driver.quit()

三、pytest框架

1、总体介绍

  1. 什么是框架:英文framework,为解决一类事情的功能整合
  2. 什么是pytest框架:第三方单元测试框架,一般用于做单元测试(unittest是自带单元测试框架)
  3. 为什么使用pytest:
  • 能够组织多个用例的执行
  • 提供丰富的断言方法
  • 能够生成测试报告

2、安装、卸载与校验

安装:

pip install pytest -i https://pypi.tuna.tsinghua.edu.cn/simple

卸载:

pip uninstall pytest 

校验:

pip list

运行:

命令行运行(推荐)

主函数运行

.表示成功

F表示失败

3、断言

什么是断言?

让程序代替人工判断测试脚本执行结果是否符合预期的结果

为什么要学习断言

  • 自动化脚本一般是无人值守状态
  • 我们不知道执行结果是否符合预期
  • 我们需要让程序代替人工检测执行结果是否符合预期
  • 这就需要用到断言

3.1 断言方法

assert xx 判断xx不为真

assert not xx 判断xx不为真

assert a in b 判断b包含a

assert a==b 判断a=b

assert a!=b 判断a不等于b

def add(x,y):
    return x+y
class TestAssert:
    def test_a(self):
        assert 2 == add(1,1)

    def test_b(self):
        assert add(1,1) == 3

4、setup和teardown

  • 前置setup初始化函数
  • 后置teardown销毁函数
import time

def add(x,y):
    return x+y
class TestAssert:
    # 获取并打印开始时间,每个测试函数执行前会打印一次
    def setup_method(self):
        print("start-time",time.time())
    # 获取并打印结束时间,每个测试函数执行前会打印一次
    def teardown_method(self):
        print("end-time",time.time())

    def test_a(self):
        assert 2 == add(1,1)

    def test_b(self):
        assert add(1,1) == 3

5、配置文件

步骤:

1、项目下新建scripts模块

2、测试脚本存放在scripts模块中

3、项目下新建pytest.ini配置文件

4、配置文件内容时,第一行为[pytest]

5、命令行运行时,会使用配置文件中的配置

** 应用场景**

使用配置文件,可以通过配置项来选择执行目录下的哪些测试模块

编码pytest.ini

[pytest]
adopts = -s
testpaths = ./scripts
python_files = test_*.py
python_classes = Test*
python_functions = test_*

6、测试报告插件

  • 应用场景:自动化测试脚本最终执行是否通过,需要通过测试报告进行体现
  • 安装:pip install pytest-html
  • 使用:在配置文件命令行参数中,增加addopts = -s --html=report/report.html
  • 生成步骤:命令行运行pytest;项目目录会出现report文件夹,里面有个html文件即测试报告

如图所示,即可打开测试报告

7、数据参数化

应用场景:

  • 登录功能都是用户名/密码等输入,点击登录
  • 但是登录等用户名和密码如果想测试多组值时,就要用到数据参数化,好处是使**代码更整洁,可读性更好 **

方法

# 数据参数化,装饰器需要放在需要传多组值的函数上
@pytest.mark.parametrize(argname,argvalues) 
argname:参数名
argvalues:参数值,类型必须为可迭代,一般是一个list列表

单一参数

# 不使用参数化,输出用户名zhangsan和lisi
import pytest

class TestLogin:
    def test_a(self):
        print("zhangsan")

    def test_b(self):
        print("lisi")
# 使用数据参数化(单一参数),修改上述代码
    @pytest.mark.paramtrize("name",["zhangsan","lisi"])
    def test_c(self,name):
        print(name)

多个参数

# 使用数据参数化(单一参数),修改上述代码
import pytest

class TestDemo:
# 需求:使用数据参数化(多个参数),分别打印两组账号和密码:zhangsan/111111和lisi/222222
    @pytest.mark.parametrize(("username", "password"), [("zhangsan", "111111"), ("lisi","222222")])
    def test_demo(self, username, password):
        print(username + "------" + password)
# 使用元组可以传多个值,("zhangsan",111111)
# 使用字典参数化的话,变量名和变量值则更加清晰(推荐方法)
    @pytest.mark.parametrize("dict",[{"username":"zhangsan","password":"111111"},
                                     {"username":"lisi","password":"222222"}])
    def test_demo1(self,dict):
        print(dict)

本文转载自: https://blog.csdn.net/m0_67329659/article/details/140639728
版权归原作者 桃饱网会员啊 所有, 如有侵权,请联系我们删除。

“Web自动化测试入门-(Python+Pytest+selenium的基础用法)”的评论:

还没有评论