登录接口的自动化测试实战
前面3个章节我们已经将必要组件全部完成了,它们分别有:接口服务器、接口访问器、MySQL访问器,现在只剩一个执行器和一个结果分析器,让我们一气呵成完成剩余2个组件吧~
一. 本章的讲解思路:
1. 新建一个保存参数的MySQL表 ( 在上一篇教程里建好的account
表保存的是实际用户的信息,我们还要建一个表params
用来放所有的接口参数,建表脚本和参数存放格式下面有示例 )
2. 按( 读取接口url、读取对应参数、发起请求、收集结果)这4个步骤编写一个总控制器:run.py
3. 先启动http服务 (运行panda_http_server.py即可),然后运行和调试run.py
确保run组件的执行过程完全符合标准的接口测试逻辑
4. 分析和总结
二. 创建参数表params
:
复制下面的sql脚本并执行,请确保建表和插入数据都成功
/*创建参数储存表*/
CREATE TABLE `panda`.`params`(
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '参数id',
`module_name` VARCHAR(200) NOT NULL COMMENT '功能模块名称',
`user` VARCHAR(50) COMMENT '测试账户名',
`password` VARCHAR(50) COMMENT '测试密码',
`create_auth` VARCHAR(50) NOT NULL COMMENT '接口创建者',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) CHARSET=utf8;
/*--------------------------------------------------------*/
/*根据account表的一个用户TerryJay,我设计了下面6组登录参数*/
/*--------------------------------------------------------*/
/*第1条——用户名密码全部正确*/
USE `panda`;
INSERT INTO
`params`(`module_name`,`user`,`password`, `create_auth`, `create_time`) VALUES
('登录测试','TerryJay','12345', 'CSDN', NOW());
/*第2条——用户名正确,但密码为空*/
USE `panda`;
INSERT INTO
`params`(`module_name`,`user`,`password`, `create_auth`, `create_time`) VALUES
('登录测试','TerryJay','', 'CSDN', NOW());
/*第3条——用户名为空,但密码正确*/
USE `panda`;
INSERT INTO
`params`(`module_name`,`user`,`password`, `create_auth`, `create_time`) VALUES
('登录测试','','12345', 'CSDN', NOW());
/*第4条——用户名正确,但密码错误*/
USE `panda`;
INSERT INTO
`params`(`module_name`,`user`,`password`, `create_auth`, `create_time`) VALUES
('登录测试','TerryJay','66666', 'CSDN', NOW());
/*第5条——用户名错误,但密码正确*/
USE `panda`;
INSERT INTO
`params`(`module_name`,`user`,`password`, `create_auth`, `create_time`) VALUES
('登录测试','PeiQi','12345', 'CSDN', NOW());
/*第6条——用户名及密码都为空*/
USE `panda`;
INSERT INTO
`params`(`module_name`,`user`,`password`, `create_auth`, `create_time`) VALUES
('登录测试','','', 'CSDN', NOW());
-----以上脚本执行成功后,可以看到params表的数据是这样子的:
-----至此,我们一共创建了3个表,他们是:
三. 开始编写执行器run,他的功能是将其他组件串联起来,协作完成自动化测试:
# -*- coding: utf-8 -*-
"""
@version: 1.0
@author: TerryJay
@license: Apache Licence 2.0
@file: run.py
@time: 2018/6/6 21:56
"""
from module.panda_connect_mysql import SQL
from module import panda_http_request
import json
class Panda_Auto_Test:
def __init__(self):
self.interface_dict = dict()
self.params_all_dict = dict()
self.params_id = list()
self.SQL = SQL()
self.success = {"Get_PASS": 0, "Post_PASS": 0}
self.fail = {"Get_FAIL": 0, "Post_FAIL": 0}
self.error = {"Get_ERROR": 0, "Post_ERROR": 0}
# 接口组装,根据case表的module_name列名去查询,此方法执行一次可提取一个接口
def panda_interface_assemble(self, case_module_name):
method = self.SQL.sql_select_one(" SELECT `request` FROM `case` WHERE `module_name`= '%s'" % case_module_name)
url = self.SQL.sql_select_one(" SELECT `url` FROM `case` WHERE `module_name`= '%s'" % case_module_name)
headers = self.SQL.sql_select_one(" SELECT `headers` FROM `case` WHERE `module_name`= '%s'" % case_module_name)
params = self.SQL.sql_select_one(" SELECT `body` FROM `case` WHERE `module_name`= '%s'" % case_module_name)
if method and url and headers and params != '':
self.interface_dict['method'] = method[0]
self.interface_dict['url'] = url[0]
self.interface_dict['headers'] = json.loads(headers[0])
self.interface_dict['params'] = json.loads(params[0])
return self.interface_dict
else:
return None
# 接口参数提取,根据params表的module_name、id 2个列完成输数据库查询,此方法执行一次可提取一组参数
def panda_params_extract(self, params_module_name, params_id_section):
# params_all_dict = dict()
params_id_min = params_id_section[0]
params_id_max = params_id_section[1]
ergodic = params_id_max - params_id_min + 1
for i in range(ergodic):
user = self.SQL.sql_select_one(" SELECT `user` FROM `params` WHERE `module_name`='%s' AND `id`='%s'" % (params_module_name, params_id_min))
password = self.SQL.sql_select_one(" SELECT `password` FROM `params` WHERE `module_name`='%s' AND `id`='%s'" % (params_module_name, params_id_min))
params_dict = dict()
params_dict['user'] = user[0]
params_dict['password'] = password[0]
self.params_all_dict[str(params_id_min)] = params_dict
params_id_min += 1
return self.params_all_dict
# 发起请求,根据case表的method列名去查询,分别以get和post的方式发起请求,并收集请求结果
# def panda_run_http(self, **merge_interface, **merge_param):
def panda_run_http(self, **merge_interface_and_param):
merge_interface = merge_interface_and_param['merge_interface']
merge_param = merge_interface_and_param['merge_param']
if merge_interface and merge_interface is not None:
param_total = len(merge_param)
for i in range(param_total):
param_order = i + 1 # for循环是从0开始的,但是我们的数据库params表的id是从1开始,所以需要+1
merge_interface['params']['loginId'] = merge_param[str(param_order)]['user']
merge_interface['params']['password'] = merge_param[str(param_order)]['password']
if merge_interface['method'] == 'get':
panda_get = panda_http_request.auto_get(merge_interface['url'], merge_interface['params'], merge_interface['headers'])
# 打印出get接口的返回值print(panda_get)
if panda_get['result'] == '200':
self.success["Get_PASS"] += 1
else:
self.fail["Get_FAIL"] += 1
elif merge_interface['method'] == 'post':
panda_post = panda_http_request.auto_post(merge_interface['url'], merge_interface['params'], merge_interface['headers'])
# 打印出post接口的返回值print(panda_post)
if panda_post['result'] == '200':
self.success["Post_PASS"] += 1
else:
self.fail["Post_FAIL"] += 1
return self.success, self.fail
else:
print('你的SQL语句查询不到结果,请检查!')
"""
------------------------------------------------------------------------------------------------------------
下面开始调用函数运行自动化测试,你可以根据数据库的实际数据来适当调整参数,并得出不同的测试结果
------------------------------------------------------------------------------------------------------------
"""
# 将Panda_Auto_Test类实例化为对象test
test = Panda_Auto_Test()
# 取出get请求的case
my_request = test.panda_interface_assemble('get登录测试')
# 取一组在数据库的module_name为'登录测试'、且取的id的区间是1~6 也就是6组数据,我们称之为params
my_params = test.panda_params_extract('登录测试', [1, 6])
# 打印出你从数据库选取的6组参数
print(my_params)
# 将case和params将储存到一个数据结构中,这个结构是一个字典
merge = {'merge_interface': my_request, "merge_param": my_params}
# 把组装好的完整case发起接口测试,得到接口测试报告
Test_report = test.panda_run_http(**merge)
# 打印此次的测试报告
print(Test_report)
执行结果:
{'1': {'user': 'TerryJay', 'password': '12345'}, '2': {'user': 'TerryJay', 'password': ''}, '3': {'user': '', 'password': '12345'}, '4': {'user': 'TerryJay', 'password': '66666'}, '5': {'user': 'PeiQi', 'password': '12345'}, '6': {'user': '', 'password': ''}}
({'Get_PASS': 1, 'Post_PASS': 0}, {'Get_FAIL': 5, 'Post_FAIL': 0})
只需修改一个参数,即可全部变成post请求 ( 找到底部这一行代码: my_request = test.panda_interface_assemble('get登录测试') 请把'get登录测试'改为'post登录测试',再次执行) 执行结果:
{'1': {'user': 'TerryJay', 'password': '12345'}, '2': {'user': 'TerryJay', 'password': ''}, '3': {'user': '', 'password': '12345'}, '4': {'user': 'TerryJay', 'password': '66666'}, '5': {'user': 'PeiQi', 'password': '12345'}, '6': {'user': '', 'password': ''}}
({'Get_PASS': 0, 'Post_PASS': 1}, {'Get_FAIL': 0, 'Post_FAIL': 5})
四. 分析和总结
从上面2次的执行结果我们可以发现:
6组参数可正常从数据库取出、可正常拼装到get和post请求中;
Test_report测试报告中:get的结果为1+5条,post的结果为1+5条,统计功能正常;
前面我们存入params表的6组用户参数中,只有一组参数是正确的用户名+密码 (id=1的那组),因为这一组是记录在account表里的正式数据,而接口恰恰就只认account的用户信息。我们的测试预期是:
get的登录请求——成功1条、失败5条
post的登录请求——成功1条、失败5条实际测试的结果是:
GET请求——————({'Get_PASS': 1, 'Post_PASS': 0}, {'Get_FAIL': 5, 'Post_FAIL': 0})
POST请求——————({'Get_PASS': 0, 'Post_PASS': 1}, {'Get_FAIL': 0, 'Post_FAIL': 5})测试结论: 测试预期和测试结果完全相同,本次基于python脚本的HTTP自动化接口测试无Bug,完美通过
传送门:初出茅庐——用python打出你的接口自动化测试第一枪(1)
传送门:初出茅庐——用python打出你的接口自动化测试第一枪(2)
传送门:渐入佳境——python接口自动化测试之实现mysql访问器(3)
版权归作者@TerryJay所有,转载请注明出处