#从数据库表中删除的读入的数据,比如:Jerry/123456 }


比如测试程序在继续后续测试的时候出现了一个异常,比如元素没有找到,系统会自动退出,而不去执行teardown方法,也就是说数据库中的数据没有得到清除,这样如果下一次测试同样的case,采用同样的测试数据就会使测试程序发生脏数据异常,为了解决这个问题我们通过使用Python的try-catch来捕获异常,并且将所有的方法封装在一个类中。我们在util.py中封装一个class类。


(1)封装定位API

代码1:封装定位API。


def find_element_by_id(self,driver,mystr):
             returndriver.find_element_by_id(mystr)
         exceptNoSuchElementException:
             print("find_element_by_id 没有发现元素"+mystr)


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


def setUp(self):
     d =drivers()
     self.driver=d.driver
     self.fd=findby()
     self.fd.implicitly_wait(self.driver,5)
def test_XXX():
    self.fd.find_element_by_id(self.driver,"kw").clear()


当然其他的定位方式也同样适用。


(2)封装操作API

代码2:封装操作API。


def send_keys(self,elenment,send_string):
             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提供了现式等待和隐式等待,实际工程中会发现这两个方法是有缺陷的,并且好些浏览器根本就不支持)。在这里进行如下的优化。

代码3:Retry优化。


def find_element_by_id(self,driver,mystr):
                        returndriver.find_element_by_id(mystr)
               except NoSuchElementException:
                       for i in range(2):
                                       time.sleep(2000)
                                        returndriver.find_element_by_id(mystr)
                                exceptNoSuchElementException:
                                       print("尝试第"+str(i+1)+"次失败")
                        print("尝试第3次失败")
                        print("find_element_by_id没有发现元素"+mystr)


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


3.对页面的封装


def test_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,"删除"))


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


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


代码4:测试添加用户购物配送地址功能。


#登录页面
class LoginPage:
def__init__(self,driver,username,password):
     self.username= username#用户名作为构造函数参数进入
     self.password= password#密码作为构造函数参数进入
     self.driver= driver#驱动
     self.usename_input= findby.find_element_by_id(self,driver,"id_username")#用户名输入框
     self.password_input= findby.find_element_by_id(self,driver,"id_password")#密码输入框
     self.login_form=findby.find_element_by_class_name(self,driver,"form-signin")#登录表单
 #登录操作
 deflogin(self):
     findby.clear(self.driver,self.usename_input)#清空用户输入框
     findby.send_keys(self.driver,self.usename_input,self.username)#输入用户名
     findby.clear(self.driver,self.password_input)#清空密码输入框
     findby.send_keys(self.driver,self.password_input,self.password)#输入密码
     findby.submit(self.driver,self.login_form)#提交表单
产品页面封装如下。
#产品页面
class ProductPage:
     def__init__(self,driver,username):
self.username =username用户名作为构造函数参数进入
self.driver = driver#驱动
self.user_name_link =findby.find_element_by_link_text(self,driver,self.username)#登录用户名点击链接
    #进入用户信息页面
    def click_username(self):
       findby.click(self.driver,self.user_name_link)# 点击登录用户名链接


登录用户详情页面封装如下。


#登录用户详情页面
class UserPage:
def__init__(self,driver):
self.driver = driver
self.create_address_button= findby.find_element_by_id(self,driver,"add_address")#添加购物配送地址按钮
#添加购物配送地址信息
def click_add_address_button(self):
findby.click(self.driver,self.create_address_button)
 #验证地址信息
 defcheck_address(self):
       return findby.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)


在这里需要注意,如果用户没有添加购物配送地址的时候,“删除”链接是找不到的,所以这里“删除”链接元素变量只能定义在方法体内,不能作为类变量。


添加地址页面封装如下。


#添加地址页面
class AddressPage:
    def __init__(self,driver,addess,phone):
        self.addess = addess#地址
        self.phone = phone#短话
        self.driver = driver
 self.address_name_input =findby.find_element_by_name(self,driver,"address")#地址输入框
        self.address_phone_input =findby.find_element_by_name(self,driver,"phone")#电话号输入框
self.address_form =findby.find_element_by_xpath(self,driver,"/html/body/div/form/button")#地址输入信息表单
    #添加新地址
    def create_address(self):
       findby.clear(self.driver,self.address_name_input)#清除地址栏信息
       findby.send_keys(self.driver,self.address_name_input,self.addess)#输入地址信息
        findby.clear(self.driver,self.address_phone_input)#清除电话栏信息
       findby.send_keys(self.driver,self.address_phone_input,self.phone)#输入电话信息
       findby.submit(self.driver,self.address_form)#提交表单

这样,验证添加购物地址的测试代码如下。


from util import drivers,findby
from page import Util,LoginPage,ProductPage,UserPage,AddressPage
class CheckEBusiness(unittest.TestCase):
    defsetUp(self):
        d =drivers()
       self.driver=d.driver
       self.fd=findby()
       self.fd.implicitly_wait(self.driver,5)
       self.fd.get(self.driver,"http://127.0.0.1:8000")
    deftest_Add_Addess(self):
       LoginPage(self.driver,"cindy","123456").login()
       ProductPage(self.driver,"cindy").click_username()
       UserPage(self.driver).click_add_address_button()
       AddressPage(self.driver,"首体南路3号","13681732596").create_address()
        self.assertIsNotNone(UserPage(self.driver).check_address())
        UserPage(self.driver).delete_address()
    deftearDown(self):
       Util(self.driver).logout()
       self.fd.quit(self.driver)
if __name__=="__main__":
       unittest.main()


这样测试程序的代码的可读性与可维护性都得到了很好得加强。现在增加“测试购物车功能”的验证。只需在Product类中建立如下方法。


代码5:测试添加商品进购物车功能。


self.put_into_cart_link =findby.find_element_by_link_text(self,driver,"放入")#“放入”链接
self.view_cart_link =findby.find_element_by_partial_link_text(self,driver,"查看购物车")#“查看购物车”链接
#放入购物车
    def put_into_cart(self):
       findby.click(self.driver,self.put_into_cart_link)# 点击“放入”链接
    #查看购物车
    def view_cart(self):
       findby.click(self.driver,self.view_cart_link)# 点击“查看购物车”链接
在加入一个Cart(购物车)类。
#购物车页面
class Cart:
    def __init__(self,driver):
        self.driver = driver#驱动
        self.goods_count =findby.find_element_by_xpath(self,driver,"//*[@id=\"id_count\"]")
        self.remove_link =findby.find_element_by_link_text(self,driver,"移除")
    #验证购物车中是否存在商品
    def check_goods(self):
        return self.goods_count
    #删除购物车总中的商品
    def delete_goods(self):
        findby.click(self.remove_link)


相应的测试代码为。


def test_Add_Goods_into_Cart(self):
       LoginPage(self.driver,self.username,self.password).login()
       ProductPage(self.driver,self.username).put_into_cart()
        ProductPage(self.driver,self.username).view_cart()
       self.assertIsNotNone(Cart(self.driver).goods_count)
Cart(self.driver).delete_goods


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


代码6:测试商品查询功能。


self.search_input =findby.find_element_by_name(self,driver,"good")#查询商品文本框
self.search_button =findby.find_element_by_xpath(self,driver,"//*[@id=\"navbar\"]/form/button")#查询商品按钮
#商品查询
def search_goods(self,good_name):
       findby.send_keys(self.driver,self.search_input,good_name)#输入查询内容
       findby.click(self.driver,self.search_button)#输入查询内容
       return self.put_into_cart_link


而在测试代码中加入如下两行测试语句就可以了。


def test_Search_Goods(self):
       LoginPage(self.driver,self.username,self.password).login()
       self.assertIsNotNone(ProductPage(self.driver,self.username).search_goods("茶"))


测试自动化工具比较:Selenium vs. Cypress
在软件开发过程中,测试自动化是一个关键的环节,它可以提高测试效率和质量,并帮助开发团队更快地交付高质量的软件。在测试自动化领域,Selenium和Cypress是两个备受关注的工具。本文将对它们进行比较,帮助开发者选择适合自己项目的测试自动化工具。
基于Selenium的测试程序优化
顾翔老师开发的bugreport2script开源了,希望大家多提建议。文件在https://github.com/xianggu625/bug2testscript, 主文件是:zentao.py 。bugreport是禅道,script是python3+selenium 3,按照规则在禅道上书写的bugreport可由zentao.py程序生成py测试脚本。 怎么利用 ChromeDriver 和 Selenium对 CEF应用进行自动化测试-python实现
怎么利用 ChromeDriver 和 Selenium对 CEF应用进行自动化测试-python实现
Selenium 大家应该都很熟悉了吧,简单说它就是个基于浏览器的 Web 自动化测试工具,基本上是自动化测试人员首选工具。因为相比其他工具,它有很多的优势: 支持多种语言,比如 Python、Java、C或C#、ruby 等都支持; 支持多种浏览器, 比如 IE、FireFox、Safari、Opera、Chrome 这些主流浏览器基本都支持; 支持多种操作系统,比如 Windows、Mac、Linux 这个款主流操作系统。