unittest+selenium结合小技巧

1389 篇文章 54 订阅
273 篇文章 20 订阅

 

   在使用unittest做单元测试时,我们可以跟selenium结合一块使用,这样的话有很多小技巧,本文就简单介绍一些他的写法。

 据说talk is cheap,所以 show my code(代码可以左右滑动,后文不再提示):

import unittestfrom selenium import webdriver#本代码以禅道为示例url = 'http://XX.XX.28.11/user-login-Lw==.html'
class ZentaoTestCase(unittest.TestCase):
  def setUp(self):    self.driver = webdriver.Chrome('/Users/zhang/downloads/chromedriver')    self.driver.get(url)     # 隐式等待,最长10秒,一次设置全局生效    self.driver.implicitly_wait(10)     #业务代码        self.driver.find_element_by_name('account').send_keys('admin')    self.driver.find_element_by_name('password').send_keys('131415qQ')    # 执行键盘操作    from selenium.webdriver.common.keys import Keys      self.driver.find_element_by_name('password').send_keys(Keys.ENTER)      def tearDown(self):    self.driver.quit()
  def testLogin(self):    #登陆的断言    assert 'admin'==self.driver.find_element_by_class_name('user-name').text    def testPageTitle1(self):    self.driver.find_element_by_link_text('测试').click()    self.driver.find_element_by_xpath("//*[@id='subNavbar']/ul/li/a").click()    #断言进入提bug页面,直接判断某个元素有没有即可。    assert self.driver.find_element_by_link_text('提Bug')
if __name__ == '__main__':    unittest.main(verbosity=2)    suite = unittest.TestSuite()    suite.addTest(ZentaoTestCase("testLogin"))    # 可以顺序添加多个case,这样就可以顺序执行单元测试了    suite.addTest(ZentaoTestCase("testPageTitle1"))    suite.addTest(ZentaoTestCase("testPageTitle2"))    runner = unittest.TextTestRunner()    runner.run(suite)

unittest3段论

import unittest
class TestZenTaoCase(unittest.TestCase):  def setUp(self):    pass  def tearDown(self):    pass  def testXXX(self):    #test code    pass

如上代码首先导入了单元测试模块,然后创建了一个测试类,并且继承了我们的unittest模块的TestCase类。这样的话,后面我们在类实例化时,就可以通过unittest的方式去实例化类,而不是再通过实例化自己测试类的方式去操作。

    然后就是unittest标准3段论,分别是启动前要执行的操作setUp函数,运行结束后操作tearDown函数,以及要执行的测试函数部分内容。

    其中setUp段函数内容,在所有的test函数每次运行前,都会运行,这样的话,方便我们在测试脚本运行前,先执行一些预加载操作。

    而同样的道理,tearDown函数,也会在所有的test函数每次结束运行后执行。

    最重要的代码部分是testXXX函数部分,这里是你最关键的测试代码,也就是要做断言的部分。尤其是需要注意的是:每个单元测试函数都是独立运行的,互相之间没有任何关联。  

selenium如何塞到unittest小小躯体里面

PART1:

 既然知道了unittest这3段论,那我们的脚本里面的内容塞进去的是啥呢。很显然是UI自动化脚本,也就是selenium的内容。

  def setUp(self):    self.driver = webdriver.Chrome('/Users/zhang/downloads/chromedriver')    self.driver.get(url)    # 隐式等待,最长10秒,一次设置全局生效    self.driver.implicitly_wait(10)     #业务代码    self.driver.find_element_by_name('account').send_keys('admin')    self.driver.find_element_by_name('password').send_keys('131415qQ')    # 执行键盘操作    from selenium.webdriver.common.keys import Keys      self.driver.find_element_by_name('password').send_keys(Keys.ENTER)

如上setUp函数代码部分,里面写的内容:实例化了谷歌浏览器,也就是我们的selenium的"司机"-driver。

然后访问了我们的url地址,然后设置了全局隐式等待时间为10秒,然后就是selenium的8种find_element定位元素大法了。

代码的最后导入了Keys模块,这个模块的作用是定义了键盘上的一些特殊操作,可以方便我们在使用selenium的时候,直接发送一些键盘操作给浏览器,让浏览器执行对应的操作,比如:这里的回车,或者CTRL键等键盘上的所有功能键。具体的有哪些键,感兴趣的可以直接去源码的selenium.webdriver.common.keys里面去看一下。

为啥写这些东西在setUp函数里面呢,因为我们要保证所有的testXXX函数都会用到,也就是每次启动的时候,都需要先执行对应的操作,也就是selenium在执行单元测试时,每次执行testXXX函数都会打开一个新的浏览器,并不会复用之前的浏览器。

因为每次都要访问url地址,并且登陆,以及selenium脚本步骤跟步骤之间的操作间隔默认情况下只有0.1秒的情况下,因为网络卡顿,页面元素没有加载完,而等不及后,就直接操作就失败。

PART2:

setUp函数部分完事了,再来看tearDown部分,这部分内容很简单

  def tearDown(self):    self.driver.quit()

只有一个浏览器退出操作,当然如果还有其他的扫尾操作,也可以加到这里。

PART3:

testXXX函数部分,也就是最关键的部分:

  def testLogin(self):    #登陆的断言    assert 'admin'==self.driver.find_element_by_class_name('user-name').text  

如上操作,其实只是做了一个断言,我们在使用selenium做UI自动化断言时,方式多种多样,可以断言浏览器的标题,也就是driver.title.我这里使用的是断言页面中其中一个元素的文本内容:admin.

其实assert 跟selenium或者unittest没有任何关系,在什么时候都可以用,而assert的写法,跟if语句写法一样,后面都是跟一个条件表达式,也就是可以判断True\False的语句。

上文还有第二个测试函数的断言是:

    assert self.driver.find_element_by_link_text('提Bug')

这句话乍看是有点问题的,其实这是很Pythonic的写法,也就是判断这个元素是否存在,如果存在的话,断言成功,否则失败。

unittest大结局

到了这里,基本上算是到尾声了,如下为结束部分代码:

if __name__ == '__main__':    unittest.main(verbosity=2)    suite = unittest.TestSuite()    suite.addTest(ZentaoTestCase("testLogin"))    # 可以顺序添加多个case,这样就可以顺序执行单元测试了    suite.addTest(ZentaoTestCase("testPageTitle1"))    suite.addTest(ZentaoTestCase("testPageTitle2"))    runner = unittest.TextTestRunner()    runner.run(suite)

上面的代码,算是unittest的写法结尾中的一种了,简单解释一下,第一句表面当在终端输出日志时,详细程度级别是2,第二句实例化了TestSuite类,然后第三句调用addTest顺序添加待执行的测试函数,当都添加完成后,再调用unittest的一种文本报告格式的Runner来执行,这样的话,报告打印的就是一个终端里面的文本内容,最后一句代码就是把前面添加的测试函数,依次执行。

当然了,unittest还支持html格式的报告,需要另外装包。也可以去通过查找指定包下面的所有py脚本(也就是模块),去挨个执行,而不仅仅是局限于当前单py脚本(也就是当前模块),也可以单独剔除掉一些,不准备执行的脚本。

unittest在实际工作中,还可以结合requests模块做接口自动化,而不仅仅只是一个单元测试脚本,所以大家可以多多尝试,发现他的一些更好用的技巧,提高自己的测试效率。

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走


在此特意为大家准备了一份13G的超实用干货学习资源,涉及的内容非常全面,涵盖功能测试、Python编程语言,接口测试、UI自动化测试、性能测试......包括软件学习路线图,50多天的上课视频、16个突击实战项目,80余个软件测试用软件,37份测试文档,70个软件测试相关问题,40篇测试经验级文章,上千份测试真题分享,还有2022软件测试面试宝典,还有软件测试求职的各类精选简历,希望对大家有所帮助…..关注下方公众号免费获取~

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值