核心实验:Selenium WebDriver->其他应用(一)
本节实验主要为大家讲解Selenium WebDriver的另外几个比较常用的对象,它们主要包括:文件上传的操作,下拉框的使用,浏览器基本操作,对测试过程进行截图,在浏览器当前页面直接运行JavaScript脚本,等待时间等。
实 验 简 介
本节实验主要为大家讲解Selenium WebDriver的另外几个比较常用的对象,它们主要包括:文件上传的操作,下拉框的使用,浏览器基本操作,对测试过程进行截图,在浏览器当前页面直接运行JavaScript脚本,等待时间等。
实 验 目 的
(1)掌握在WebDriver中通过GUI进行文件上传的操作。
(2)掌握在WebDriver中对下拉框的使用。
(3)掌握在WebDriver中对浏览器的基本操作。
(4)掌握在WebDriver中如何对测试现场进行截图保存。
(5)掌握在WebDriver中直接运行JavaScript脚本。
(6)掌握在WebDriver中如何灵活使用等待时间。
实 验 流 程
1.等待时间
大家在运行脚本时,往往会出现一个问题:页面元素找不到,导致最后用例失败,这并不是用例逻辑上的错误,而是脚本不稳定所致。面对此类问题,我们首先要观察页面加载和代码运行情况,很多元素找不到的异常是发生在页面还未加载完成时代码已经开始在查找页面元素。解决此类问题只需要设置等待时间。以下是常用的三种方法,各自有其不同的应用场景。
sleep()
强制等待,设置固定休眠时间,以秒为单位。Python 的time 模块提供了休眠方法sleep() ,导入time 包后就可以使用sleep()进行脚本的执行过程进行休眠。这种等待方式是最简单,最直接的使用,但这种方式也有其局限性:
(1)受网络和硬件环境不同而导致的等待时间不够。
由于webdriver脚本的可移植性,很多时候代码会拿到其他机器 或网络环境上运行。这就会遇到页面加载时间的不一致。也许在代码编写人员那页面加载只需要1秒,而其他环境需要2秒或更长。那么,如何设置sleep()的时间呢将是编码人员的困惑。如果没次等待加载超过3秒。将直接影响自动化执行效率。
(2)有些提示信息没有固定的出现和消失时间。
在很多web系统中,都会出现一些用户异常操作的提示信息,如图所示。
这种提示信息一般会在一个很短的时间内就自动消失。起到提示用户有操作问题的作用。如果想要通过webdriver来定位该元素,比如得到“请输入名称”,用time.sleep(2)的方式就可能获取不到。
implicitly_wait()
隐式等待,是webdirver 提供的一个超时等待。相当于设置全局的等待,在定位元素时,对所有元素设置超时时间。
… #设置全局等待时间,在超时30秒内每隔一段时间去查找元素,直到30秒超时 driver.implicitly_wait(30) … |
隐式等待也有不是万能的,它也会有一些问题。如图所示。
这是一个提示信息。次信息可以通过id=’msg’定位。而且在页面加载完成就可以定位。如果用户做了页面操作比如新增、删除和修改后,该信息就会发生变化,如图所示。
对比提示信息源代码,可以发现,页面元素id没有发生变化,变化的仅仅是标签中的文本内容。如果代码只使用隐式等待。
from selenium import webdriver import time driver = webdriver.Firefox(firefox_binary=r"C:\Program Files (x86)\Mozilla Firefox\firefox.exe") … driver.implicitly_wait(20) … message = driver.find_elemnet_by_id(‘msg’).text #获取页面提示信息内容 if ‘成功啦:新增数据成功’in message: #判断内容是否是新增成功 print(‘新增成功’) print(message) |
运行上面的代码,message的结果是“操作信息在此查看”,为什么会这样呢?其实,由于该元素本来就存在,新增成功的信息需要等待1到2秒的时间才会出现。所以,隐式等待就不能解决这个问题。当遇到这个情况的时候可以在隐式等待的同时加上前面的强制等待。
… time.sleep(2) message = driver.find_elemnet_by_id(‘msg’).text #获取页面提示信息内容 if ‘成功啦:新增数据成功’in message: #判断内容是否是新增成功 print(‘新增成功’) print(message) |
再次执行代码,message的值就是我们想要得到的新增成功的内容了。
WebDriverWait()
显式等待,同样也是webdirver 提供的方法。在设置时间内,默认每隔一段时间检测一次当前页面元素是否存在,如果超过设置时间检测不到则抛出异常。用法如下。
WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
driver - WebDriver 的驱动程序(Ie, Firefox, Chrome 或远程)
timeout - 最长超时时间,默认以秒为单位
poll_frequency - 休眠时间的间隔(步长)时间,默认为0.5 秒
ignored_exceptions - 超时后的异常信息,默认情况下抛NoSuchElementException 异常。如图所示。
from selenium.webdriver.support.ui import WebDriverWait from selenium import webdriver
driver = webdriver.Firefox(firefox_binary=r"C:\Program Files (x86)\Mozilla Firefox\firefox.exe") …
ele = WebDriverWait(diver,5,0.5).until(lambda driver:driver.find_element_by_ xpath('//div[@id='gritter-item-2']/div[2]/div[2]/h5')) if str == ‘请输入名称’: print(‘必填项标题未填写’) … |
对于显示等待,我们可以看成是针对某个具体元素的隐式等待。可以用来判断某个具体的元素是否出现,并返回该元素以供后面操作。
2.文件上传
在WebDriver的测试中,除了使用正常的协议操作外,我们也同样可以进行基于界面的文件上传。但是这里有一个关键问题,当我们上传文件时,系统都会弹出一个对话框让我们选择要上传的文件。
事实上,该窗口是一个操作系统级对话窗口,Selenium WebDriver本身是无法识别到里面的元素的。所以我们在进行文件上传时,不应该去打开这个窗口,而是直接对“文件上传”的类文本框进行写操作,将文件路径直接写入到该文本框中即可。在蜗牛进销存中也有文件上传模块,如图5-19所示。
要实现这种input标签的文件上传,方式有很多,其中,用webdriver的send_keys()方法就可以实现代码如下:
from selenium import webdriver wd = webdriver.Firefox(firefox_binary=r"C:\Program Files (x86)\Mozilla Firefox\firefox.exe") wd.find_element_by_id('username').send_keys('admin') |
这里需要注意的是,文件url不要使用‘/’,必须使用‘\\’的方式才能成功。这是最常见的上传文件的方式。
利用pyHook包中的的pykeyboard模块下的PyKeyboard类来实现模拟键盘输入,当然,需要先下载pyHook和PyUserInput两个第三方库,具体安装可以通过pip install的方式直接实现。文件上传实现代码如下:
from selenium import webdriver from pykeyboard import PyKeyboard wd = webdriver.Firefox(firefox_binary=r"C:\Program Files (x86)\Mozilla Firefox\firefox.exe") wd.find_element_by_id('username').send_keys('admin') wd.find_element_by_id('batchfile').click() #点击上传按钮,打开文件上传窗口 |
这里需要注意的是,k.type_string()方法不接受中文,所以我们需要把上传文件名改成字母和数字的形式。其实现原理,就是利用webdriver打开文件上传后,其输入的光标在文件名的输入框内的特性。
(1).使用前面所学的SikuliX的jar包来操作。代码如下:
import jpype import os … #省略中间webdriver操作页面的过程 #调用java虚拟机,实现文件上传功能
jarpath = 'G:/SikuliX/SikuliX/SikuliX/' wd.find_element_by_xpath('//input[@onclick="uploadBatchFile()"]').click() |