python requests接口自动化测试_基于python+requests+unittest实现的接口自动化测试方案...

第一篇简书文章献给你,笔芯~

背景简介

最近在做接口测试,每次新功能提交测试,有大量的接口,有些接口参数有几十个,转化成用例,除了每个参数基础的边界值、等价类校验外,还涉及很多业务逻辑的比对测试。由于团队提供的API接口在swagger上面,每次测试在swagger上拼参数测试确实很方便,但是没有个记录,测试完了除非每个团队成员都对接口参数有保存,后续再要验证时要重新拼参数或是找同事拿已经拼好的参数,增加时间成本,而且要回归验证有需要再重新调一次,考虑到这些,做了一些需求调研,决定使用python+requests+unittest实现读取Excel用例自动执行请求。项目落成,在此做个记录,当然仍有许多不足之处需改进。

需求分析

要做一个东西,当然是要先搞清楚需求,即我们的现状,要实现怎样的效果,搞清楚了要实现什么,再来一步一步的任务拆分,然后想办法实现。

首先,开发提供给我们测试的接口是通过swagger自动生成,没有特定的接口文档,swagger上有每个接口详细的参数描述等信息。接口请求类型主要有GET、POST、PUT、DELETE,针对每个类型的接口,传参类型有所不同,不能用通用的requests传参来做拼接请求,如下:

f648e0a1dda2

params_type.png

如果类型为URL Path的,做请求时就需要拿到base_url+URL Path,拼接好后作为请求的url;

如果类型为Query的,就需要把参数以key-value的形式进行传参;等等...

依此,设计Excel模板如下:

f648e0a1dda2

Excel模板.png

每个团队成员只需要在Excel里面写一次用例,执行的时候记录下每个传参、请求的基础url,预期结果,之后就可以自动回归啦~

接下来就是要怎么实现这个过程了...

实现

就像把大象塞冰箱里面需要几个步骤一样,打开冰箱、把大象塞进去、关上冰箱....(⊙﹏⊙)b....大象根本就塞不下一般的冰箱好不啦~

言归正传,怎样实现这个过程:

1.遍历excel,读取数据

2.处理读取到的数据,拿到我们想要的数据

3.拼接请求,发送request请求

4.拿到response状态值,对比excel预期结果是否一致

架构如图(也说不上什么架构哈~)

f648e0a1dda2

项目结构.png

说明:

·operate_excel.py:封装一些操作excel数据表的方法

·get_data.py:封装获取excel值的方法

·data_config.py:配置excel的固定列,封装获取对应列的方法

·handle_requests.py:封装request请求

·run.py:主函数,根据拿到的请求类型判断,拼装请求url及参数自动发送请求,返回实际请求的status_code以及excel的expect。然后作为参数传递给unittest的test方法自动断言

data_config.py:

#!/usr/bin/python

# -*- coding:utf-8 -*-

"""

获取Excel每列

"""

class global_var:

Id = '0'

interface_name = '1'

case_name = '2'

case_paramas_type = '3'

case_method = '4'

case_headers = '5'

parameters = '6'

query = '7'

body = '8'

request_url ='9'

expect = '10'

result = '11'

sql1 = '12'

sql2 = '13'

def get_id():

return global_var.Id

def get_url():

return global_var.request_url

def get_interface_name():

return global_var.interface_name

def get_case_name():

return global_var.case_name

def get_case_params_type():

return global_var.case_paramas_type

def get_method():

return global_var.case_method

def get_headers():

return global_var.case_headers

def get_parameters():

return global_var.parameters

def get_query():

return global_var.query

def get_body():

return global_var.body

def get_expect():

return global_var.expect

get_data.py:

#!/usr/bin/python

# -*- coding:utf-8 -*-

"""

获取单元格中的内容

"""

from NewTest.public.operate_excel import OperateExcel

from NewTest.public import data_config

import xlrd

class GetData:

def __init__(self,file_name):

self.opera_excel = OperateExcel(file_name)

# 获取Excel行数,即case个数

def get_case_linese(self):

return self.opera_excel.get_lines()

# 获取是否携带headers

def is_header(self,row):

col = int(data_config.get_headers())

header = self.opera_excel.get_cell_value(row,col)

if header != '':

return header

else:

return None

# 获取请求方式

def get_request_method(self,row):

col = int(data_config.get_method())

request_method = self.opera_excel.get_cell_value(row,col)

return request_method

# 获取请求url

def get_request_url(self,row):

col = int(data_config.get_url())

request_url = self.opera_excel.get_cell_value(row,col)

if request_url == '':

return None

else:

return request_url

# 获取请求query

def get_request_query(self,row):

col = int(data_config.get_query())

reuqest_query = self.opera_excel.get_cell_value(row,col)

if reuqest_query == '':

return None

else:

return reuqest_query

# 获取请求body

def get_request_body(self,row):

col = int(data_config.get_body())

request_body = self.opera_excel.get_cell_value(row,col)

if request_body == '':

return None

else:

return request_body

# 获取期望结果

def get_expect_result(self,row):

col = int(data_config.get_expect())

expect_result = self.opera_excel.get_cell_value(row,col)

if expect_result != '':

return expect_result

else:

return None

# 获取用例参数方式

def get_case_params_type(self,row):

col = int(data_config.get_case_params_type())

case_paramas_type = self.opera_excel.get_cell_value(row,col)

return case_paramas_type

# 获取parameters

def get_request_params(self,row):

col = int(data_config.get_parameters())

request_params = self.opera_excel.get_cell_value(row,col)

return request_params

def get_case_id(self,row):

col = int(data_config.get_id())

id = self.opera_excel.get_cell_value(row,col)

return id

operate_excel.py:

#!/usr/bin/python

# -*- coding:utf-8 -*-

import xlrd

class OperateExcel:

def __init__(self,file_name,sheet_id=0):

self.file_name = file_name

self.sheet_id = sheet_id

self.data = self.get_data_contents()

self.new_path = '../NewTest/report/'

# 获取sheet内容

def get_data_contents(self):

data = xlrd.open_workbook(self.file_name)

table = data.sheet_by_index(self.sheet_id)

return table

# 获取单元格行数

def get_lines(self):

tables = self.get_data_contents()

return tables.nrows

# 获取某个单元格内容

def get_cell_value(self,row,col):

return self.data.cell_value(row,col)

handle_requests.py:

#!/usr/bin/python

# -*- coding:utf-8 -*-

"""

封装get/post请求

"""

import requests

class SendRequest:

def request_main(self, method, request_url, params=None, data=None, headers=None):

try:

res = requests.request(method, request_url, params=params, data=data, headers=headers, timeout=5)

return res

except (requests.ConnectionError, requests.HTTPError, requests.URLRequired, requests.Timeout,

requests.ConnectTimeout), e:

print e

run.py

#!/urs/bin/python

# -*- coding:utf-8 -*-

from public.get_data import GetData

from public.handle_requests import SendRequest

import json

import requests

from nose_parameterized import parameterized

import unittest

class TestRunCase():

def __init__(self, file_name):

self.run_request = SendRequest()

self.data = GetData(file_name)

self.path = file_name

def get_params(self):

param_dic = []

try:

rows_count = self.data.get_case_linese() # 获取用例excel条数

for i in range(1, rows_count):

method = self.data.get_request_method(i)

type = self.data.get_case_params_type(i)

query = self.data.get_request_query(i)

body = self.data.get_request_body(i)

url = self.data.get_request_url(i)

params = self.data.get_request_params(i)

if type == "URL Path":

request_url = url + str(params)

params = None

data = None

headers = None

elif type == "No Type":

request_url = url

params = None

data = None

headers = None

elif type == "Query":

request_url = url

params = json.loads(query)

data = None

headers = None

elif type == "URL Path And Query":

request_url = url + params

params = json.loads(query)

data = None

headers = None

elif type == "Body":

request_url = url

body = json.loads(body)

params = None

data = json.dumps(body)

headers = None

else:

print "请求方式不在范围内!"

response = self.run_request.request_main(method, request_url, params=params, data=data,

headers=headers)

actual_results = response.status_code

expect_results = int(self.data.get_expect_result(i))

case_id = i + 1

param_dic.append((case_id, expect_results, actual_results))

return param_dic

except (requests.ConnectionError, requests.HTTPError, requests.URLRequired, requests.Timeout,

requests.ConnectTimeout) as e:

print e

path = "/Users/shifenyuanqi/Desktop/test.xlsx"

params_list = TestRunCase(path).get_params()

print params_list

class TestRun(unittest.TestCase):

@parameterized.expand(params_list)

def test_run(self, name, expect_res, actual_res):

self.assertEqual(expect_res, actual_res)

最后run一波,自动遍历excel的每条case执行请求生成结果:

f648e0a1dda2

run_results.png

当然还有写入excel执行结果啦,生成测试报告,自动持续集成到Jenkins这些这里就暂时不赘述了~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值