浅谈自动化测试2——selenium库中的常用函数

1、元素查找

1.1 什么是元素查找?

什么是元素查找:查找前端页面的元素/标签。譬如:找到一个输入框、找到一个按钮、找到一个导航栏、找到一个标签页...,就叫做元素的定位。

2、元素定位

2.1 元素定位涉及的函数

selenium 库中查找元素的函数主要有2个函数,分别是:

(1)、findElement() :查找一个符合条件的元素。

使用 findElement() 函数时,需要注意:页面符合条件的元素必须是唯一的,如果不是唯一的,代码不一定会报错,但是我们要查找的元素一定是不符合预期的。

例如:

(2)、findElements() :查找所有符合条件的元素

查找完元素可以通过多种方式去定位元素,常用的主要有以下2函数,分别是:

(3)、By.xpath(String a) :路径语言,通过路径语言选中页面中指定的标签元素。

(4)、By.cssSelector(String b) :选择器,通过选择器选中页面中指定的标签元素。

操作步骤:

1)、任找一个网页,以百度网页为例:

#su是通过选择器的方式对百度一下按钮复制下来的选择器元素。

2.2 cssSelector的语法(重点)

#hotsearch-content-wrapper > li:nth-child(1) > a > span.title-content-title:

(需要能做到不仅仅是会复制 ,还需要做到能够看懂我们复制下来的选择器标签,因为我们可能需要去手动修改该选择器标签(因为前端代码标签的id属性值集有一些会发生改变,比如上一次我们复制div标签的id值是a值,页面刷新后,该div标签的id值是b值,这种叫做动态元素,此时怎么复制,所需的元素都定位不到),会根据给出的复杂选择器标签层层找到最终要求的标签元素/前端代码)

2.3 xpath的语法(重点)

//*@id="hotsearch-content-wrapper"/li1/a/span2

2.4 点击/提交对象

click() :例如该场景:找到百度一下按钮后,点击该按钮(点击使用到的是 click() 函数)

页面上大多数元素/标签都可以点击,但是也有一些特殊元素不能点击:(1)、页面隐藏的,不可见的标签的无法点击

通过F12打开开发者工具,点击选择按钮去选择页面中所有可以被蓝色蒙尘覆盖点击的元素,都能找到其代码;但点击某段代码,不一定能在页面上找到对应的元素,如下图所示:

1)、可以从页面元素上定位到代码(大部分情况下是可以的,但部分情况下根据页面元素去找代码,定位到的代码也不准确,存在元素被遮挡的问题):

2)、通过前端代码不一定能定位到页面元素(代码虽存在,但页面上没有对应的元素,说明该代码对应的标签有可能是个隐藏标签):

2.5.1 元素定位时自动化测试常见的异常

这些不确定性将会导致元素定位时自动化测试常出现如下常见异常:

2.5.1.1 ElementNotInteractableException

元素不可交互异常,即页面元素不可点击

2.5.1.2 NoSuchElementException

元素找不到异常

通常出现该异常的原因有:

2.1)、查找元素时元素复制错误(元素复制时复制到其他元素的代码或元素复制正确地方但粘贴时元素粘贴出错)

2.2)、方法使用错误(1、元素定位时使用xpath(),代码里却用了cssSelector(),或者反之)

2.3)、复制到的这个元素是个动态元素(动态元素就会导致上一秒复制到的代码id为A,页面刷新后id值变为了B)

2.5 模拟按键输入

sendKeys() :该函数可模拟人手工敲打键盘在输入框中输入对应内容

2.6 清除文本内容

clear() :可用于清除已输入的内容

2.7 获取对应的文本信息

getText() :可获取到元素的文本信息(需要区分文本和属性,getTextz()无法获取属性值,获取属性值需要使用getAttribute(String)函数)

2.8 获取当前页面标题

getTitle() :获取当前页面标题

2.9 获取当前页面URL

getCurrentURL():获取当前页面URL

3、窗口

场景:进入百度一下页面,点击"图片"选项,页面打开了一个新标签页,新弹窗,此时想要通过getTitle()、getCurrentURL()获取新标签页的标题、URL时,会发现获取到的还是旧标签页的,实际结果与我们的预期结果不一致

但是当我们通过sendKeys()函数去输入某关键字后点击百度一下按钮,新页面没有另开新标签页,而是在当前标签页,此时通过getTitle()、getCurrentURL()函数去获取新标签页的标题、URL,我们会发现,获取到的是新的标题、URL

出现上述问题的原因是,每个标签页都有自己的窗口句柄。

对当前页面操作,若新打开了一个标签页面,想去获取新标签页的标题和URL,大概率只能够获取到旧标签页的标题和URL;对当前页面操作,未打开新标签页,仍在原标签页的基础上显示搜索结果,那么此时,去获取新标签页的标题和URL,能够获取到新的标题和URL。这是因为每个标签页都有自己的窗口句柄

当我们进行手工测试时,可以简单的通过眼睛来判断当前标签页是哪个窗口,当前窗口是什么,但是对于程序来说,程序不知道当前最新窗口是哪个。那么程序就可以通过每个浏览器窗口都有一个唯一的属性句柄(handle)来识别每一个窗口。

3.1 获取当前页面句柄

driver.getWindowHandle()

3.2 获取所以页面句柄

driver.getWindowHandles()

3.3 切换窗口(切换标签页)

switchTo.window(句柄) :告诉程序,当前需要切换窗口,即:若对当前页面进行操作,打开了一个新标签页,此时想去获取新标签页的标题、URL,就可以通过该函数,让程序知道,当前应不再与旧标签页对话,应与新标签页对话。

但是可能常会有以下场景需求出现:

当我们打开多个(10个以上)标签页时,该怎么去切换每个标签页的窗口句柄呢?

难道我们需要每打开一个新标签页,就去获取所有的句柄,然后通过与当前句柄比较取非当前句柄的方式去让程序切换标签页吗?这样做也是可行的,但在代码中将会做大量的重复性代码,也很麻烦。

此时我们可以通过较为简单的方式:

1)、driver.get(url)

2)、一般情况下,自动化测试不会存在需要打开多个标签页的情况

3.4 窗口的大小设置

driver.manage().window().maximize():窗口最大化

driver.manage().window().minimize():窗口最小化

driver.manage().window().fullscreen():全屏窗口

driver.manage().window().setSize(new Dimension(1024,768)) :自定义设置窗口大小

3.5 屏幕截图(很必要的功能)

一般来说,自动化脚本将部署在机器上自动的定时去运行,程序员不可能时时刻刻盯着这个自动化运行,那么如果自动化脚本出现了报错,可以通过抓拍来记录当时的错误场景:

1)、即:可能通过日志,没办法定位到具体是什么报错,那么此时就可以通过查看当时的抓拍:即页面的运行表现是什么,迅速定位到具体是什么报错。

2)、在测试过程中,测试截图也是非常必要的,有时候是甲方验收的材料组成之一,有时候是测试留痕的必备材料。

屏幕截图方法需要额外导入包(即下述依赖):

java 复制代码
<dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

getScreenShotAs() :通过这个函数可以将抓拍到的页面转成文件的形式,还需要借助FileUtils这个工具类将文件转成图片文件,由于FileUtils这个工具类,屏幕截图需要去导入依赖。

上述图片中,确实截图了driver作用在当前标签页的图片,但是如果切换了标签页,截图下来的新图片将会覆盖掉旧图片,这是因为我们在生成图片文件时,写死了图片文件名称。

因此由于我们在测试过程中,需要对很多页面很多场景进行截图(我们上百条测试用例,可能每条),所以可以通过:更改图片文件的名称,保证每一次保存的图片名称都是唯一的,就可以确保旧截图不会被新截图覆盖掉。使用时间戳来命名图片文件,图片文件名称就不会重复。

现在自动化测试每执行一次,都能够获取到新截图,同时旧截图仍然保存着不会被覆盖,那么,我们能不能把这些抓拍到的截图分类成文件夹存储起来,以便想要查看的时候更好的翻找到?

比如说:今天是12月1号,那么12月1号自动化测试运行抓拍到的所有图片文件都存储在A文件夹里,12月2号自动化测试运行抓拍到的所有图片文件都存储在B文件夹里,依次类推...

3.6 关闭窗口

driver.close():关闭窗口。就像资源用完后需要关闭,否则一直开启却不关闭,造成资源浪费内存不足。

注意:

1)、 driver 默认作用于第一个标签页

2)、窗口关闭后driver 需要重新定义,即driver需要切换(注意:close()存在这个坑),如果没有切换driver,继续用当前这个已经被closed的driver操作,自动化测试脚本报错。

driver.quit()和 driver.close()的区别?

1)、当浏览器打开多标签页时,driver.close()是仅关闭当前作用的窗口;driver.quit()是关闭整个浏览器,释放driver对象。

2)、当浏览器打开的是单页面时,driver.close()和driver.quit()都是直接关闭整个浏览器。

4、等待

等待:代码执行的速度比页面渲染的速度要快,有时候往往代码已经执行了但是页面元素还没加载好,这就导致出现了自动化测试报错。

在进行自动化测试时,常出现一个问题:页面上有这个元素,代码中也有这个元素对应的前端代码,但是程序在执行的时候出现报错:NoSuchElementException,程序提示:找不到这个元素

4.1 自动化测试时产生NoSuchElementException异常的原因

1)、元素复制错误(复制元素时复制成别的元素了 、 复制元素时复制正确但粘贴时出现漏粘多粘等问题)

2)、复制时方法使用错误(使用xpath()方法复制,却选择用选择器去粘贴;使用cssSelector()方法复制,却选择用xpath去粘贴)

3)、代码未设置登录态,导致自动化打开的页面与手工测试打开页面不一致,得到的测试结果也会不一致

4)、动态元素

5)、代码执行的速度比页面加载的速度要快

4.2 等待---由于代码执行速度与页面渲染速度不匹配导致自动化报错引入的解决方案

4.2.1 强制等待

通过 Thread.sleep() 强制等待来解决(叫做强制等待是因为,当程序执行到这一行代码的时候,线程强制阻塞在当前,直到等待时间结束)

优点:使用简单,调试的时候较为有效

缺点:影响运行效率,浪费大量时间(如果自动化时需要执行的用例(=方法)有300个,每个方法都需要等待6s,用时共计3分8秒,再加上其他代码执行需要等待的时间估计为2分,那么这次自动化执行时300个用例+其他代码执行所需的时间 = 5分8秒,一次自动化测试执行所需的时间有点长了,所以说使用强制等待将会较影响运行效率,浪费大量时间)

4.2.2 智能等待

智能等待分为2种,一种是隐式等待,一种是明式等待。

4.2.2.1 隐式等待 implycitlyWait()

implycitlyWait():参数是Duration类中提供的毫秒、秒、分钟等方法

2.1.1)隐式等待是一种智能等待,它可以规定在查找元素时,在指定时间内不断查找元素,如果找到则代码继续执行,超时没找到元素程序才会报错退出

2.1.2)隐式等待的作用域是整个脚本的所有元素。即:隐式等待作用在整个页面的所有元素上,它会等待页面上的所有元素加载成功。即:只要driver对象没有被释放(driver.quit())掉,隐式等待就一直生效

局限性:隐式等待无法等待非页面元素(像页面的标题、URL、前进、后退、刷新等操作,并不在页面上,还有弹窗,所以隐式等待对他们不起作用)

4.2.2.2 显示等待 new WebDriverWait()

new WebDriverWait() ,参数有:WebDriver driver,Duration类里的函数秒、毫秒、分钟...,until($express),注意 :until函数里的表达式,是用了ExpectedConditions类里的方法

ExpectedConditions 预定义方法的一些示例:

elementToBeClickable(By locator)--- 用于检查元素,期望是可见的的并已启用的,以便可以单击它

textToBe(Bylocator,String str) --- 用于检查元素

presenceOfElementLocated(Bylocator)用于检查页面的 DOM 上是否存在元素

urlToBe(java.lang.String url) 检查当前页面的 URL 是一个特定的 URL

显示等待也是一种智能等待,在指定超时时间范围内,只要满足操作的条件就会继续执行后续代码。

优点:

2.2.1)、显示等待可以弥补隐式等待的缺陷,它可以等待非页面元素,作用全局(如:页面标题、页面URL、弹窗、前进、后退、刷新等)

2.2.2)、显示等待的运行效率优于隐式等待。隐式等待不管页面上这个元素是加载得快还是加载得慢,都是等待页面上所有得元素都加载成功。而显示等待,它想作用在哪个元素上面,他就作用在哪个元素上面。比如说页面其他元素都加载得很快,1~2s加载完毕,但有个加载得很慢的A元素,这时显示等待就可以只作用在这个加载得很慢的元素上。

4.3 隐式等待和显示等待混合使用

隐式等待和显示等待的用法略有差异,因此在程序方法执行过程中,衍生出了一种场景:是否隐式等待和显示等待可以在代码中混合使用呢?

下述为在testDemo4()方法中将隐式等待和显示等待混合使用,隐式等待等待时间设置为1min,显示等待等待时间同样设置为1min,期望程序执行后总等待时间为2min:

但实际程序执行结果:如图可知,总等待时间为1min,与预期结果不符。

因此,我们自动化脚本里,不要混合使用隐式等待和显示等待去查找页面元素,将会出现不符合预期的执行结果。可以将它们配合进行使用,如:可使用隐式等待查找页面元素,显示等待查找弹窗、非页面元素。

5、浏览器导航

浏览器的这部分称为:导航栏

在导航栏我们可以进行:输入URL、前进、后退、刷新...等操作,这些操作都是页面上无法定位到的。

5.1 打开浏览器

1)、driver.navigate.to(String s)

2)、driver.get(String s)

5.2 浏览器的前进、后退、刷新功能

1)、driver.navigate.back()

2)、driver.navigate.forward()

3)、driver.navigate.refresh()

6、弹窗

弹窗在页面是找不到任何元素的,打开开发者工具页面,点击没有蒙尘覆盖,找不到任何元素,这种情况怎么定位到页面元素??可使用 Selenium 提供的 Alert 接口。

弹窗的主要操作有:确认(alert.accept())、取消(alert.dismiss())、输入文本信息(alert.sendKeys()),获取文本信息(alert.getText())。

6.1 警告弹窗

如下图所示,警告弹窗会显示一个按钮,这个按钮有可能是确认按钮,有可能是取消按钮。

6.2 确认弹窗

如下图所示,确认弹窗会显示2个按钮,一个是可操作的确认/确定按钮、另一个是可操作的取消按钮

6.3 提示弹窗

如下图所示,确认弹窗会显示2个按钮1个输入框,一个是可操作的确认/确定按钮、另一个是可操作的取消按钮,还有一个可操作的输入框

6.4 弹窗出现后必须处理,不处理无法执行下一步

如下图所示,弹窗被调起后,未进行·任何处理,直接去操作页面其他元素,程序执行报错:unexpected alert open(不被期待的弹窗被打开了) / UnhandledAlertException(未操作弹窗异常)

7、文件上传

点击文件上传的场景下会弹窗系统窗口,让用户进行文件选择。

Selenium 无法识别非 Web 的控件,上传文件窗口为系统自带,因此无法识别上传文件窗口元素。

但可以使用sendKeys()来上传指定路径的文件,可达到一样的效果。

8、浏览器参数设置

8.1 设置无头模式

无头模式(options.addArguments("-headless"))的意思:前端看不到一系列操作动作,但是后端已经在执行了。

默认情况下默认为有头模式,就像我们在执行自动化脚本的时候,在电脑上可以看到代码里的每一步在屏幕前执行,如此时正在输入账密,此时正在点击登录按钮,此时正在上传文件...等操作。

实际工作中,自动化在编写完成交付之后,每次执行的时候不会真的安排人工一直肉眼盯着自动化的执行效果,一般自动化测试在实际运行中设置的浏览器参数都是无头模式,如果真的想要查看自动化测试脚本的执行效果,可以通过日志、程序执行结果、调试、屏幕抓拍...

8.2 设置浏览器的加载策略

options.setPageLoadStrategy(PageLoadStrategy.NONE):可通过该函数来设置浏览器的加载策略

PageLoadStrategy 类的返回类型是一个枚举,主要有3个值:NONE、EAGER、NORMAL

NONE:完全不阻塞WebDriver

EAGER:DOM访问准备就绪即可,其他资源还在加载(如图像、样式...)

NORMAL:浏览器加载策略的默认值,等待浏览器所有资源加载完成

若页面资源比较多,通过 driver.get() 方法去请求页面需要请求很长时间,这时候就会存在这样的要求:期望页面主要框架加载完毕就继续往下执行,而不是等待所有的资源加载完成。

这时候就可以通过 设置页面的加载策略 来完成上述需求的落地。

相关推荐
蒲公英内测分发8 小时前
AI 玩具 App 每周更新,怎么用 CI/CD 自动上传测试包又避免误发?
人工智能·测试工具·智能硬件·web app
泷泷_9 小时前
CISP-PTE实操题(自写靶场与题类似或变型)
php·文件上传·cisp-pte·cisp·文件包含·sql注入
程序员小远9 小时前
接口测试知识总结
自动化测试·软件测试·python·测试工具·职场和发展·测试用例·接口测试
测试秃头怪10 小时前
Postman中变量的使用
自动化测试·软件测试·python·测试工具·测试用例·接口测试·postman
破土士V1 天前
【软件测试】自动化测试
自动化测试·selenium·web自动化测试·ui自动化
ClouGence1 天前
告别低效脚本!8款更省事的 Selenium 替代工具推荐
selenium·测试
zhonyu鱼1 天前
Wireshark:开源免费的抓包工具,网络故障排查与安全分析利器
测试工具·安全·wireshark