Selenium测试程序的优化

简介: Selenium测试程序的优化

1.异常优化


考虑以下情形。

deftestLogin():
#从Excel文件中读入测试数据,比如:Jerry/123456
#继续后续测试
defteardown():
#从数据库表中删除的读入的数据,比如:Jerry/123456
...


比如测试程序在继续后续测试的时候出现了一个异常,比如元素没有找到,系统会自动退出,而不去执行teardown方法,也就是说数据库中的数据没有得到清除,这样如果下一次仍旧执行这个测试用例,这样就会产生异常,这个异常是刚才没有执行清除数据造成,这时的数据就叫做“脏数据”,为了解决这个问题,可以通过使用Pythontry-except来捕获异常,并且将所有的方法封装在一个类中。在util.py中封装一个class类。


1)封装定位API
案例:封装定位API。
deffind_element_by_id(self,driver,mystr):
try:
return driver.find_element_by_id(mystr)
exceptNoSuchElementException:
print("find_element_by_id 没有发现元素"+mystr)


这样如果系统通过by_id方式找不到某个元素,测试程序会抛出“find_element_by_id 没有发现元素"+mystrmystr即定位的id号)”信息,然后继续下面的程序。调用的时候采用下面的方法。

defsetUp(self):
d = drivers()
self.driver=d.driver
self.fd=findby()
self.fd.implicitly_wait(self.driver,5)
deftest_XXX():
self.fd.find_element_by_id(self.driver,"kw").clear()


其他的定位方式也采取同样的方法。


2)封装操作API
案例:封装操作API


defsend_keys(self,elenment,send_string):
        try:
             elenment.send_keys(send_string)
        except:
              print("send_keys操作失败")


当执行send_keys发生异常,系统抛出“send_keys操作失败”信息,然后继续下面的程序。调用的时候采用下面的方法。


self.fd.send_keys(self.fd.find_element_by_id(self.driver,"kw"),inputstring)


2.Retry优化


UI自动化测试程序的最大问题之一在于由于网络的不稳定,从而造成页面元素不是不存在,而是还没有被调出来(虽然Selenium提供了显隐式等待,实际工程中会发现这两个方法是有缺陷的,并且好些浏览器根本就不支持)。在这里进行如下的优化。


案例Retry优化。
deffind_element_by_id(self,driver,mystr):
try:
return driver.find_element_by_id(mystr)
except NoSuchElementException:
for i in range(2):
try:
time.sleep(2000)
return driver.find_element_by_id(mystr)
except NoSuchElementException:
print("尝试第"+str(i+1)+"次失败")
print("尝试第3次失败")
print("find_element_by_id 没有发现元素"+mystr)


当程序找不到元素的时候,等待2秒钟,继续获取,如果还是没有取到,继续等待,在这里设置了3次的等待机会,如果没有,则报异常信息。


3.对页面的封装


案例:测试添加用户购物配送地址功能。

deftest_Add_Addess(self):
username='cindy'
password='123456'
#登录
self.clear(self.find_element_by_id(driver,"id_username"))
self.send_keys(self.find_element_by_id(driver,"id_username"),username)
self.clear(self.find_element_by_id(driver,"id_password"))
self.send_keys(self.find_element_by_id(driver,"id_password"),password)
self.submit(self.find_element_by_class_name(driver,"form-signin"))
#在登录首页找到用户名
self.fd.click(self.fd.find_element_by_link_text(self.driver,username))
#进入用户信息列表
self.fd.click(self.fd.find_element_by_id(self.driver,"add_address"))
#进入添加送货地址信息页面,添加收货信息
self.fd.clear(self.fd.find_element_by_name(self.driver,"address"))
self.fd.send_keys(self.fd.find_element_by_name(self.driver,"address"),"北京清华")
self.fd.clear(self.fd.find_element_by_name(self.driver,"phone"))
self.fd.send_keys(self.fd.find_element_by_name(self.driver,"phone"),"13699876655")
self.fd.click(self.fd.find_element_by_xpath(self.driver,"/html/body/div/form/button"))
#验证加入的信息
self.assertIsNotNone(self.fd.find_element_by_link_text(self.driver,"删除"))
#测试完毕,清场操作
self.fd.click(self.fd.find_element_by_link_text(self.driver,"删除"))


被测对象是一个附录A电子商务网站,要测试在用户界面添加一条收货信息。必须先登录,登录完毕后点击当前用户名的超链接,然后进入用户信息界面,接下来点击新建用户收货地址按钮,进入新建页面,建立完毕进行断言,最后为了以后仍旧可以进行这个测试用例,进行清除操作。由此可见,如果一个测试业务比较长,按照这样的写法可读性是比较差的,并不便于维护,因此采用目前比较流行的基于页面的封装方法。


先对登录页面进行封装,代码如下。

#通用信息
classUtil:
def __init__(self,driver):
self.driver = driver
def logout(self):
findby.click(self.driver,findby.find_element_by_link_text(self,self.driver,"退出"))
findby.quit(self,self.driver)
#登录页面
class LoginPage:
def __init__(self,driver):
self.driver = driver
#登录操作
def login(self,username,password):
findby.clear(self.driver,findby.find_element_by_id(self,self.driver,"id_username"))
#清空用户输入框
findby.send_keys(self.driver,findby.find_element_by_id(self,self.driver,"id_username"),username)
#输入用户名
findby.clear(self.driver,findby.find_element_by_id(self,self.driver,"id_password"))
#清空密码输入框
findby.send_keys(self.driver,findby.find_element_by_id(self,self.driver,"id_password"),password)#
输入密码
findby.submit(self.driver,findby.find_element_by_class_name(self,self.driver,"form-signin"))
#提交表单


产品页面封装如下。

#产品页面
classProductPage:
def __init__(self,driver):
self.driver = driver
#进入用户信息页面
def click_username(self,username):
findby.click(self.driver,findby.find_element_by_link_text(self,self.driver,username))
#点击登录用户名链接


用户详情页面封装如下。


#用户详情页面
classUserPage:
def __init__(self,driver):
self.driver = driver
#添加购物配送地址信息
def click_add_address_button(self):
findby.click(self.driver,findby.find_element_by_id(self,self.driver,"add_address"))
#验证地址信息
def check_address(self):
returnfindby.find_element_by_link_text(self,self.driver,"删除")
#删除地址信息
def delete_address(self):
delete_button = findby.find_element_by_link_text(self,self.driver,"删除")
findby.click(self.driver,delete_button)
添加地址页面封装如下。
#地址
classAddressPage:
def __init__(self,driver):
self.driver = driver
#添加新地址
defcreate_address(self,addess,phone):
     findby.clear(self.driver,findby.find_element_by_name(self,self.driver,"address"))
#清空地址栏
findby.send_keys(self.driver,findby.find_element_by_name(self,self.driver,"address"),addess)
#输入地址信息
findby.clear(self.driver,findby.find_element_by_name(self,self.driver,"phone"))
#清空电话栏
findby.send_keys(self.driver,findby.find_element_by_name(self,self.driver,"phone"),phone)
#输入电话信息
findby.submit(self.driver,findby.find_element_by_xpath(self,self.driver,"/html/body/div/form/button"))
#提交表单
这样,验证添加购物地址的测试代码如下。
#coding:utf-8
fromselenium import webdriver
fromselenium.webdriver.support.ui import WebDriverWait
importunittest,time
fromutil import drivers,findby
frompage import Util,LoginPage,ProductPage,UserPage,AddressPage,CartPage
classCheckEBusiness(unittest.TestCase):
def setUp(self):
driver = drivers().driver
fd = findby()
self.util = Util(driver)
self.loginpage = LoginPage(driver)
self.producepage = ProductPage(driver)
self.userpage = UserPage(driver)
self.addresspage = AddressPage(driver)
self.cartpage = CartPage(driver)
fd.implicitly_wait(driver,5)
fd.get(driver,"http://127.0.0.1:8000")
self.username = "cindy"
self.password = "123456"
self.adddress = "首体南路3号"
self.phone = "13681732596"
deftest_Add_Addess(self):
self.loginpage.login(self.username,self.password)
self.producepage.click_username(self.username)
self.userpage.click_add_address_button()
self.addresspage.create_address(self.adddress,self.phone)
self.assertIsNotNone(self,self.userpage.check_address())
self.userpage.delete_address()
if __name__=="__main__":
unittest.main()
  • 这样测试程序的代码可读性与可维护性都得到了很好的加强。接下来添加测试“购物车功能”的验证。只需在Product类中建立如下两个方法。


案例:测试添加商品进购物车功能。


#放入购物车
defput_into_cart(self):
findby.click(self.driver,findby.find_element_by_link_text(self,self.driver,"放入"))# 点击“放入”链接
#查看购物车
defview_cart(self):
findby.click(self.driver,findby.find_element_by_partial_link_text(self,self.driver,"查看购物车"))# 点击“查看购物车”链接在加入一个Cart(购物车)类。
然后增加一个购物车的类。
#购物车页面
classCartPage:
def __init__(self,driver):
self.driver = driver
#验证购物车中是否存在商品
def check_goods(self):
returnfindby.find_element_by_xpath(self,self.driver,"//*[@id=\"id_count\"]")
#删除购物车中总的商品
def delete_goods(self):
findby.click(self.driver,findby.find_element_by_link_text(self,self.driver,"移除"))
相应的测试代码如下。
deftest_Add_Goods_into_Cart(self):
self.loginpage.login(self.username,self.password)
self.producepage.put_into_cart()
self.producepage.view_cart()
self.assertIsNotNone(self.cartpage.check_goods())
self.cartpage.delete_goods()


最后再来验证一下对商品查询的功能,在Product类中加入。


案例:测试商品查询功能。

#商品查询
defsearch_goods(self,good_name):
findby.send_keys(self.driver,findby.find_element_by_name(self,self.driver,"good"),good_name)#输入查询内容
findby.click(self.driver,findby.find_element_by_xpath(self,self.driver,"//*[@id=\"navbar\"]/form/button"))#输入查询内容
returnfindby.find_element_by_link_text(self,self.driver,"放入")
在测试代码中加入如下两行测试语句就可以了。
deftest_Search_Goods(self):
self.loginpage.login(self.username,self.password)
self.assertIsNotNone(self.producepage.search_goods("茶"))


案例:使用Pytest测试电子商务网站

现在用Pytest+allure完成前面几个测试用例,代码如下。

page.py


#!/usr/bin/envpython
#coding:utf-8
fromselenium import webdriver
from selenium.common.exceptionsimport NoSuchElementException
fromselenium.webdriver.support.ui import WebDriverWait
fromselenium.webdriver.common.by import By
fromselenium.webdriver import ActionChains
fromutil import findby
importtime
importallure
#通用信息
classUtil:
def __init__(self,driver):
self.driver = driver
def logout(self):
findby.click(self.driver,findby.find_element_by_link_text(self,self.driver,"退出"))
findby.quit(self,self.driver)
#登录页面
classLoginPage:
def __init__(self,driver):
self.driver = driver
@allure.step("登录系统")
def login(self,username,password):
findby.clear(self.driver,findby.find_element_by_id(self,self.driver,"id_username"))#清空用户输入框
findby.send_keys(self.driver,findby.find_element_by_id(self,self.driver,"id_username"),username)#输入用户名
findby.clear(self.driver,findby.find_element_by_id(self,self.driver,"id_password"))#清空密码输入框
findby.send_keys(self.driver,findby.find_element_by_id(self,self.driver,"id_password"),password)#输入密码
 findby.submit(self.driver,findby.find_element_by_class_name(self,self.driver,"form-signin"))#提交表单
#产品页面
classProductPage:
def __init__(self,driver):
self.driver = driver
@allure.step("进入用户信息页面")
def click_username(self,username):
findby.click(self.driver,findby.find_element_by_link_text(self,self.driver,username))#点击登录用户名链接
@allure.step("放入购物车")
def put_into_cart(self):
findby.click(self.driver,findby.find_element_by_link_text(self,self.driver,"放入"))# 点击“放入”链接
@allure.step("查看购物车")
def view_cart(self):
findby.click(self.driver,findby.find_element_by_partial_link_text(self,self.driver,"查看购物车"))# 点击“查看购物车”链接
@allure.step("商品查询")
def search_goods(self,good_name):
findby.send_keys(self.driver,findby.find_element_by_name(self,self.driver,"good"),good_name)#输入查询内容
findby.click(self.driver,findby.find_element_by_xpath(self,self.driver,"//*[@id=\"navbar\"]/form/button"))#输入查询内容
return findby.find_element_by_link_text(self,self.driver,"放入")
#购物车页面
classCartPage:
def __init__(self,driver):
self.driver = driver
@allure.step("验证购物车中是否存在商品")
def check_goods(self):
returnfindby.find_element_by_xpath(self,self.driver,"//*[@id=\"id_count\"]")
@allure.step("删除购物车中总的商品")
def delete_goods(self):
findby.click(self.driver,findby.find_element_by_link_text(self,self.driver,"移除"))
#登录用户详情页面
classUserPage:
def __init__(self,driver):
self.driver = driver
@allure.step("添加购物配送地址信息")
def click_add_address_button(self):
findby.click(self.driver,findby.find_element_by_id(self,self.driver,"add_address"))
@allure.step("验证地址信息")
def check_address(self):
returnfindby.find_element_by_link_text(self,self.driver,"删除")
@allure.step("删除地址信息")
def delete_address(self):
delete_button =findby.find_element_by_link_text(self,self.driver,"删除")
findby.click(self.driver,delete_button)
#地址
classAddressPage:
def __init__(self,driver):
self.driver = driver
@allure.step("添加新地址")
def create_address(self,addess,phone):
findby.clear(self.driver,findby.find_element_by_name(self,self.driver,"address"))#清空地址栏
findby.send_keys(self.driver,findby.find_element_by_name(self,self.driver,"address"),addess)#输入地址信息
 findby.clear(self.driver,findby.find_element_by_name(self,self.driver,"phone"))##清空电话栏
findby.send_keys(self.driver,findby.find_element_by_name(self,self.driver,"phone"),phone)#输入电话信息
findby.submit(self.driver,findby.find_element_by_xpath(self,self.driver,"/html/body/div/form/button"))#提交表单


test_PageObjetTest.py


#!/usr/bin/envpython
#coding:utf-8
fromselenium import webdriver
fromselenium.webdriver.support.ui import WebDriverWait
importtime
fromutil import drivers,findby
frompage import Util,LoginPage,ProductPage,UserPage,AddressPage,CartPage
importpytest
importallure
classTestEBusiness:
def setup(self):
driver = drivers().driver
fd = findby()
self.util = Util(driver)
self.loginpage = LoginPage(driver)
self.producepage = ProductPage(driver)
self.userpage = UserPage(driver)
self.addresspage = AddressPage(driver)
self.cartpage = CartPage(driver)
fd.implicitly_wait(driver,5)
fd.get(driver,"http://127.0.0.1:8000")
self.username = "cindy"
self.password = "123456"
self.adddress = "首体南路3号"
self.phone = "13681732596"
@allure.feature('电子商务产品')
@allure.story('添加配货地址')
@allure.severity('Normal')
@allure.issue("http://www.jila.com")
@allure.testcase("http://www.testlink.com")
def test_Add_Addess(self):
self.loginpage.login(self.username,self.password)
self.producepage.click_username(self.username)
self.userpage.click_add_address_button()
self.addresspage.create_address(self.adddress,self.phone)
try:
self.userpage.check_address()
assert 1==1
except:
assert 0==1
self.userpage.delete_address()
@allure.feature('电子商务产品')
@allure.story('添加进购物车')
@allure.severity('Normal')
@allure.issue("http://www.jila.com")
@allure.testcase("http://www.testlink.com")
def test_Add_Goods_into_Cart(self):
self.loginpage.login(self.username,self.password)
self.producepage.put_into_cart()
self.producepage.view_cart()
try:
self.cartpage.check_goods()
assert 1==1
except:
assert 0==1
self.cartpage.delete_goods()
@allure.feature('电子商务产品')
@allure.story('模糊查询商品')
@allure.severity('Normal')
@allure.issue("http://www.jila.com")
@allure.testcase("http://www.testlink.com")
def test_Search_Goods(self):
self.loginpage.login(self.username,self.password)
try:
self.producepage.search_goods("茶")
assert 1==1
except:
assert 0==1
def teardown(self):
self.util.logout()
if__name__ == '__main__':
pytest.main(['-sv', '-q', '--alluredir','./report/xml'])


建立文件report.bat


del.\report\*
pytest.\test_PageObjetTest.py -s -q --alluredir report .\report\
allureserve .\report
allureopen -h 127.0.0.1 -p 8083 .\report\report\


运行后产生如图1所示的测试报告。

image.png


                         

1 电子商务网站Pytest+Selenium 测试报告


顾老师性能测试课程

selenium自动化测试

https://study.163.com/course/courseMain.htm?courseId=1209835807&share=2&shareId=480000002205486

image.png

目录
相关文章
|
23天前
|
安全 Linux 测试技术
提升龙蜥内核测试能力!探究持续性模糊测试优化实践
清华大学软件学院对Anolis OS使用靶向模糊测试方法将测试工作引向修改的代码,进而提高对业务代码的测试能力。
|
22天前
|
Web App开发 前端开发 Java
《手把手教你》系列技巧篇(九)-java+ selenium自动化测试-元素定位大法之By name(详细教程)
【4月更文挑战第1天】 这篇教程介绍了如何使用Selenium Webdriver通过name属性来定位网页元素,作为系列教程的一部分,之前讲解了id定位,后续还会有其他六种定位方法。文中以百度搜索为例,详细说明了定位搜索框(name="wd")并输入关键词“北京宏哥”的步骤,包括手动操作流程、编写自动化脚本以及代码实现。此外,还提供了查看和理解Selenium源码的方法,强调了`open implementation`选项用于查看方法的具体实现。整个过程旨在帮助读者学习Selenium的元素定位,并实践自动化测试。
41 0
|
18天前
|
前端开发 Java 测试技术
《手把手教你》系列技巧篇(十二)-java+ selenium自动化测试-元素定位大法之By link text(详细教程)
【4月更文挑战第4天】本文介绍了link text在自动化测试中的应用。Link text是指网页中链接的文字描述,点击可跳转至其他页面。文章列举了8种常用的定位方法,其中着重讲解了link text定位,并通过实例展示了如何使用Java代码实现点击百度首页的“奥运奖牌榜 最新排名”链接,进入相应页面。如果link text不准确,则无法定位到元素,这说明linkText是精准匹配,而非模糊匹配。文章还提到了partial link text作为link text的模糊匹配版本,将在后续内容中介绍。
36 4
|
16天前
|
XML 前端开发 Java
《手把手教你》系列技巧篇(十四)-java+ selenium自动化测试-元素定位大法之By xpath上卷(详细教程)
【4月更文挑战第6天】按宏哥计划,本文继续介绍WebDriver关于元素定位大法,这篇介绍定位倒数二个方法:By xpath。xpath 的定位方法, 非常强大。使用这种方法几乎可以定位到页面上的任意元素。xpath 是XML Path的简称, 由于HTML文档本身就是一个标准的XML页面,所以我们可以使用Xpath 的用法来定位页面元素。XPath 是XML 和Path的缩写,主要用于xml文档中选择文档中节点。基于XML树状文档结构,XPath语言可以用在整棵树中寻找指定的节点。
43 0
|
2天前
|
前端开发 测试技术 C++
Python自动化测试面试:unittest、pytest与Selenium详解
【4月更文挑战第19天】本文聚焦Python自动化测试面试,重点讨论unittest、pytest和Selenium三大框架。unittest涉及断言、TestSuite和覆盖率报告;易错点包括测试代码冗余和异常处理。pytest涵盖fixtures、参数化测试和插件系统,要注意避免过度依赖unittest特性。Selenium的核心是WebDriver操作、等待策略和测试报告生成,强调智能等待和元素定位策略。掌握这些关键点将有助于提升面试表现。
14 0
|
4天前
|
Web App开发 JavaScript 前端开发
深入理解自动化测试框架Selenium的设计与实现
【4月更文挑战第20天】 在软件测试领域,自动化测试已成为提升测试效率和确保产品质量的关键手段。Selenium作为一款广泛使用的开源自动化测试框架,其设计精巧且功能强大,为Web应用提供了一种灵活、高效的测试解决方案。本文将深入探讨Selenium的核心架构与实现细节,解析其如何通过模拟用户操作来执行测试用例,以及它如何适应不断变化的Web技术标准。通过对Selenium内部机制的剖析,旨在帮助测试工程师更好地掌握该工具,并在测试实践中发挥其最大效能。
|
5天前
|
前端开发 JavaScript Java
《手把手教你》系列技巧篇(二十五)-java+ selenium自动化测试-FluentWait(详细教程)
【4月更文挑战第17天】其实今天介绍也讲解的也是一种等待的方法,有些童鞋或者小伙伴们会问宏哥,这也是一种等待方法,为什么不在上一篇文章中竹筒倒豆子一股脑的全部说完,反而又在这里单独写了一篇。那是因为这个比较重要,所以宏哥专门为她量身定制了一篇。FluentWait是Selenium中功能强大的一种等待方式,翻译成中文是流畅等待的意思。在介绍FluentWait之前,我们来讨论下为什么需要设置等待,我们前面介绍了隐式等待和显式等待。
28 3
|
7天前
|
Java 测试技术 定位技术
《手把手教你》系列技巧篇(二十三)-java+ selenium自动化测试-webdriver处理浏览器多窗口切换下卷(详细教程)
【4月更文挑战第15天】本文介绍了如何使用Selenium进行浏览器窗口切换以操作不同页面元素。首先,获取浏览器窗口句柄有两种方法:获取所有窗口句柄的集合和获取当前窗口句柄。然后,通过`switchTo().window()`方法切换到目标窗口句柄。在项目实战部分,给出了一个示例,展示了在百度首页、新闻页面和地图页面之间切换并输入文字的操作。最后,文章还探讨了在某些情况下可能出现的问题,并提供了一个简单的本地HTML页面示例来演示窗口切换的正确操作。
33 0
|
8天前
|
敏捷开发 监控 前端开发
深入理解自动化测试框架Selenium的架构与实践
【4月更文挑战第16天】 在现代软件开发过程中,自动化测试已成为确保产品质量和加快迭代速度的关键手段。Selenium作为一种广泛使用的自动化测试工具,其开源、跨平台的特性使得它成为业界的首选之一。本文旨在剖析Selenium的核心架构,并结合实际案例探讨其在复杂Web应用测试中的高效实践方法。通过详细解读Selenium组件间的交互机制以及如何优化测试脚本,我们希望为读者提供深入理解Selenium并有效运用于日常测试工作的参考。
14 1
|
9天前
|
自然语言处理 测试技术 API
深入理解自动化测试框架Selenium的设计理念与实践
【4月更文挑战第15天】 在现代软件开发过程中,自动化测试已成为确保产品质量和加速迭代的关键手段。Selenium作为一种广泛使用的自动化测试框架,提供了对多种浏览器和平台的支持,极大地促进了Web应用的功能测试。本文旨在剖析Selenium的核心设计理念,探讨其在实际项目中的应用,并指出常见的误区及最佳实践,以期帮助测试工程师更高效地利用Selenium进行测试工作。

热门文章

最新文章