失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 【软件测试】总结web自动化测试-selenium+python

【软件测试】总结web自动化测试-selenium+python

时间:2019-07-03 13:38:43

相关推荐

【软件测试】总结web自动化测试-selenium+python

自动化测试指软件测试的自动化,在预设状态下运行应用程序或者系统,预设条件包括正常和异常,最后评估运行结果。将人为驱动的测试行为转化为机器执行的过程。

常见的自动化测试工具:QTP、selenium、Rational Robot 、jmeter、appium、soapui、Loadrunner等等

selenium 是一个web 的自动化测试工具,不少学习功能自动化的同学开始首选selenium , 相因为它相比QTP 有诸多有点:

多平台:windows、linux、MAC 。支持多浏览器:ie、Firefox、safari、opera、chrome。支持分布式测试用例的执行,可以把测试用例分布到不同的测试机器执行,相当于分发机的功能

文章目录

一、使用selenium IDE录制测试脚本二、Python+selenium 环境搭建1、Python+selenium2、webdriver三、selenium下,webdriver的常用API1、定位元素1)、id 和name2)、tag name 和 class name3)、CSS_selector 定位4)、Xpath定位5)、link text6)、partial link text2、操作测试对象3、添加等待4、打印信息5、浏览器的相关操作6、键盘事件7、鼠标事件8、多层框架和窗口定位9、上传文件四、unittest框架1、批量执行测试用例2、unittest断言3、HTML测试报告4、数据驱动

一、使用selenium IDE录制测试脚本

selenium IDE,可以安装到浏览器的插件上,Microsoft Edge浏览器中,可以不用翻墙,就能安装IDE,而像Chrome浏览器,好像要翻出去才能安装。这里就不细说Chrome怎么装了,以下是Edge浏览器的安装流程。

打开Edge浏览器的扩展

打开Edge的插件商店

安装插件

安装成功后,在“地址栏”的右边就会出现图标,又或者点击扩展就能看到。

录制脚本过程如下

打开IDE后,点击第一行蓝色字体;

输入工程名

输入被测试的网址

点击 “START RECORDING”后,会打开浏览器,并且进入到被测试的网站里

进入测试操作,比如输入“彭于晏”。然后鼠标点击IDE的停止按钮,脚本就录制好了。

输入这次测试的名称

运行录制的脚本

导出录制的脚本

以上就是用selenium IDE,进行录制脚本,并且将录制的脚本转换为编程语言,例如Python。

二、Python+selenium 环境搭建

1、Python+selenium

我自己安装的Python3.10版本,编译环境用的是pycharm。

在安装Python解释器的时候,直接用默认安装路径即可,如下,是我的安装路径:

pycharm的配置

然后安装selenium包

上诉是在pycharm上安装selenium包,有的人可能安装不上,那么可以试试在cmd命令行窗口试试这条命令:

pip install selenium // 用于安装seleniumpip show selenium //用于查看是否已经安装selenium

安装好后,就是这样的

2、webdriver

selenium安装好之后,就只差一个浏览器驱动了。不同的浏览器,不同的版本,驱动是不一样的。Chrome浏览器,国内有镜像源

可以在这里找到Chrome的驱动。Edge浏览器,好像不用翻墙也能够下载到。

在下载驱动的时候,驱动的版本号要和浏览器的版本号对应上,有可能你安装的浏览器的版本号,找不到相应的驱动。安装临近的驱动版本号也是可以的。如图:

将下载好的驱动,解压到Python解释器的安装路径下(Script文件夹),如下:

至此,环境就搭建好了。

三、selenium下,webdriver的常用API

在讲解API时,我们首先要知道selenium需要导包的,如下:

from selenium import webdriver# webdriver 就是浏览器的驱动,用这个驱动,能完成很多浏览器的操作driver = webdriver.Edge() # 获取Edge浏览器的驱动driver.get("/") # 让浏览器打开百度搜索

1、定位元素

在打开百度搜索之后,我们需要定位到“搜索框”,然后才能进行输入。那么如何定位到搜索框呢?我们有以下几种方法:

1)、id 和name

id 和name 是我们最最常用的定位方式,因为大多数控件都有这两个属性,而且在对控件的id 和name 命名时一般使其有意义也会取不同的名字。通过这两个属性使我们找一个页面上的属性变得相当容易。

在浏览器中,打开开发者工具(按F12)。就能查看到页面的每一个元素的前端代码。

# 在上文中,已经打开获得浏览器驱动的情况下,输入以下代码就能定位元素driver.find_element_by_id("kw") # 通过id定位driver.find_element_by_name("wd") # 通过name定位

2)、tag name 和 class name

看上图,知道搜索框的标签是“input”,并且class=“s_ipt”。那么我们也可以通过这两个属性进行定位。但是需要知道的是,使用tag name 进行定位,可能得到的不止一个标签的数据。所以在使用的时候,需要注意页面共有多少个相同的标签。

driver.find_element_by_tag_name("input") # 得到所有的input标签driver.find_element_by_class_name("s_ipt") # 得到class="s_ipt"的元素

3)、CSS_selector 定位

driver.find_element_by_css_selector("#kw") # 通过Css_selector定位

4)、Xpath定位

上图两个都行

driver.find_element_by_xpath("//*[@id="kw"]") # 通过xpath进行定位

5)、link text

有的时候,页面不是搜索框之类的,而是一条链接,也就是HTML中的a标签,此时就可以link text进行定位,值得注意的是,这种定位,输入的参数,也就是这条链接的名称,在当前页面只能是唯一的。只有这样,才能通过link进行定位。

driver.find_element_by_link_text("新闻").click() # 通过link text进行定位,并且点击

6)、partial link text

根据名称都知道,这就是link text的模糊查询。如下:

driver.find_element_by_partial_link_text("闻").click() # 通过partial_link text进行定位,并且点击

只通过一个“闻“字,就能够定位到”新闻“.

2、操作测试对象

前面讲了很多的定位元素的操作,那么定位到元素之后,又有如下这些操作;

click() 点击操作send_keys() 输入参数clear() 清空当前输入框submit() 提交表单text 没有括号,这里的获取元素的文本信息

from selenium import webdriverimport timedriver = webdriver.Edge()driver.get("/")driver.find_element_by_id("kw").send_keys("彭于晏") # 搜索框 输入彭于晏driver.find_element_by_id("su").click() # 点击 百度一下time.sleep(2) # 停留2秒driver.find_element_by_id("kw").clear() # 清空搜索框的内容driver.find_element_by_id("kw").send_keys("胡歌") # 搜索框输入胡歌driver.find_element_by_id("su").click() # 点击 百度一下time.sleep(2)driver.quit() # 关闭浏览器

以上就是一份完整的代码,先是搜索了彭于晏,然后清空输入框,再搜索胡歌。

3、添加等待

在上面的代码中,可能你已经看到了time.sleep(),这就是等待。这个time,是需要导入time包的。除了这个,还有一个等待的函数

driver.implicitly_wait(5) # 智能等待

括号里面填的是最长等待时间,单位秒。

这个方法呢,可以在这样的场景下使用:

在搜索出结果后,需要点击百度百科,查看详细信息。因为在点击搜索彭于晏的时候,浏览器需要向后台发送请求,只能后台给出回应之后,才能看到这“百度百科”这几个字,这个时候才能点击。所以在点击百度百科的时候,是需要等待后台响应的,这段时间,人们是不能把控的,就可以通过智能等待,这个函数。

上诉代码的意思就是,在5秒之内,“百度百科”这几个字出来之后,就直接点击了。不需要傻傻的等待5秒。那么如果5秒后,还没点击的haul,就会报出异常。

from selenium import webdriverimport timedriver = webdriver.Edge()driver.get("/")driver.find_element_by_id("kw").send_keys("彭于晏") # 搜索框 输入彭于晏driver.find_element_by_id("su").click() # 点击 百度一下driver.implicitly_wait(5) # 智能等待driver.find_element_by_link_text("百度百科").click() # 点击 百度百科,查看详情time.sleep(2)driver.quit()

4、打印信息

可能通过一些函数,查看当前网页的URL和title的信息,如下

from selenium import webdriverimport timedriver = webdriver.Edge()driver.get("/")print(driver.title) # 打印titleprint(driver.current_url) # 打印URLdriver.quit()

5、浏览器的相关操作

浏览器窗口的最大化和最小化:

driver.maximize_window() # 最大化driver.minimize_window() # 最小化

除了最大化最小化,我们还可以手动的设置窗口的长宽。

driver.set_window_size(480, 800) # 长480,宽800

浏览器的后退和前进,也就是浏览器左上角的两个箭头。

driver.back() # 后退driver.forward() # 前进

控制网页的滚动条。python是做不到这个操作的,只能通过javaScript的语句,来达到。

js = "var q=document.documentElement.scrollTop=10000" # 这里设置为10000,表示滚动条拉到最下面driver.execute_script(js) # 执行上面的JavaScript语句

scrollTop 设置为10000,表示滚动条拉到最下面。相反的,设置为0,就表示将滚动条拉到最上面。execute_script(script, *args),在当前窗口/框架同步执行javaScript 。

6、键盘事件

在有些场景,我们是需要使用键盘的,我们也是可以通过驱动,来按动键盘,也可以使用组合键,比如Ctrl + C等等。

# 首先是需要进行导包的from mon.keys import Keys# 通过send_Keys(),来按键send_Keys(Keys.TAB) # tab键send_Keys(Keys.ENTER) # 回车键# 组合键的用法send_Keys(Keys.CONTROL, 'a') # Ctrl + asend_Keys(Keys.CONTROL, 'c') # Ctrl + c

# 举个例子# 搜索框先搜索彭于晏,然后Ctrl+x,剪切彭于晏。再重新输入胡歌进行搜索# 键盘事件from selenium import webdriverfrom mon.keys import Keys # 需要导入keys包import timedriver = webdriver.Edge()driver.get("/")driver.find_element_by_id("kw").send_keys("彭于晏")driver.find_element_by_id("su").submit()time.sleep(2)# 键盘的组合键# 将上诉输入的内容进行剪切,然后重新输入新的内容# 首先还是需要先定位到元素driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'a')driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'x')time.sleep(3)# 重新输入新的数据driver.find_element_by_id("kw").send_keys("胡歌")driver.find_element_by_id("kw").send_keys(Keys.ENTER)time.sleep(3)driver.quit()

7、鼠标事件

还是一样的,需要使用到鼠标,首先还是需要先进行导包

from mon.action_chains import ActionChains

这个类里面有以下几种操作:

context_click() 右击double_click() 双击drag_and_drop() 拖动move_to_element() 移动

from selenium import webdriverfrom mon.action_chains import ActionChainsimport timedriver = webdriver.Edge()driver.get("/")driver.find_element_by_id("kw").send_keys("胡歌")p = driver.find_element_by_id("su") # 定位到 百度一下按钮ActionChains(driver).double_click(p).perform() # 双击百度一下按钮time.sleep(6)driver.quit()

ActionChains(driver), 生成用户行为。所有的行为都存储在ActionChains对象里面,通过perform()存储的行为。

double_click§,双击p所指向的元素。

perform(),执行所有存储的行为。

8、多层框架和窗口定位

多层框架或窗口的定位:

switch_to_frame()switch_to_window()

对于一个现代的web 应用,经常会出现框架(frame) 或窗口(window)的应用,这也就给我们的定位带来了一个难题。有时候我们定位一个元素,定位器没有问题,但一直定位不了,这时候就要检查这个元素是否在一个frame 中,seelnium webdriver 提供了一个switch_to_frame 方法,可以很轻松的来解决这个问题。switch_to_frame(name_or_id_or_frame_element):可以简单记忆一下,如果这个frame有name和id属性那么就用这两个属性就好,如果没有的话可以先用find_element_by_xxx方法找到这个frame元素,然后把这个元素传进去,这也是可行的。switch_to_frame()把当前定位的主体切换了frame里。怎么理解这句话呢?我们可以从frame的实质去理解。

frame中实际上是嵌入了另一个页面,而webdriver每次只能在一个页面识别,因此才需要用switch_to_frame方法去获取frame中嵌入的页面,对那个页面里的元素进行定位。

switch_to_default_content() :从frame中嵌入的页面中跳出,跳回到最外面的原始页面中。

还有可能嵌套的不是框架,而是窗口,还有针对窗口的方法:switch_to_window(),用法与switch_to_frame ()相同:

driver.switch_to_window(“windowName”)

9、上传文件

上传文件也是比较常见的操作,比如在gitee上,重新上传自己账户的头像之类的,都是上传文件的操作。

其实思路还是跟上面介绍的操作一样的,首先还是需要先定位到上传按钮,然后直接send_Keys(),括号里面输入的就是图片的绝对地址

# 首先定位到上传按钮driver.find_element_by_link_text("上传").send_Keys(图片的路径)

四、unittest框架

1、批量执行测试用例

在上文,我们在写代码时,都是一个测试用例,就要写一个.py的源文件,而unittest框架,就能够使其简化,这个框架可以将一个测试用例,写成一个函数就行,我们只需要框架,这样就能一次性跑完所有的代码了。unittest 单元测试提供了创建测试用例,测试套件以及批量执行的方案, unittest 在安装pyhton 以后就直接自带了,直接import unittest 就可以使用

作为单元测试的框架, unittest 也是可以对程序最小模块的一种敏捷化的测试。在自动化测试中,我们虽然不需要做白盒测试,但是必须需要知道所使用语言的单元测试框架。利用单元测试框架,创建一个类,该类继承unittest的TestCase,这样可以把每个case看成是一个最小的单元, 由测试容器组织起来,到时候直接执行,同时引入测试报告。

import unittest # 导包class Test(unittest.TestCase):# 写其他函数

像这样写,意思就是该类,继承与unittest的TestCase。然后在这个类里面写一个函数就行。那么该如何调用这个类呢?非常简单,如下:

# 调用函数if __name__ == "__main__":unittest.main()

在执行测试用例之前,我们还需要做一些准备工作收尾工作,比如获取浏览器驱动、获取测试网址,又或者是关闭浏览器,这些操作,都是需要写在函数里面的。

setUp() : 用于做准备工作的tearDown(): 用于做收尾工作的

完整的代码如下:

import unittest # 导包from selenium import webdriverclass Test(unittest.TestCase):def setUp(self): # 准备工作self.driver = webdriver.Edge()# 获取浏览器驱动self.url = "/"self.driver.maximise() # 浏览器最大化def tearDown(self): # 收尾工作self.driver.quit() # 关闭浏览器if __name__ == "__main__":unittest.main()

现在大致的样子,就是这样的。接下来就是需要我们写测试用例的代码了。

这个框架有个怪脾气,我们写的测试用例的函数名,必须是以“test_”开头,不然的话,他是不会执行这个函数的。如下

import unittest # 导包from selenium import webdriverclass Test(unittest.TestCase):def setUp(self): # 准备工作self.driver = webdriver.Edge()# 获取浏览器驱动self.url = "/"self.driver.maximise() # 浏览器最大化def tearDown(self): # 收尾工作self.driver.quit() # 关闭浏览器# 测试:百度搜索 许嵩def test_xusong(self):driver = self.driverdriver.get(self.url)driver.find_element_by_id("kw").send_keys("许嵩")driver.find_element_by_id("su").click()time.sleep(3)if __name__ == "__main__":unittest.main()

这样,我们就用unittest框架,跑了一个测试用例,如果还有其他测试用例,我们只需要在类里面另外在写一个函数即可。

执行流程

假设有很多测试用例,都写进了测试类里面,在执行代码的时候,每执行一个测试用例,它就是重新调用setUP函数,这个测试用例执行结束之后,也会先调用tearDown函数,然后才执行下一个测试用例

我们还可以使用类似于java中的注解,可以忽略某一个测试用例。

# 测试:百度搜索 许嵩@unittest.skip("kipping") # 表示忽略这个函数,不会执行这个函数def test_xusong(self):driver = self.driverdriver.get(self.url)driver.find_element_by_id("kw").send_keys("许嵩")driver.find_element_by_id("su").click()time.sleep(3)

2、unittest断言

除此之外,unittest框架还提供了断言,当测试用例很多时,程序猿眼睛可能是看不完的。这个时候我们就可以使用断言,用于判断实际结果与预期结果不相等时,就会提示测试失败

# 测试:百度搜索 许嵩def test_xusong(self):driver = self.driverdriver.get(self.url)driver.find_element_by_id("kw").send_keys("许嵩")driver.find_element_by_id("su").click()time.sleep(3)title = driver.title # 获取当前网页的titleself.assertEqual(title, "许嵩_百度搜索", msg="与预期结果不一致")time.sleep(2)

如上,当title不相等时,就会提示测试失败,在终端就能够看到这些信息。其他的一些断言方法:

当然,当断言失败,也就是预期结果与实际结果不相等时,我们还可以使用try、except语句,进行处理,将结果进行截图保存。

@data([u"彭于晏", u"彭于晏_百度搜索"], [u"胡歌", u"胡歌_百度搜索"],[u"理想", u"刘翔_百度搜索"])@unpack # 对上诉数据进行打包,用于下面代码测试def test_baidu2(self, first_value, second_value):driver = self.driverdriver.get(self.url)driver.find_element_by_id("kw").send_keys(first_value)driver.find_element_by_id("su").click()time.sleep(3)title = driver.title# self.assertEqual(second_value, title, msg="与描述不符合")try:self.assertEqual(second_value, title, msg="与描述不符合")except:self.get_screen(driver, first_value)def get_screen(self, driver, file_name):# 没有这个文件夹,就创建一个if not os.path.exists("../htmlResult"):os.makedirs("../htmlResult")# 获取现在的时间nowTime = time.strftime("%Y-%m-%d %H%M%S", time.localtime(time.time()))# 获取截图--浏览器的截图driver.get_screenshot_as_file('../htmlResult/' + nowTime + file_name + '.png')time.sleep(1)

3、HTML测试报告

在所有的测试用例执行完之后,我们还可以自动生成一个测试报告,里面就写清楚了很多信息。我们需要通过HTMLTestRunner.py 来生成测试报告,这个python解释器没有自带,需要自己下载。

HTMLTestRunner下载

然后将下载的包,放到下面这个Lib文件夹里面。

# html报告生成import osimport unittestimport timeimport HTMLTestRunner# 得到所有测试用例import demo.demo9def createSuite():# 收集写好的.py的文件suite = unittest.defaultTestLoader.loadTestsFromTestCase(demo.demo9.TestBaidu)return suiteif __name__ == "__main__":if not os.path.exists("../htmlResult"):os.makedirs("../htmlResult")now_time = time.strftime("%Y-%m-%d %H%M%S", time.localtime(time.time()))file_name = "../htmlResult/" + now_time + ".html"with open(file_name, 'wb') as fp:# 生成HTMLRunnerrunner = HTMLTestRunner.HTMLTestRunner(stream=fp,verbosity=2,title="测试报告",description="用例执行情况")suite = createSuite()runner.run(suite)

上诉代码中,使用到了suite。称为单元测试用例的集合,也就是将所有的.py源文件全部集中起来,一起跑代码。有四种得到suite的方式:

4、数据驱动

在上文中的所有代码中,我们在输入参数的时候,都是事先在代码中写好的,不够方便。那么我们可以事先将所有的测试用例写到一个txt文件中,然后我们调用一个函数,从文件中读取所有的测试用例。再使用数据驱动(ddt),将测试用例填入我们的代码中。

python 的unittest 没有自带数据驱动功能。所以如果使用unittest,同时又想使用数据驱动,那么就可以使用DDT来完成 。

# 命令行输入以下代码pip install ddt # 安装ddtpip show ddt # 查看ddt

导包:

import sysimport unittest, csvimport osfrom selenium import webdriverimport timefrom ddt import ddt, unpack, data, file_data # 新加的包

要想一个类,能够使用数据驱动,那么需要在这个类的前面写这一行代码:

要想一个函数,能够自动添加测试的数据,就需要在这个函数的前面写这样一行代码:(只需在括号里填数据就行)

或者还可以输入两个参数的形式:

上面这样的代码,虽然能够做到自动添加测试数据,但是还是不够好,如果测试数据有100万行,难道要全部一次性写在函数名前面吗?

显然没必要,此时就用到了txt文件。如下

我的txt文件内容如下,具体改怎么写读取文件的内容,还是要看你的txt文件是怎么洗的。(第一行要写data,表示这是测试数据)

也还可以读取json文件,这里我们就不多介绍了。

好啦,本期更新就到此结束啦,我们下期再见吧!!!

如果觉得《【软件测试】总结web自动化测试-selenium+python》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。