自动化框架的搭建概述
UiAutomator、Selenium和RobotFramework这些自动化平台的推出,为自动化测试提供了基础,这些平台提供通用的UI元素定位和UI元素操作的API,让人为执行用例的过程用测试脚本代替,以后UI和业务流程测试满足自动化条件时,工程师可以通过编写测试用例完成。无论人工还是代码自动化,提高测试效率才是最终目的,正如开发一个Android App一样,我们开发app不用纠结底层AMS、WMS和PMS等这些系统服务的原理和实现,我们只需要根据开发者文档会用即可。自动化框架的构建也是这个目的,对于测试开发工程师或自动化开发工程师来说,根据公司需求,构建符合公司实际的自动化软件平台才是我们的任务。以我用的Appium来说,自动化工程师需要完成AppiumServer的安装搭建,对于Android系统用到的公用API如按键操作(back,menu,home,volume+等等),app安装卸载,日志文件拉取,生成报告等这些公用的服务进行封装或套接。以下我尝试用分层架构思维进行对整个框架的搭建叙述,如有谬误,请批评指正。
自动化框架模块集合
1. appium-client
这里我默认读者已经完成appium-server的安装配置。appium-client是我们搭建自动化框架的基础,他提供了和客户端交互的协议和接口,通过和DUT(device under test)建立http连接,我们的测试脚本才能传到客户端完成操作流程。下面是appium-client在github上的托管地址(python版本):https://github.com/appium/python-client
2. unittest
这个是python语言提供的一个完整的测试框架,里面有用例基类,断言,用例加载器Loader和执行器Runner等接口,appium-client和unittest的结合会给我们带来极大便利;java语言可以选择junit。
3. HTMLTestRunner
这个也是现有的三方库,用它执行测试用例后,会输出格式化的测试报告,为我们检验提供方便。
4. logging
所有执行过程中,我们需要输出log,才能对执行结果进行监控和跟踪。
以上都有现成的三方库,工程师只需要把他们有机的套接起来即可。还有些模块需要自己进行封装,为顶层提供调用。
5. driver
driver这里意指自动化框架的驱动,也就是为整个自动化跑起来提供基础连接的模块,无论是web还是android,自动化框架必须和DUT建立连接,下面是自动化框架和android或web建立连接的语句:
Web端:
driver = webdriver.Chrome()
driver.get(url)
Android端:
desired_caps = {}
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '6.0.1'
desired_caps['deviceName'] = '8c28b78c'
desired_caps['appPackage'] = 'com.ss.android.article.news'
desired_caps['appActivity'] = '.activity.SplashActivity'
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
如上所示,是连接驱动,这里我们其实可以对其进行一定的封装,因为每条用例没必要重复开启连接,我们在整个测试集启动之前,建立一个连接或连接池(连接池对应多台设备)即可。这里的封装总结如下:
1.driver封装:可以是自己定义一个MyDriver类,然后让框架的driver作为MyDriver的内置对象,或者让自己的MyDriver继承框架driver,class MyDriver(driver),这样封装有一个好处,就是对driver可控,因为driver连接一次需要消耗资源,所以,对齐封装后,连接时机和数量在框架内可以进行控制;
2. driver连接池,如果自动化平台同时在多台设备上跑,需要建立多个连接,也就是多个driver进行通信。类似于数据库连接池或者线程池,为了减少资源消耗或者资源可控设计的,我们这里的driver连接也可以看成是一个高消耗资源的类,所以在整个框架跑起来之初,可以原先建立起多个连接,放入driver连接池,这个链接池属于appium框架底层,对他的上一层都是可见的。
6. 公用层(Common)
PageObject模型和自动化框架(一)我们说用PageObject模式,将Page的公用接口封装了起来,那么多个Page之间还有没有公用接口呢?答案是肯定的,回想之前那篇文章AppObject(请博友不要喷,我为了叙述方便),PO模型是对Page的封装,那么AO就是对App的公用接口封装,比如某个App为了UI界面一致性,所有页面的弹窗样式内容都一样,那么操作这个弹窗的接口就可以封装成一个app级别的公用接口;好,这是PO,AO公用层,那么在网上还可以抽象基于整个系统的公用曾吗?也是可以的,对于Web,你可以更具Web app的特点封装前进、后退、最大化窗口、最小化窗口、清除缓存等等Web框架级别的公用类,那么对于Android,你可以封装物理按键、安装卸载app、adb命令、拉取日志等等针对整个Android系统的公用类。注意我这里说的公用类不是说一个class,有可能是多个class组成的公用包,比如基于整个Android系统的公用包Common,你可以分装子类ADB、LogParser、HardButton(物理按键)等等多个子类,这些类构成整个android系统级别的自动化测试公用类,你的AO和PO模型中的类可以有这些类的对象引用,也可以继承这些更通用级别的公用类。
7. 工具层(Util)
在java app编码中我们可能会定义一些静态类或静态方法,这些静态代码扮演一个较常用的角色–工具。例如我们在JDBC编程中,对于加载数据库驱动的代码一般会写成静态,原因上面说过就是高消耗资源在系统中只用到一次就好,通常这种类我们会叫做DBUtil,类似还有FileUtil、ToastUtil。自动化框架中,我们也需要这样的类或方法,随时随地调用,比如建立一时间命令的测试报告文件夹,处理Excel表数据、获取DUT网络状态等等都需要封装成工具类或工具包。
8. 用例层(Cases)
终于到我们的用例层了,前面做了那么多工作,现在构想一下,我们写一条用例脚本是不是很方便,如下:
......
test_login_with_username_passwd();
self.driver.connect()
self.comon.start_logging()
self.start_app();
username = self.ExcelUtil.read_username()
passewd = self.ExcelUtil.read_passed()
result = self.login_page.login(username = username, passwd = passwd)
self.asserTrue(result)
self.comon.write_to_report()
self.comon.stop_logging()
self.driver.disconnect()
......
上面仅仅是伪代码级别的用例,大家可以体会一下,底层搭建好以后,case就是在调用API,组织业务过程,这就大大简化了自动化用例开发的流程,而且维护成本也大大降低。
好了,综上就是我对搭建自动化框架的一点浅见,希望博友批评指正,可能会有博友说,我的博客好多文字,没有实质性的代码,我会在后期抽时间写每个层次搭建中伪代码的编写的详细博客,也会努力建立github项目,到时候一起学习进步,谢谢广大博友的支持。