本自动化测试框架采用python + unittest 的基础来搭建,采用PO模式、数据驱动的思想,通过selenium来实现WEB UI自动化,通过request来实现接口自动化。移动终端的自动化也可在该框架基础上去构建补充。
总体框架如下图:

用例扫描、测试结果反馈,如要和其它项目管理系统或是用例管理系统对接(比如testlink),就需要单独出来进行处理。
对于大型的产品,用例数特别多的话,需要建设一个master节点,专门负责管理用例和脚本,分发测试脚本,指定测试环境,汇总测试结果等。各节点执行分给自己的测试用例即可。
PO模式(Page Object)是UI自动化测试常采用的一种设计模式,用于解决开发频繁修改UI页面而导致的自动化脚本维护困难的问题。
PO模式中心思想:
- 每一个页面为一个对象;
- 每一个对象维护着页面中的各元素和操作方法;
- 用例测试脚本只需要聚集业务逻辑和测试数据;
- UI页面的变更,只需要修改对应的PO对象,无需修改测试脚本(理想情况下。实际上也很难100%做到,因为UI的变更很多时候意味着业务逻辑的变更)。
DDT(Data Driven Testing)数据驱动测试模式,用来解决部分自动化用例逻辑完全相同,只有测试数据和预期结果不同的问题。实际上就是同一测试脚本使用不同的测试数据来反复执行(但脚本只需要写一个),测试数据和测试行为完全分离。
DDT中心思想:
- 将测试数据分离出来,单独维护;
- 减少重复自动化用例的数量。
将以上两种思想进行结合,就可以做成 对象、数据、业务行为 三者分离的模型,再结合模块进行管理,为后续自动化用例脚本的长期维护打下基础。否则时间一长自动化就会乱成一团,维护成本越来越高,陷入自动化率不升反降的怪圈。
关键字驱动(Keyword Driven Testing),在前面的基础上,可以进一步实现关键字驱动。即将业务逻辑相同的部分,抽象成关键字库。这样在写自动化用例脚本时,只需要写关键字和对应测试数据即可,可以进一步减少工作量,减少测试人员对代码的学习和依赖。
如京东搜索商品时直接写脚本需要好多步:
- 定位到搜索框
- 输入关键字
- 定位到搜索按钮
- 点击搜索按钮
- 定位结果列表
- 获取结果并返回
以关键字驱动的思想,即将这6步抽象出一个方法jd_search(),测试人员只需要写一句话就能完成以上所有动作获得结果。如:
大多数框架采用java语言或是python语言来实现,考虑到python容易掌握,各种库也比较全,所以采用python语言来实现。
python自动化框架最常用的有unittest和pytest,两者都可以,这里采用python自带的unittest。
对于WEB UI自动化测试,没有别的选择,基本都是采用selenium来驱动浏览器来完成。
对于接口自动化测试,可采用的办法较多,postman、jmeter都可以,但灵活性都不如直接采用python的request库。
数据驱动,由于unittest没有直接可用的dataprovider,采用常见的ddt来实现。
对于手机自动化,暂未实现,后续考虑加入,可采用appnium来实现。
测试数据,第1阶段采用excel管理,对于大型系统,建议直接采用数据库进行管理。
所以总的来讲,这个所谓的框架,就是东拼本凑,即没有新思想,也没有新技术,只是将一些常用的技术,按一定的思路组织起来、驱动起来而已。
总共执行6个用例,4个为京东搜索并抓取结果(WEB UI自动化测试),2个为百度翻译通用接口(接口自动化测试)。
各用例对应的定义方式(PO/DDT)
页面定义方式
PO对象定义:京东主页面定义了搜索框和搜索按钮,以name为关键字,定义元素定位方式和执行的动作。
测试数据定义方式:

API接口定义方式
直接采用大家接口测试时熟悉的json格式来定义。
对应的请求消息头headers等内容也可以定义在这里面。
主程序main.py
负责扫描用例,执行用例,并生成测试报告,发送邮件。

测试执行结果
3个脚本,每个脚本2条测试数据,共6个用例。运行main.py,执行测试,测试结果如下,3个失败的是故意修改了测试数据。

红线部分为接口测试时,自动比对的json差异,预期结果为“苹果”,实际结果为“期望值”。
测试报告邮件:

测试报告详情:

- 开发IDE: pycharm 安装指导
- python: python 3 安装指导
- 依赖库:anaconda 3(个人比较懒,懒得一个一个库的安装,这个库比较全) 安装指导
pycharm、python、anaconda三者的关系:添加链接描述
基本上都是直接上对应官网,下载安装。准备好了以后,直接开干。
pycharm上新建项目TestFrame,选择好存放目录,并在TestFrame项目下新建各模块。注意除了Log和Report是新建Directory外,其它的都是新建Python Package,因为下面还要放py文件的。
pycharm上切换项目的python环境为anaconda,File—>Settings—>Project下面切换,如下图:

1. 配置功能实现(Conf)
配置功能是项目的基础,所以先实现。在Conf目录下新建2个文件,分别为config.ini和config.py。
config.ini内容如下:
暂时先加这么多,后续需要再慢慢添加。
config.py文件实现config.ini文件的读取。
ini文件读取,python有ConfigParser库可以使用,那就直接用。
ConfigParser库传送门
运行结果:
后续其它文件就可以直接使用 sys_cfg 和 smtp_cfg 这两个字典,以key的方式访问需要的配置内容。
2. 日志功能实现(Log)
先去我们的配置文件中config.ini添加日志相关的配置,这里先定义3个配置:日志级别、日志格式、日志路径。
再在config.py中最后面添加一行代码,把log相关的配置放在一个变量中,好直接使用。
打印出来看一下结果:
再接着在Comm目录下,新建一个Log.py,开始定制日志。定制日志还有几个问题要提前考虑:
一是存放目录问题,我们这里使用了固定目录,所以问题不大。
二是日志分割、滚动问题,每天跑持续集成,大量用例生成大量日志,日志堆成山。如果觉得日志有用呢,就搞个ELK把日志取走存放起来做分析。如果觉得日志没用呢,保存几天后就删除掉。无论怎么讲,都要实现日志的分割和滚动。
幸好你想到的大佬们早就想到了,logging模块就有这个功能,只要配置一下就可以了。
下面开搞,引入logging库,把项目的根路径取出来,把上面config.ini中的日志配置取过来,最后拼接好日志文件存放的绝对路径:
注意上面log_level的写法,这里用了个eval,如果不加这个函数,log_level取过来是个字符串,没法直接用,通过eval执行后,就变成了logging定义的对象了。
再配置日志,引入TimedRotatingFileHandler这个东东,这是实现滚动日志的。
日志就做好了,试一下效果。
运行结果:
其它文件使用日志:
先在main.py里面引入这个log_init(),在最开始的时候初始化一下,日志就配置好了。
再在各个要使用日志的文件中,直接按下面这种方式使用:
注意各个模块自己getLogger的时候,直接main后面加上“.模块名”,就能使用同一个logger区分模块了。
到这里日志功能就完成了。
顺手做个截图的功能,供大家使用。截图可以直接在用例里面用selenium提供的截图功能,也可以自己做一个公共的。下面是用PIL里面的功能做的截图。
运行这个方法就能截图了,大功告成。截图文件其实也需要一个滚动删除,后面有时间再写吧。
3. 读取EXCEL实现(data)
接着写一个读取EXCEL文件数据的功能吧,这个项目里面主要是用来读测试数据,以实现数据驱动。
python读取excel数据,我看大家都喜欢用xlrd和xlwt,还有用openpyxl的,对于我这种懒人来讲,都太麻烦了。
我们用pandas来干,一句话的事情,搞那么多干吗,用python就是要快。
在Comm目录下,新建一个data.py,专门来处理数据。引入pandas,直接用pandas的read_excel读excel,而且支持它原始的其它参数,只是最后将结果转了字典,方便使用:
随便放一个excel在同一个目录下,填上数据,试一下效果。excel里面2页数据,Sheet1如下:

Sheet2如下:

调用我们写好的方法,打印数据:
运行结果如下:
每页数据都读出来了,而且每一行都是字典形式,直接通过key就可以方便的使用。
pandas还能直接计算数据,如通过几个列算加密签名,写动态cookie等,使用方法也很简单。比如在数据中增加一列sign, 让它简单等于 req.from列 + ‘.aaaa.’ + req.to列,给大家演示一下。
运行结果:
我们可以看到多了一列sign,值就是自动根据每一行的数据算出来的,这对于我们数据驱动来讲,去计算一些动态值非常有用。我这里没有用到动态的,只是读而已。大家如果要计算,就要自己写计算方法。
pandas还支持直接读各种主流数据库,后面扩展也很方便,我们一直都用它。
4. 邮件发送实现(Email)
实现邮件功能,用于发送测试报告。使用python的smtplib模块实现。
先在Conf目录下的config.ini中添加好邮件相关的配置:
再在Config.py中将它们取到变量中放好:
然后在Comm目录下新建Email.py,开始撸代码。邮件支持了定义主题、正文和多个附件,控制了单个附件大小和附件总数。代码如下:
邮件初始化发送时的调用方式如下:
返回结果为True则发送成功,否则发送失败。
我们以京东搜索爬虫为例来看如何构建这三者的关系:在京东主页面,搜索“电脑”,再获取搜索结果,保存。
1. 页面PO对象配置
name: 每个元素+操作的唯一标识。一个元素可能由于操作不同,而要定义多个,但大部分只要定义一个。
desc:元素+操作的描述。
by:元素的定位方式,使用selenium的原生定位方式,不自己定义封装。
ec: 等待元素出现的方式,这个暂时未用。
action:元素的对应操作。使用原生的selenium动作方法,不自己定义封装。
京东商城主页面现在只用到这两个,就只定义这两个。
搜索结果页面,定义如下:
2. 实现basePage基类
basePage基类的实现思想是不做过多的封装,尽量让测试人员直接使用selenium原装的方法,而不像其它框架一样什么都封装在这里面。
所以我对basePage的定义是:根据业务逻辑(测试用例)指定的元素,输入的数据,协助它完成元素定位和操作,仅此而已。
当然如果去封装各种东西也是可以的,直接在里面加就行了。
在Page目录下,新建basePage.py,开始撸代码:
这里面主要的只包含3个方法,一个是动态加载指定的PO对象获取元素列表,一个是在获取的元素列表中去找到当前要操作的元素,最后一个就是拼接原生的selenium命令,将测试数据插入到动作里面去。
其它的就简单了,直接调用selenium运行拼接出来的命令,把结果返回出去。
这里要注意的是,有些复杂的selenium操作,不能这么简单的拼命令,要特殊处理,这里暂时没弄;简单的命令,也没有列全。后面再慢慢加。
3. 写业务测试用例
下面开始写测试用例。
在Testcase目录下,新建一个python package:Model1。在Model1下面再建一个目录:Testdata,用于放测试数据;建一个python package:Case,用于放用例脚本。目录结构如下:

准备测试数据:
准备一份excel数据(test_jd_desktop.xlsx),存放在Model1/Testdata/jd下:

keyword:搜索的关键字
count:搜索结果总数,只抓了一页,应该是60个
实现业务用例:
在Model1/Case/jd下新建一个文件:test_jd_desktop.py,开始写用例脚本。
用例使用unittest结合DDT来实现,具体代码如下:
主程序的主要作用是 组织用例,执行用例,生成报告,发送测试报告邮件。
组织用例和执行用例都直接用unittest;
生成报告,采用BeautifulReport;
下面开始撸main.py的代码:
运行主程序,就可以把WEB UI自动化跑起来了。
1. API对象配置
2.实现base_api基类
这里面的思路是:
- 动态加载API对象,获取API请求参数模板、和响应参数模板;
- payload的时候,从测试数据中,取出API请求相关的数据(以API名.req开头,如fanyi.req.q),填入模板,没有的就用模板数据;
- 加载预期结果的时候,从测试数据中,取出API响应相关的数据(以API名.res开头,如fanyi.res.trans_result.0.src),填入模板,没有的就用模板数据。
- 提供json比较的方法;
- 提供了一个随机handers。
具体的大家看一下就明白了。想进一步封装的还可以继续封装,比如生成hearders,数据配完了直接发送,取到结果直接比对什么的。但是建议不要过度封装。
附json比较的方法:
3.测试用例
在Testcase下建API模块,API模块下建Case和Testdata,分别放用例和数据,目录如下:

定义测试数据:
测试数据需要按一定的格式处理,即每个参数以api名称开头,用“.”连接,然后用res和req来区分响应还是请求,后面就是具体的参数了,多级参数以“.”连接。具体如下:

测试用例脚本:
仍然用unittest和ddt来实现。
然后运行主程序,API自动化测试也就可以跑起来了。
很多人求源码,源码早已上传,链接没放在这里而已。
古人云:书非借不能读也,公开的源码大家必高束焉,不会用心揣摩,于自身没有益处。放这里前,特意改成收费的,有心者得之。
代码链接地址:https://download.csdn.net/download/sunjice/
未完待续…
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/9225.html