11

Python从无到有搭建接口(API)自动化测试框架

 3 years ago
source link: https://blog.csdn.net/weixin_40331132/article/details/111572517
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Python从无到有搭建接口(API)自动化测试框架

目录

1、前言

2、思路    

3、正文

一、路径模块-initPath.py

二、配置文件模块-getConfig.py

三、读取用例模块-getCase.py

四、数据库操作模块-operatorDB.py

五、日志模块-log.py

六、邮件模块-sendEmail.py

七、消息模块-sendMsg.py

八、变量参数化模块-parameteriZation.py

九、API请求模块-sendApirequests.py

十、公共方法的模块(核心)-commKeyword.py

十一、工厂封装(核心)-methodFactoy.py

十二、解析用例(核心)-testCase.py

十三、最后的运行文件-testRun.py


         自动化测试,是测试道路上不可或缺的重要部分,现在有很多自动测试工具,基本可以满足软件市场的测试要求,但使用工具让人知其然而不知其所以然,学会了也只是一个自动化测试工具人,所以学会自动化框架,是摆脱工具人、提升自己、加薪升职的必经之路;

         天王刘德华说:学到了要教人。

         这是一个已经学会了的人分享的一点知识,希望测试同胞们在前进路上路过我这篇博客时,如得感觉有一点点的帮助,请留下您的一个赞。

         观看此文时,需要有入门级的Python代码基础,如没有,请先去找视频教程学习一段时间。

         本文所有讲解代码与执行结果用截图展示,这为了是让您看着可以有个写代码的过程,提升自己;当然如果不想写,也可以只接跳转每一小节末尾,整体代码展示,可以"使用程序员高阶技能ctrl+c, ctrl+v"自行学习。

       1、搭建一个目录框架

            common目录里内容含义

setApirequest.py  实现API接口请求的模块,实现发送post/get等方法;

             getCase.py  实现读取data目录里的用例文件数据的,设计执行格式,输出JSON用例集;

             getConfig.py 实现读取config目录下的配置文件;

             initPath.py  实现获取框架文件路径,方便其他模块使用目录方法;

             log.py  实现日志打印统一入口,将文件输出到log目录里;

             operatorDB.py  实现读写数据的方法;

             parameteriZation.py  实现数据参数化的实体类;

             sendEmail.py\ SendMsg.py  实现实时发送测试报告至邮件与企业微信的方法;

            kemel目录里内容含义

             methodFactory.py 实现各方法调用的统一入口;

             commKeyworl.py 公共方法、主要是分装所有底层模块的操作入口,并提供一些特殊性的公共方法;

            testcase目录里内容含义

             图片里目录中没有添加文件。应该是这个文件tsetCase.py,实现解析getCase.py里输出的JSON用例集,执行用例的,检查执行结果的模块,因为Unitest库的要求,此用例解析目录与文件必须以test开头,当然含义也见名思义。

           其他目录 

            data用例文件目录,log输出日志目录、report输出测试报告目录,library引入三方模块目录(ddt数据驱动模块,HTMLRunner测试报告格式化输出模块)

             library引入两个三方库的下载路径(重要文件,不或或缺):

             ddt:https://download.csdn.net/download/weixin_40331132/14022116

             HTMLRunner:   https://download.csdn.net/download/weixin_40331132/14022157

       5、分层概念

           一个软件MCV的层次概念

            M是底层,模型层,前面封装的代码都是这种模块,属于底层代码 。

            C是中层,控制层,封装所有底层的接入方法。

            V是高层,会话层,界面也操作提供给用户使用。

           MVC的区分(分层概念)

           common目录下的模块都是M

           kemel目录下的模块是C

           test_Case.py, testRun.py等运行模块是V

一、路径模块-initPath.py

       1、了解如何获取当前绝对路径:

             先了解python是如何取得当前目录的,我们可以使用内置库os来实现

             首先我们得知道 __file__在python中代表当前文件,

             然后在菜鸟教程里找到os.path的库,知道获取绝对路径的方法 os.path.abspath(path)

             然后开始在initPath.py写代码打印一下os.path.abspath(__file__)方法

             见下图,打印出了initPath.py的绝对路径。

        2、获取文件路径,不包含本身文件名

              在菜鸟找到了os.path,dirname()方法

              在initPath.py里使用打印一下这个方法,然后我们希望是\的路径,所以使用os.path.dirname(os.path.abspath(__file__))这个代码取路径

              然后我们再增加一层,os.path.dirname(os.path.dirname(os.path.abspath(__file__))),我们是要获取工程根目录路径的。如下图

        3、拼接所有路径

              我们要拼接目录,需要一个方法,进入菜鸟网,找到os.path.join(path1, path2),合成路径方法

             直接写initPath.py的代码了,将项目下所有文件夹的路径都定义好了。打印如下图

             initPath.py的代码段

二、配置文件模块-getConfig.py

        1、我们先了解一下配置文件

              在计算机领域,配置文件:是一种计算机文件,可以为一些计算机程序配置参数和初始设置。

              具体文件类型与相关知识点不多说,我们这里使用一ini配置文件,内容格式如下

             [about]

             aaa = bbb

             ccc = ddd

             其实about是节点,aaa = bbb是参数,key = value的意思

             所以在config/baseCon.ini下配置添加一些配置,如下图

         2、读取baseCon.ini里的配置项

              获取配置文件路径:

              读取配置文件之前,我们得先得到文件baseCon.ini的绝对路径,

              先引用已经定义好的config的绝对路径,然后使用os.path.join(path1, path2)方法将baseCon.ini的绝对路径生成,具体代码如下图

             了解configparser

              ConfigParser 是用来读取配置文件的包。三方库,所以需要通过命令 pip install configparser 来下载。

              在代码里直接导入ConfigParser类,然后创建其对像,调用方法read(),读取配置文件,具体代码如下图

               仔细学习上面的路子,下面就开始着手封装configparser了,这个库已经很完美了,不过我们后续读取配置文件时需要将读取文件这个步骤也省略,所以稍加封装。

               封装configparser配置文件读取

               封装的代码运行如下图

             nyCof.saveData()方法添加了配置项,写到了baseCon.ini里面

            getConfig.py的代码段:

三、读取用例模块-getCase.py

          读取用例是框架的比较重要,与独立的模块,不过读取用例前,我们先要设计用例文件与用户格式,一般我们可以将用例放在excel里,或者建立一个mysql数据库,将excel里的数据导入到里面,但后者比较麻烦,所以本文只接读取excel文件里的用例

         1、设计用例文件与用例格式

              在data目录里新增一个testcase.xlsx的excel文件,目录如下图:

              打开testcase.xlsx,在sheet1里设计用例表头,如下图:

             用例字段的含义:

              case_id:id,自己设定数字,只为了输出报告时识别用例的位置

              api:url里的接口路由,也是为了输出报告时识别用例的正确性

              title: 可以是用例的中文标题,也可以自定义方法中参数化接收数据的变量,格式可以是,abc或${abc}

              method: 请求类型 post/get ,或者自定义的方法名称

              url: 接口请求中的url,可以被参数化

              headers: 接口请求中的headers, 可以被参数化

              data:  接口请求中的data, 可以被参数化

              checkey:用例检查点的检查方法

              expected:  用例检查点的检查值

              Test_result:  用例执行完成后,回写给用例的状态,pass/fail,不过我一般不用。

             用例示例如下图:

         2、设计用例集JSON格式 

               格式如下:

                    根据用例excel文件,具体的JSON用例串应该下面是这样子的,前面字段是excel列表数据,最后一个是sheet_name是表示了sheet页名称。一般接口用例按模块编写,一个模块一个sheet页,以此字段区分,为后面输出测试报告做准备。

            'case_id':1,

            'api': 'publickey',

             'title':'url',

             'method':'设置变量',

             'url':'https://www.adbcde.com.cn/',

             'headers':'Host:www.adbcde.com.cn',

             'data':'userToken=16029513602050&loginpassword=qwert12345&loginphone=15361828291',

             'checkey':'结果包含',

             'expected':'"return_code": "SUCCESS"',

             'Test result':None,

'sheet_name':'sheet1',

          ......

.....

         3、openpyxl库学习

               读写excel的库有很多,因为用例要求不高,所以选择openpyxl库来封装用例代码

               安装使用命令 pip install openpyxl

               开始写代码

               操作excel用例之前,要得到文件的绝对路径

               获取绝对路径成功,接下来开始读取excel里的文件了,

               读取excel文件内容

                步聚如下图,1、先打开excel文件,2、遍历一下sheet页输出名称,3遍历输出Sheet1里的数据,这三个写后,就表名,excel可以读取成功了。openpyxl也学完了

             4、封装用例类

                  我定义的用例是一个excel文件一个项目,在工作中,应该不止一个项目,所以有可能在data目录里有多个excel文件,我们需要执行哪个呢,所以此能用到前面写的配置文件,在里面加一个case节点,增加执行用例文件名称

                  一个用例文件中肯定有很多注释的用例,所以定义一个 # 来区分注释用例。两个定义如下图

                      封装代码无法载图全部,先看执行结果,后面读取用例只需要两行代码就可将用例JSON读取出来

                     getCase.py的代码段

四、数据库操作模块-operatorDB.py

         1、pymysql安装

               安装pymysql使用命令pip install pymysql

         2、pymysql学习

               学习之前,我们先把连接数据库的相关配置参数,在配置文件中取出来

               如下图,先导入myCof对像,使用getValue取出对应该的配置参数打印成功

               pymysql已经导入成功了,连接数据参数也取出来了,接下来开始连接数据,执行SQL语句

               连接数据库

               如果没连接成功会抛出异常,所以此时需要 try ... except.....来catch异常,打印出来,下图为连接数据库超时,因为还没起Mysql的服务。

                这里我们得先配置好一个mysql服务器,方便调试,不懂的可以在网上找教程学习学习,当然直接用公司的测试环境也行,省时少力。

               打开mysql服务后,运行,会报一个错,我们将port参数强转化为int类型,他不能为str类型。

               强转后,再运行一次,连接成功了

               执行SQL

               执行SQL语句,我们需要游标,先获取游标,再使用游标执行SQL,一次通过

               打印SQL查询的数据

               pymysql学习完成,接下来可以封装了

         3、封装数据操作

               封装的逻辑是,将连接作一个方法,执行SQL写一个方法,关闭连接写一个方法

               先看封装好后的执行结果,只需要写四行代码就可以执行SQL语句了。

                opeartorDB.py的代码段:

五、日志模块-log.py

         1、logging学习

               logging是python的基础库,不需要下载,直接导入可用

               日志有五个等级,自动测试一般INFO等都打印,所以我们在配置文件里的加上日志参数配置

                [log]

                level = INFO

               打印日志

               编写代码,先获取日志等级配置,然后设置日志等级,初始化日志对像,打印日志,因为日志等是INFO,所以debug的日志不会打印,代码如下图

               设置日志格式

格式设置如下图

                将日志输出到文件

                日志文件存放在log目录下,所以先获取导入目录与os

                设计日志文件隔一天时间,日志就另新增一个,保留十五天,所以需要导入logging里的一个方法TimedRotatingFileHandler、

from logging.handlers import TimedRotatingFileHandler  #导入的方法

                 代码如下图

                运行后,输出了testReport文件,里面打印了执行日志

                logging基本学习完成 ,再简单封装一下

         2、日志模块封装

               封装日志这一块,不需要创建对像,因为他本身需要返回一个logging的对象,对象操作对象,别扭,所以在Log类里直接封装一个静态的方法,可以直接类调用方法返回一个logging对象。

               调式执行结果与上面一致,但不截图了,直接上代码

               log.py代码段

六、邮件模块-sendEmail.py

          1、开启邮箱的SMTP服务

                email邮箱提供商都可以开启smtp服务的,如果知道什么是smtp并知道设置的朋友可以略过这一段

               以qq邮箱为例

               进入qqmail.com登录邮箱,找到【设置】-【账户】,点击POP3/SMTP 开启(下图标记的有误,别被误导了哈)

               按描述发送短信

               开启之后,我们会得到一个密钥,好好保存,

          2、学习使用smtplib库发送带附件的邮件

               邮件参数添加到配置文件

               host 是邮件服务器,腾讯的是smtp.qq.com,  

               port 是邮件服务器端口,开通smtp时,腾讯会邮件告之端口号

               user是邮箱、pwd是开通smtp时得到的密钥

               from_addr 是发送邮箱地址,与user是同一个

               to_addr是收件箱,可以做成逗号分隔

                   连接smtp服务器

                   一般连接啥服务器没成功都会抛异常呀,所以用一下try,新建一个smtplib的对像,带上服务器与端口,然后使用用户名密码连接  

                    发送邮件

                    发送邮件之前需要构建一个邮件内容,所以所以email库,可以通过pip install email下载,使用

                    先构建一个纯文本的内容 ,所以导入 MIMEText,

                    下面是构建邮件内容与发送成功的截图,msg消息休是邮件内容 ,里面需要文本,发送人,收件人,邮件主题等参数

                    发送成功后,进入邮箱查看邮件

               邮件发送成功后了,基础的已经学会了,还有两种邮件类型、MIMEMultipart多媒体内型,MIMEApplication附件内型,不多赘述,看后面封装代码即可通明

          3、封装代码

                封装代码前呢,先知道了一般的自动化报告是html格式的,这里我拿了以前的测试放在工程report目录下,方便使用,如下图

                封装邮件模块后,两行代码即可发送测试报告。

                sendEmail.py的代码段

七、消息模块-sendMsg.py

          1、创建企业微信应用           

               在企业微信建立一个应用,为接收消息的载体,添加相关人员

               在Python中实现得到企业微信应用token,

               在企业微信官网创建一个公司,或者用公司的企业微信号,获取企业微信的企业ID

              创建应用

               得到AgentId、Secret

               进入新建的应用详情页面,可以得到这两个字段

       1、学习发送企业微信消息

             资深开发者直接会找企业微信的API开发指南,应该知道怎么封装了。

              先将创建应该时得到的三个参数配置到baseCon.ini文件里

             获取企业微信的token

拼接得获取token的API url,corpid与corpsecret字段为参数,用requests.get()方法请求,从结果集中解析出token字段值

                发送消息

发送消息的代码如下图,先拼接发送消息的api的url,需要添加上面得到token值,再构造一个消息,转换成bytes格式的消息休,使用requests.post发送消息

企业微信收到了消息,如下图

       2、代码封装

            封装完成后,只需要两行代码就可以发送消息了

           sendMsg.py的代码段

八、变量参数化模块-parameteriZation.py

                前面七小节已经将自动化测试框架的周边全部弄完了,接下来便开始写核心模块了。

                自动化测试工具有很多变量可以配置,分为两大类,系统环境变量(在执行之前,人为配置好的变量,执行完还存在),临时变量(在执行过程参数化的变量,执行完成消失,等待下次参数化)

          1、系统环境变量

  这个很简单 ,我们直接写在配置文件即可,比如我们需要一个账号与密码,将其设置为系统环境变量,直接在bascCon.ini里添加

                然后我们导入 myCon,使用getValue方法就可以取到变量的参数了,

               这还是第一步,我们需要设计变量的格式,比如 {aaa}, ${aaa},前者使用{}来标识aaa需要参数化,后者用${}来标识aaa需要参数化,

               那就将${}定义为变量的标识符

               取变量名

               那么我们将如何来取变量名呢,比如,${phone},直接使用是取不到手机号码的,需要将phone取出来。此时我们可以使用正则表达式库,re来处理

               正则表达式很强大,规则也很多,在这里不做赘述。re的话是Python的基础库,所以可以在菜鸟站上搜索到教程,我们要用到的方法就这两个

               代码如下与执行结果见下图

               将变量参数化   

               就是在上面代码里加上获取配置参数即可,代码与执行结果见下图:变量已经参数化了。

           2、临时变量

                 临时变量,这是个检验Python代码基础的活儿,面向对象,属性,setattr  ,getattr等知识点。如果懂了我们只需要在上加几行代码就成了。

                先定义一个空类。不给属性与方法,在执行代码的过程中使用setattr给这个空类添加属性与值,这个属性即 临时变量,如果想调用,即可用getattr取属性的值,进行参数化

               代码如下与执行结果如下

              临时变量参数化

设置好临时变量,参数化过程与系统环境变量的差不多,区别是将myCon.getValue(‘par’,  key)  改成getattr(Paramte, key)

           代码与执行结果如下图:

          3、代码封装

                parameteriZation.py的代码段

九、API请求模块-sendApirequests.py

       1、requests库下载

            第三方库,所以需要用命令:pip install requests   下载

       2、requests库学习

            requests的请求类型

常用的请求类型都在下图

            目前主要的请求是get与post

             requests.get(url=‘请求api的url’, params=‘get请求的参数,可以为空’, headers=‘请求头,如果接口没有校验,可以为空’)

             requests.post(url=‘请求api的url’, json=‘如果json参数,使用json字段’, data=‘如果是表单格式,使用data参数’, files=‘当数据为文件时,使用file参数’, headers=‘请求头,如果接口没有校验,可以为空’)

              post里的可以传json、data、file三种参数,但三个只能传一个。

       3、api请求封装

            sendApirequest.py代码段

            这个文件在kemel目录下面

             封装代码调用-get

             封装代码调用-post

十、公共方法的模块(核心)-commKeyword.py

      1、公共方法理念

            一个软件MCV的层次概念

            M是底层,模型层,前面封装的代码都是这种模块,属于底层代码 。

            C是中层,控制层,封装所有底层的接入方法。

            V是高层,会话层,界面也操作提供给用户使用。

           MVC的区分(分层概念)

           common目录下的模块都是M

           kemel目录下的模块是C

           解析用例与运行文件是V

           公共方法、主要是分装所有底层模块的操作入口,并提供一些特殊性的公共方法

            什么是特殊的公共方法呢?

             比如:自动生成手机号码、自动生成身份证号码,自动生成随机字符串,自动生成全国各地区号,设置变量、拆分字段,获取字符串中的指定字段等等。

      2、封装

            封装完成公共方法,会与后面的工厂结合起来使用

           commKeyword.py的代码段

十一、工厂封装(核心)-methodFactoy.py

       1、工厂的逻辑

             工厂是公共方法调用入口。

             有人传入关键的文字,而工厂会找到关键文字对应的公共方法,执行方法得到结果,最后返回给调用工厂的人。

             那我们如何通过文字找方法呢?

             需要用到配置文件,我们在配置文件将前面小节封装的公共方法逐一配置好,

             格式:文字=方法名称

             代码实现,先通过配置文件得到公共方法的名称 ,然后使用getattr方法在公共模块对象上找到公共方法,然后执行方法,可以得到想要的结果。

             如下图

       2、封装

            methodFactory.py的代码段

十二、解析用例(核心)-testCase.py

       1、详情讲解

            python 自动了一个单元测试框架unittest,用来做自动化测试是绝好的。

           先引用一段理论:

--------------------------------------------

做过自动化测试的同学应该都知道python中的unittest框架,它是python自带的一套测试框架,学习起来也相对较容易,unittest框架最核心的四个概念:

​  test case:就是我们的测试用例,unittest中提供了一个基本类TestCase,可以用来创建新的测试用例,一个TestCase的实例就是一个测试用例;unittest中测试用例方法都是以test开头的,且执行顺序会按照方法名的ASCII值排序。

​  test fixure:测试夹具,用于测试用例环境的搭建和销毁。即用例测试前准备环境的搭建(SetUp前置条件),测试后环境的还原(TearDown后置条件),比如测试前需要登录获取token等就是测试用例需要的环境,运行完后执行下一个用例前需要还原环境,以免影响下一条用例的测试结果。

​  test suite:测试套件,用来把需要一起执行的测试用例集中放到一块执行,相当于一个篮子。我们可以使用TestLoader来加载测试用例到测试套件中。

​  test runner:用来执行测试用例的,并返回测试用例的执行结果。它还可以用图形或者文本接口,把返回的测试结果更形象的展现出来,如:HTMLTestRunner。

--------------------------------------------

           自动化测试流程:是基于unittest中TestCase + ddt data 模式成自动化用例集(俗称数据驱动)。而后被unittest中的test suite套件将用例集中管理起来,最后使用unittest中的test runner将集中起来的用例执行,生成测试报告

            解析用例。就是数据驱动这一段。已经封装好在testCase.py中了可以自行看代码与注释学习

       2、封装

            testCase.py代码段

十三、最后的运行文件-testRun.py

        1、代码封装

             testRun.py代码段

            写完这个文件的代码,再然后按照第三小节的   ’读取用例模块-getCase.py‘ 里面的规则设计测试用例,然后放支data文件目录里,将配置文件里的用例文件名称配置好,然后执行自动化测试了

            执行后的测试报告如下:

              做测试的,语言组织能力不太在行,希望大家能看的懂,等哪天开心,会公开源码,希望诸位给个小赞。谢谢!!! 


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK