接口自动化测试流程和相关准备工作

第一步: 拿到需求文档、UI交互图(原型图)、数据库表设计文档、接口文档

1问:为什么要拿到这些文档资料呢?

1答:

①.《需求文档》,明确定义了:各个表单字段的限制条件;相关场景逻辑校验;

②.《UI交互图》,明确定义了:各单页面需展示的数据;页面之间的交互;

③.《数据表设计文档》,结合UI图和需求文档,明确定义了:表字段规则、表N多N关系(一对一、一对多、多对多);

④.《接口文档》,结合需求文档和UI和数据表,明确定义了:接口名,各个入参值,各个返回值,和其他相关信息;

2细节:

①.大多数公司,针对这四类文档资料都整理的不规范,或者没能及时更新;

②.这会导致接口测试用例的编写没有一个绝对可靠的需求来源;

③.因为,接口测试用例本质是针对各个表字段的校验;

④.所以需求文档里对各个表单字段的限制条件,产品人员务必都要写清楚,不要遗漏限制条件;

⑤.而接口文档里针对各个用例场景的返回值,文档里务必都要及时填写和更新;

⑥.针对接口文档返回值的字段:比如code=0表示登录成功,code=1表示密码错误;code=2表示无网络;code=3表示账号错误,等等类似code值有不同含义;

3注意:

①.所以,在写接口测试用例之前,务必要先核对需求文档和接口文档,以最正确的需求文档和接口文档,来编写接口用例,才能得到最正确的结果;

②.先实现单接口解耦;后续按照业务场景组合多个接口;

第二步: 拿到个人编写的接口用例模板,针对特定单接口编写接口用例

1重点:要及时更新接口用例模板.xlsx,保证用例模板的准确性;

2假设有一个后台系统banner广告位子模块,以特定单接口-createBanner-新增banner,来讲解编写单接口的接口用例的操作流程:

(1)新建一个xlsx后缀的excel文档,excel名改为:banner.xlsx

(2)打开banner.xlsx,第一个sheet页名称改为:创建banner

(3)打开接口用例模板.xlsx,把名称为【接口测试demo】的sheet页里的所有内容复制到banner.xlsx的名称为【创建banner】的空sheet页;

(4)在名称为【创建banner】的sheet页里,做如下步骤的操作:

(4-1)针对第一行各单元格数据(第一行各单元格是用来填写相关参数名和用于标识的参数名):

①按照实际需求来灵活配置:操作入参名所在的单元格;操作返回参数名所在的单元格;

入参名都用红色字体表示;返回参数名都用绿色字体表示;

比如:修改某个入参名,删除多余的一个入参名所在的一个列,新增一个列来填写一个新的入参名;

比如:修改某个返回参数名,删除多余的一个返回参数名所在的一个列,新增一个列来填写一个新的返回参数名;

②跟入参名跟返回参数名所在的单元格无关的单元格,都保持原位置和原单元格名称即可。

( 当然也支持任意移动位置和更改单元格名,但不建议更改单元格名因为更改了单元格名后代码也要跟着变动)

(4-2)针对第二行各单元格数据(第二行各单元格是用来填写默认值):

①单元格【验证字段】的值:不填,为空;

②单元格【接口地址】的默认值值是接口相对路径,结合实际情况比如更改为:/api/b.banner/creBanner,用于拼接该接口请求的绝对路径;

③单元格【请求方式】的默认值值是请求方式,结合实际情况比如更改为:post;

④单元格【编号】的值:不填,为空;

⑤单元格【返回值和断言结果的所在行下标】的值:不填,为空;

⑥单元格【用例类型】的值:不填,为空;

⑦单元格【用例目的】的值:不填,为空;

⑧单元格【用例名】的值:不填,为空;

⑨单元格【返回值】的值:不填,为空;

⑩单元格【断言结果】的值:不填,为空;

细节1:如果入参名所在的单元格和返回参数名所在的单元格,单元格值可以重复且出现频率高,那就可以填写默认值;

细节2:如果入参名所在的单元格和返回参数名所在的单元格,单元格值不可以重复只能是唯一值,那就单元格值为空;

(4-3)针对第三行及大于第三行的各单元格数据(用于填写具体值):

结合接口用例模板.xlsx的名为【接口测试用例模板】sheet页称为A,在banner.xlsx的名为【创建banner】sheet页称为B,进行灵活填写;

操作步骤:

①针对某个接口字段,复制A的三列数据【用例类型】【用例目的】【示范的用例名】,复制给B的三列数据【用例类型】【用例目的】【用例名】;

②然后删除不需要的用例名对应的行数据;

③更改各条剩下的用例名,比如更改字段名和相关数字等数据;(基本99%都要替换掉从模板复制过来的数据);

④B的这列数据【接口地址】,务必都填写DF;

⑤B的这列数据【请求方式】,务必都填写DF;

⑥B的这列数据【编号】,务必都填写文本形式的数字且数字递增,值从01开始(文本形式的数字可以再excel里设置);

⑦B的这列数据【返回值和断言结果的所在行下标】,务必都填写数字且数字递增,值从2开始;

⑧B的这列数据【验证字段】,灵活按照实际入参名来填写;

⑨B的两列数据【code】【data】都务必结合接口文档和需求文档,填写正确的值;(若哪些值觉得不合理,后期可以让产品或开发人员进行修改);

⑩B的两列数据【code】【msg】都务必结合接口文档和需求文档,填写正确的值;(若哪些值觉得不合理,后期可以让产品或开发人员进行修改);

细节1:DF表示默认值,取值于第二行各自的单元格值(在脚本里有做相关转化和校验);

细节2:&$,表示一个变量,由脚本内部赋值。比如: variable = {"${count}": 666} ;

细节3:B的两列数据【返回值】【断言结果】都默认不填写,这两列数据都是由相关脚本返回的值;

细节4: 相关颜色的标注,可结合实际来灵活填写;

细节5: 列数据【data】和列数据【msg】不可能同时有值;

细节6:待补充列表字段【预期值】,把【code】+【data】&【code】+【msg】这样组合为一个dict,回传写入【banner(包含接口返回值和断言结果).xlsx】;

第三步: 结合项目框架,做相关流程的脚本操作

(1)第一,执行必须操作的步骤(按项目二级目录的排序顺序来执行)

1. 在二级模块名【/data】内:编写脚本d_add_banner.py; (在子类D_add_banner的父类属性variable可结合banner.xlsx内的接口用例赋值情况,来重写该variable属性值;)

2. 在二级模块名【/excel】内:存放banner.xlsx;

3.在二级模块名【/expectedResult】内:编写脚本e_add_banner ; (第一次编写子类E_add_banner时,直接继承且不重写任何一个父类方法;调试期间,可按照实际重写父类相关方法;);

4. 在二级模块名【/model】内:编写脚本m_add_banner.py; (第一次编写子类M_add_banner.py时,直接继承且不重写任何一个父类方法;调试期间,可按照实际重写父类相关方法;)

5. 在二级模块名【/optimize】内:编写脚本o_add_banner.py; (第一次编写子类O_add_banner.py时,直接继承且不重写父类的sleep方法;调试期间,可按照实际重写父类的sleep方法;)

6. 在二级模块名【/validate】内:编写脚本v_add_banner.py;(第一次编写子类V_add_banner.py时,直接继承且不重写父类的compareResult方法;调试期间,可按照实际重写父类的compareResult方法;)

7. 在二级模块名【/writeCellValue】内:编写脚本w_add_banner.py;

细节:各步骤对应的类都相对解耦,数据源基本都来自同个上游接口--d_add_banner.py内的子类D_add_banner所调用的父类方法excel_data()的返回值;

(2)第二,再执行非必须操作的步骤(按项目二级目录的排序顺序来执行)

1. 在二级模块名【/fileAttribute】内:编写脚本f_add_banner.py;

2. 在二级模块名【/public】内:存放图片视频等相关测试数据;

(3)第三,针对单接口createBanner,调试接口请求

1. 在二级模块名【/controller】内:编写脚本c_add_banner.py; (第一次编写C_add_banner.py时,务必对某个特定的父类方法进行重写,比如:父类方法add,父类方法update;)

细节1: 相关入参值都采取参数化;

细节2:在【if __name__ == ‘__main__‘:】下方区域,进行单元测试的调试;

细节3:用于调试的数据源data,可以在【d_add_banner.py内的子类D_add_banner所调用的父类方法excel_data()的返回值】这边获取,获取符合要求的其中一条数据来当做数据源;

(4)第四,针对单接口createBanner,结合ddt,遍历执行所有的接口测试用例

1. 在二级模块名【/testcase】内:编写脚本test_001_add_banner_testcase.py;

细节1:可直接复制其余现成的脚本,用ctrl+R快捷键统一替换相关关键字;

细节2:针对不同接口,脚本需增加/减少特定的代码;(比如【修改】接口可能比【新增接口】需要多调用sleep方法,防止程序执行过快导致接口请求异常返回报错信息)

细节3:成功执行该脚本后,会在二级模块名【/excel】里生成对应的【banner(包含接口返回值和断言结果).xlsx】,会包含每条接口用例的返回值和断言结果;

(5)第五,核对生成的数据

1. 查看【banner(包含接口返回值和断言结果).xlsx-【创建banner】sheet页的 返回值和断言结果】,大概看一下返回值的数据是否正确;如果有错误的返回值,则继续排查和优化相关脚本;

(6)第六,执行单一入口函数

步骤:

1.配置根目录run.py相关参数信息;

2.执行run.py

3.生成html格式的测试报告;并,发送相关报告至指定邮箱;

后期拓展:

1.部署线上jenkins服务,部署本地/线上python环境,部署本地/线上wamp环境,CI持续集成;

2.熟悉相关linux命令;优化相关脚本逻辑;

3.部署线上禅道服务,实现主要功能:实时写入bug&获取bug清单&更改bug状态,下载最新包含符合筛选条件的bug的excel文档;

python相关核心脚本如下:

 1 # coding:utf-8
 2 ‘‘‘
 3 @file: test_002_update_banner_testcase.py
 4 @author: jingsheng hong
 5 @ide: PyCharm
 6 @createTime: 2019年07月29日  10点21分
 7 @contactInformation: [email protected]
 8 ‘‘‘
 9
10
11 import unittest
12 import ddt
13 from data.b.banner.d_update_banner              import D_update_banner
14 from controller.b.banner.c_update_banner        import C_update_Banner
15 from expectedResult.b.banner.e_update_banner    import E_update_banner
16 from validate.b.banner.v_update_banner          import V_update_banner
17 from optimize.b.banner.o_update_banner          import O_update_banner
18 from writeCellValue.b.banner.w_update_banner    import W_update_banner
19
20 excel_data = D_update_banner().excel_data()
21
22 @ddt.ddt
23 class Test_update_banner(unittest.TestCase):
24     ‘‘‘【更新banner】接口的接口测试用例集合‘‘‘
25
26     def setUp(self):
27         pass
28
29     def tearDown(self):
30         pass
31
32     @ddt.data(*excel_data)
33     def test_update_banner(self,data):
34         O_update_banner(data).sleep()
35         O_update_banner(data).printAllParamsLog()
36         expectResult    =  E_update_banner(data).update()
37         actualResult    =  C_update_Banner(data).update()
38         W_update_banner(data).writeReturnValue(actualResult)
39         O_update_banner(data).printLog(expectResult,actualResult)
40         compareResult   =  V_update_banner(expectResult,actualResult).compareResult()
41         assertResult    =  V_update_banner(expectResult,actualResult).assertResult()
42         W_update_banner(data).writeAssertResult(assertResult)
43         self.assertTrue(compareResult)
44
45 if __name__ =="__main__":
46     unittest.main()

php相关控制层脚本如下:

  1 <?php
  2 /**
  3  * Created by PhpStorm.
  4  * User: Administrator
  5  * Date: 2019/03/25
  6  * Time: 19:02
  7  */
  8
  9 namespace app\api\controller\b;
 10
 11 use app\api\controller\ApiCommon;
 12 use app\api\controller\utils\File;
 13 use app\api\model\ModelBanner;
 14 use app\api\validate\V_Banner;
 15 use think\Db;
 16 use think\Response;
 17
 18 class Banner  extends ApiCommon
 19 {
 20
 21     /**  后台查询banner列表(可传id获取单个banner信息)
 22      * @return \think\Response
 23      */
 24     public function showBannerA(){
 25         $id = input(‘param.id‘);
 26         $page = input(‘param.page‘);
 27         $last = input(‘param.last‘);
 28         //实例化content,查询all
 29         $mBanner = new ModelBanner();
 30         $list = $mBanner->showBannerA($id,$page,$last);
 31         $count = $mBanner->countBanner();
 32         list_upload_image_path_format($list,‘image‘);
 33         if ($list){
 34             $data = [
 35                 ‘code‘=>0,
 36                 ‘count‘=>$count==0?‘‘:$count,
 37                 ‘data‘=>$list,
 38             ];
 39             return response($data,0,array(),‘json‘);
 40         }else{
 41             return api_list_not_more();
 42         }
 43     }
 44     //Banner排序接口
 45     public function sortBanner(){
 46         //获取到的id和sort值
 47         $param = input(‘param.‘);
 48         if (empty($param)){
 49             return api_param_error();
 50         }
 51         $all=[];
 52         for ($i = 0;$i<count($param[‘id‘]);$i++){
 53             //验证参数
 54             $validate = new V_Banner();
 55             if (!$validate->scene(‘sort‘)->check([‘sort‘=>$param[‘sort‘][$i]])) {
 56                 return api_param_error($validate->getError());
 57             }
 58             $info[‘id‘]=$param[‘id‘][$i];
 59             $info[‘sort‘]=$param[‘sort‘][$i];
 60             $all[] = $info;
 61         }
 62         $banner = new ModelBanner();
 63         $res = $banner->saveAll($all);
 64         if ($res){
 65             return api_success(‘操作成功‘);
 66         }else{
 67             return api_error();
 68         }
 69     }
 70
 71     /**  删除banner(传id删除单个banner或传数组批量删除)
 72      * @return \think\Response
 73      */
 74     public function delBanner(){
 75         $id = input(‘param.id‘);
 76         $mBanner = new ModelBanner();
 77         $banner =$mBanner->delBanner($id);
 78         if ($banner){
 79             return api_success(‘成功删除‘);
 80         }else{
 81             return api_error();
 82         }
 83     }
 84     /**  创建banner
 85      * @return Response
 86      */
 87     public function creBanner(){
 88         //获取内容信息    id title img_path status  type
 89         $info = input(‘param.‘);
 90         //验证参数
 91         $validate =  new V_Banner();
 92         if (!$validate->scene(‘create‘)->check($info)) {
 93             return api_param_error($validate->getError());
 94         }
 95         if (strpos($info[‘sort‘],‘.‘)){
 96             return api_error(‘排序只能是整数‘);
 97         }
 98         $banner = new ModelBanner();
 99         $sort = $banner->where(‘sort‘,$info[‘sort‘])->find();
100         if ($sort){
101             return api_error(‘此排序数字已经存在‘);
102         }
103         $file = new File();
104         $files = $file->upload(‘Banner‘,‘image‘,true);
105         //判断是否上传文件
106         if ($files instanceof Response) {
107             return api_error(‘没有上传图片‘);
108         }
109         //检查是否上传成功
110         if ($files[0][‘is_success‘]) {
111             // 启动事务
112             Db::startTrans();
113             try {
114                 $info[‘image‘] = $files[0][‘file_path‘];
115
116                 $res = $banner->save($info);
117                 if ($res){
118                     // 提交事务
119                     Db::commit();
120                     return api_success(‘创建成功!‘);
121                 }
122             } catch (\Exception $e) {
123                 // 回滚事务
124                 Db::rollback();
125                 return api_success(‘创建失败!‘);
126             }
127         }else{
128             return api_error($files[0][‘error_msg‘]);
129         }
130
131     }
132     /** 修改banner
133      * @return \think\Response
134      */
135     public function upBanner(){
136
137         //获取内容信息    id title img_path status  type
138         $info = input(‘param.‘);
139         //验证参数
140         $validate =  new V_Banner();
141         if (!$validate->scene(‘update‘)->check(input(‘param.‘))) {
142             return api_param_error($validate->getError());
143         }
144         if (strpos($info[‘sort‘],‘.‘)){
145             return api_error(‘排序只能是整数‘);
146         }
147         $banner = new ModelBanner();
148         $sort = $banner->where(‘sort‘,$info[‘sort‘])->find();
149         if ($sort){
150             if (!$banner->where(‘sort‘,$info[‘sort‘])->find($info[‘id‘])){
151                 return api_error(‘此排序数字已经存在‘);
152             }
153         }
154         $file = new File();
155         $files = $file->upload(‘Banner‘,‘image‘,true);
156
157         //判断是否上传文件
158         if (!$files instanceof Response) {
159             //判断是否符合大小和格式
160             if (!$files[0][‘is_success‘]) {
161                 return api_error($files[0][‘error_msg‘]);
162             }
163             $info[‘image‘] = $files[0][‘file_path‘];
164         }
165         // 启动事务
166         Db::startTrans();
167         try {
168             $mBanner = new ModelBanner();
169             $res = $mBanner->save($info,[‘id‘=>$info[‘id‘]]);
170             if ($res){
171                 // 提交事务
172                 Db::commit();
173                 return api_success(‘修改成功!‘);
174             }
175         } catch (\Exception $e) {
176             // 回滚事务
177             Db::rollback();
178             return api_error(‘修改失败!‘);
179         }
180     }
181
182
183
184     /**  banner上下线功能
185      * @return Response
186      */
187     public function togStatus(){
188         $id = input(‘param.id‘);
189         if (empty($id)){
190             return api_param_error();
191         }
192         $mBanner = new ModelBanner();
193         $result=$mBanner->togStatus($id);
194         if($result){
195             return api_success("操作成功!");
196         }else{
197             return api_error();
198         }
199
200     }
201
202     /**  测试
203      * @return array|false|\PDOStatement|string|\think\Model
204      */
205     function f(){
206         $id = input(‘param.‘);
207         $banner = new ModelBanner();
208         $item = $banner->find($id);
209         return $item;
210     }
211
212     public function image(){
213 //        $arr = input(‘param.‘);
214 //        dump($arr);
215 //        return $arr;
216         return input(‘param.‘);
217         return $_POST[‘title‘];
218         return $_FILES;
219         $files = request()->file(‘file‘);
220         return $files;
221     }
222
223 }

待更新 ...

原文地址:https://www.cnblogs.com/xiamen-momo/p/11368379.html

时间: 2024-07-29 14:27:42

接口自动化测试流程和相关准备工作的相关文章

接口自动化测试,完整入门篇

1. 什么是接口测试 顾名思义,接口测试是对系统或组件之间的接口进行测试,主要是校验数据的交换,传递和控制管理过程,以及相互逻辑依赖关系.其中接口协议分为HTTP,WebService,Dubbo,Thrift,Socket等类型,测试类型又主要分为功能测试,性能测试,稳定性测试,安全性测试等. 在分层测试的“金字塔”模型中,接口测试属于第二层服务集成测试范畴.相比UI层(主要是WEB或APP)自动化测试而言,接口自动化测试收益更大,且容易实现,维护成本低,有着更高的投入产出比,是每个公司开展自

用Jmeter进行接口自动化测试工作流程

原文转自:https://blog.csdn.net/jinganglong123/article/details/51122713 在测试负责人接受到测试任务后,应该按照以下流程规范完成测试工作.2.1    测试需求分析产品开发负责人在完成某产品功能的接口文档编写后,在核对无误后下发给对应的接口测试负责人.测试负责人拿到接口文档需要首先做以下两方面的工作.一方面,测试人员要对接口文档中各个接口的功能以及接口中涉及的各个字段的意义和用途进行理解.另一方面,测试人员也应该充分与开发人员交流,理解

接口自动化测试框架 (一) :APIAutoTest框架

前言 随着测试技术的发展,接口自动化测试逐渐成为各大公司投入产出比最高的测试技术.介入时间早,执行效率高,稳定性高的优点,让越来越多的公司引入接口自动化测试. 框架简介 APIAutoTest是处理API接口的轻量级自动化测试框架,Java语言实现,基于TestNG测试框架,支持持续集成,自动构建与测试. 框架介绍 1.    数据驱动设计,使用TestNG中的@DataProvider读取Excel中存储的自动化测试用例. 2.    基于TestNG测试框架 3.    使用HttpClie

【python3+request】python3+requests接口自动化测试框架实例详解教程

转自:https://my.oschina.net/u/3041656/blog/820023 前段时间由于公司测试方向的转型,由原来的web页面功能测试转变成接口测试,之前大多都是手工进行,利用postman和jmeter进行的接口测试,后来,组内有人讲原先web自动化的测试框架移驾成接口的自动化框架,使用的是java语言,但对于一个学java,却在学python的我来说,觉得python比起java更简单些,所以,我决定自己写python的接口自动化测试框架,由于本人也是刚学习python,

api4excel - 接口自动化测试excel篇

api4excel - 接口自动化测试excel篇 工作原理: 测试用例在excel上编辑,使用第三方库xlrd,读取表格sheet和内容,sheetName对应模块名,Jenkins集成服务发现服务moduleName查找对应表单,运用第三方库requests请求接口,根据结果和期望值进行断言,根据输出报告判断接口测试是否通过. 1. 数据准备 数据插入(容易实现的测试场景下所需外部数据) 准备sql (接口需要重复使用,参数一定得是变量) 2.集成部署(运维相关了解即可) 平滑升级验证脚本加

Python 基于http接口自动化测试

设计原理 基于http协议接口的测试设计,莫过于Python的requests库,简单粗暴易理解. 设计模式 采用python的flask框架,搭建一套接口自动化测试平台. 测试用例维护:采用Excel 测试结果保存:采用MongoDb存储,HTML页面展示 相关核心代码介绍: Excel模板如下: 看Excel的定义命名,基本理解,每个参数的含义 介绍: B1:要测试的接口地址 B2:该测试接口的请求参数,以"#"分隔[便于分割] B3:登录的URL,若测试不需要登录 B4:登录的j

美团接口自动化测试实践

一.概述 1.1 接口自动化概述 众所周知,接口自动化测试有着如下特点: 低投入,高产出. 比较容易实现自动化. 和UI自动化测试相比更加稳定. 如何做好一个接口自动化测试项目呢? 我认为,一个"好的"自动化测试项目,需要从"时间"."人力"."收益"这三个方面出发,做好"取舍". 不能由于被测系统发生一些变更,就导致花费了几个小时的自动化脚本无法执行.同时,我们需要看到"收益",不能为

python+requests接口自动化测试框架实例详解教程

转自https://my.oschina.net/u/3041656/blog/820023 摘要: python + requests实现的接口自动化框架详细教程 前段时间由于公司测试方向的转型,由原来的web页面功能测试转变成接口测试,之前大多都是手工进行,利用postman和jmeter进行的接口测试,后来,组内有人讲原先web自动化的测试框架移驾成接口的自动化框架,使用的是java语言,但对于一个学java,却在学python的我来说,觉得python比起java更简单些,所以,我决定自

python+requests接口自动化测试框架实例详解

前段时间由于公司测试方向的转型,由原来的web页面功能测试转变成接口测试,之前大多都是手工进行,利用postman和jmeter进行的接口测试,后来,组内有人讲原先web自动化的测试框架移驾成接口的自动化框架,使用的是java语言,但对于一个学java,却在学python的我来说,觉得python比起java更简单些,所以,我决定自己写python的接口自动化测试框架,由于本人也是刚学习python,这套自动化框架目前已经基本完成了,于是进行一些总结,便于以后回顾温习,有许多不完善的地方,也遇到