python+selenium+unittest——ui自动化的轻量级选择

阿凡达2018-06-28 09:25

最近项目部分趋于稳定,部分功能进入了维护阶段,但每次的小改动都需要进行回归测试,回归的用例不多但也算是重复劳动浪费资源。为了节约这部分人力,我考虑引入web的ui自动化。之前在其他项目中用的都是java+selenium+testng这样的框架选型,由于testng提供了方便的参数化功能方便多组测试数据分类整合运行自动化,因此广受欢迎。然而,本次的自动化由于其业务的特殊性,其难点在于对业务自动化的实现,而非数据的组织,同时为了更快地实现这部分自动化解放生产力我决定选择一组更轻量的结构来实现。 相对于java,python可以更快地实现一个自动化case,下面介绍下过程。

一、构建一个python环境

1.安装python环境

如果你是mac系统,那么python自带,不用操心。但万恶的windows总是要人操心的。 先安装python,注意安装2.x就好了,兼容性更好一些。可以配置下环境变量,方便使用。然后再安装pip,pip官方解释:A tool for installing and managing Python packages. 也就是说pip是个python下用来安装第三方工具包的工具。

2.安装selenium

pip install -U selenium

3.安装火狐驱动

这里遇到这个问题,使用以下测试代码运行后打开了火狐浏览器但是一直卡住最后退出。

报错如下:

原来firefox47以上就需要第三方驱动了,由于网络限制官网很难下到,建议google后安装,至此环境准备妥当。

二、创建一个自动化case

1.unittest原理和使用方法

unittest中最核心的四个概念是:test case, test suite, test runner, test fixture。下面这张图是网上找的unittest类图:

 

  • 一个TestCase的实例就是一个测试用例。可以包括setUp,测试代码主体testMethod,还有tearDown。 TestSuite相当于testcase的集合,而且TestSuite也可以嵌套TestSuite。-
  • testsuite中可以指定多个testcase的执行顺序。
  • TestLoader用来加载TestCase到TestSuite中的,其中有几个loadTestsFrom__()方法,就是从各个地方寻找TestCase,创建它们的实例,然后add到TestSuite中,再返回一个TestSuite实例。
  • TextTestRunner是来执行测试用例的,其中的run(test)会执行TestSuite/TestCase中的run(result)方法。 测试的结果会保存到TextTestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息。
  • 对一个测试用例环境的搭建和销毁,是一个fixture。

以下是我的工程目录:

 

以下是一个简单case:可以看到这个类继承了TestCase 并且重写了setUp,tearDown和主体run方法test_sms。

 

2.如何组织testcase

使用testsuit组织testcase非常方便,他可以组织同一文件中的多个case,也可以组织多个不同文件中的case。如果要满足基本的使用,仅需要几行代码,如下:

suite = unittest.TestSuite()
suite.addTest(SmsTest("test_sms"))
suite.addTest(ClickTest("test_click"))
suite.addTest(DragTest("test_drag"))

这里使用了testsuit的addTest方法添加了三个case,这三个case会顺序执行。如果使用下面的TestLoader就无法顺序执行case。

suite.addTests(unittest.TestLoader().loadTestsFromName(’sms.test_sms'))
suite.addTests(unittest.TestLoader().loadTestsFromName(’drag.test_drag'))

3.简单易用的报告生成

测试报告是必须的,unittest除了提供文本报告形式,还可以生成html形式的直观报告,可以一目了然的观察testcase的执行情况,他会把console中打出的日志汇集起来,在需要排查问题的时候直接查看。 使用以下代码可以生成文本测试报告。

with open('UnittestTextReport.txt', 'a') as f:
    runner = unittest.TextTestRunner(stream=f, verbosity=2)
    runner.run(suite)

引入HTMLTestRunner,这是一个第三方的unittest HTML报告库。需要下载一个HTMLTestRunner.py,并放在python的lib库下。

with open('HTMLReport.html', 'w') as f:
    runner = HTMLTestRunner.HTMLTestRunner(stream=f,
                            title='CaptchaTest Report',
                            description='generated by HTMLTestRunner.',
                            verbosity=2
                            )
    runner.run(suite)

生成的测试报告如下,可以看到有fail,pass和error三种类型。fail指的是case失败,而error指的是诸如找不到元素等异常导致的失败。

三、有趣的点

事实上,本次实现的自动化难点在于业务,出于项目的保密性,这部分不能分享,倒是可以分享一个有趣的技术实现。目前selenium没有api可以进行接口的交互,但是往往我们进行ui自动化,有时候是需要从接口中拿一些数据用于界面元素的填充等的。尽管有时候我们可以在代码中调用一下某个接口也获取需要的数据,但是,当ui和这个接口强相关的时候——调用了一下这个接口,当下的ui元素会刷新失效——这种情况下我们就不能简单的调用接口了。推荐一个好用的代理browsermobproxy。为了实现上述需求,可以在setUp方法中启动这个代理,获取页面元素时代理正在监控并抓取响应的接口请求和返回信息。只需设置一个target接口url, 当代理抓取到目标接口时分离并获取返回的目标数据,就可以供自动化输入到页面元素中填充了。源码参看:

 

本文来自网易实践者社区,经作者何美玲授权发布。