巧用python进行接口自动化测试

python

一、接口自动化测试的流程

1、需求分析

1、1请求(url,方法、数据)

2、挑选需要做自动化测试的接口

3、设计自动化测试用例

4、搭建自动化测试环境

5、设计自动化执行框架(报告、参数化、 用例执行框架)

6、编写代码

7、执行用例(unittest、pytest)

8、生成测试报告(htmltextrunner\allure)

二、用例设计

2、1单接口

模板:id,模块,接口名称,请求url,用例名称,请求方法,请求参数类型,请求参数,预期结果,实际结果,备注

注意:单接口颗粒度放的比较小(以测试数据为颗粒度)

2、2多接口

模板:id,模块,接口名称,请求url,用例名称,请求方法,请求参数类型,请求参数,预期结果,实际结果,备注

注意:多个接口颗粒度为每个接口为基础,每个接口内所设计的数据可以通过参数化来解决。

三、自动化目录结构

1、配置层(common)

python;gutter:true;">import os

def filePath(fileDir='',fileName=''):

'''

:param fileDir: 目录

:param fileName: 文件的名称

:return:

'''

return os.path.join(

os.path.dirname(os.path.dirname(__file__)), fileDir, fileName)

2、用例执行业务层(testcase)

import pytest,json,allure

from util.apiutil import Request

from util.yamlutil import OperationYaml

from util.excelutil import OperationExcel,ExcelVarles

obj = Request()

objYaml = OperationYaml()

objExcel = OperationExcel()

data_key = ExcelVarles

class TestExcel:

# request封装

def run_api(self, url, method, params=None, headers=None, cookies=None):

if str(method).lower() == "get":

res = obj.get(url, params=params, headers=headers, cookies=cookies)

elif str(method).lower() == "post":

res = obj.post(url, json=params, headers=headers, cookies=cookies)

return res

# 运行前置用例

def run_pre(self, pre_case):

url = objYaml.readbaseyaml()["test_url"] + pre_case[data_key.url]

method = pre_case[data_key.method]

params = eval(pre_case[data_key.params])

headers = pre_case[data_key.headers]

header = self.json_parse(headers)

cookies = pre_case[data_key.cookies]

res = self.run_api(url, method, params, header)

print("前置用例执行:%s" % res)

return res

@pytest.mark.parametrize('datas',objExcel.runs())

# 运行测试用例

def test_login(self,datas):

url = objYaml.readbaseyaml()["test_url"] + datas[data_key.url]

print(url)

case_id = datas[data_key.case_id]

case_model = datas[data_key.case_model]

case_name = datas[data_key.case_name]

pre_exec = datas[data_key.pre_exec]

method = datas[data_key.method]

params = eval(datas[data_key.params])

expect_result = datas[data_key.expect_result]

headers = datas[data_key.headers]

cookies = datas[data_key.cookies]

code = datas[data_key.code]

db_verify = datas[data_key.db_verify]

if pre_exec:

pass

pre_case = objExcel.case_prev(pre_exec)

print("前置条件信息为:%s" % pre_case)

pre_res = self.run_pre(pre_case)

headers = self.get_correlation(headers,pre_res)

header = self.json_parse(headers)

res = self.run_api(url, method, params, header, cookies)

print("测试用例执行:%s" % res)

assert expect_result in str(res["body"]["message"])

assert code == int(res["code"])

# 对allure报告进行配置

# allure

# sheet名称 feature 一级标签

# allure.dynamic.feature(sheet_name)

# 模块 story 二级标签

allure.dynamic.story(case_model)

# 用例ID+接口名称 title

allure.dynamic.title(case_id + case_name)

# 请求URL 请求类型 期望结果 实际结果描述

desc = "<font color='red'>请求URL: </font> {}<Br/>" \

"<font color='red'>请求类型: </font>{}<Br/>" \

"<font color='red'>期望结果: </font>{}<Br/>" \

"<font color='red'>实际结果: </font>{}".format(url, method, expect_result, res)

allure.dynamic.description(desc)

def json_parse(self,data): # 格式化字符,转换json

# if headers:

# header = json.loads(headers)

# else:

# header = headers

return json.loads(data) if data else data

# token参数关联替换

def get_correlation(self,header,pre_res):

# 验证是否有关联

headers_para = objExcel.params_find(header)

if len(headers_para):

# 有关联,执行前置用例,获取结果

headers_data = pre_res["body"]["data"]["token"][headers_para[0]]

# 结果替换

headers = objExcel.res_sub(header, headers_data)

return headers

if __name__ == '__main__':

pytest.main(["-s", "-v", "test_single_api.py"])

3、数据驱动(data)

存放excel,yaml文件

4、测试报告(report)

5、工具层(第三方工具包)

apiutil.py

import requests

class Request():

def requests_api(self,url, json=None, headers=None, cookies=None, params=None, data=None,method="get"):

if method == "get":

r = requests.get(url=url,headers=headers,cookies=cookies,params=params,data=data)

elif method == "post":

r = requests.post(url=url,json=json,headers=headers,cookies=cookies)

elif method == "put":

r = requests.put(url=url,headers=headers,cookies=cookies,params=params)

elif method == "delete":

r =requests.delete(url=url,headers=headers,cookies=cookies,params=params)

code = r.status_code

try:

body = r.json()

except Exception as e:

body = r.text

res = dict()

res["code"] = code

res["body"] = body

return res

def get(self,url,**kwargs):

return self.requests_api(url, method="get", **kwargs)

def post(self,url,**kwargs):

return self.requests_api(url, method="post", **kwargs)

def put(self,url,**kwargs):

return self.requests_api(url, method="put", **kwargs)

def delete(self,url,**kwargs):

return self.requests_api(url, method="delete", **kwargs)

excelutil.py

import xlrd

from common.basepath import *

import json

import re

p_data = '\${(.*)}\$'

class ExcelVarles:

case_id = "用例ID"

case_model = "模块"

case_name = "接口名称"

url = "请求URL"

pre_exec = "前置条件"

method = "请求类型"

params_type = "请求参数类型"

params = "请求参数"

expect_result = "预期结果"

actual_result = "实际结果"

beizhu = "备注"

is_run = "是否运行"

headers = "headers"

cookies = "cookies"

code = "status_code"

db_verify = "数据库验证"

class OperationExcel:

@property

def getExcelDatas(self):

datas = list()

book = xlrd.open_workbook(filePath('data', 'api.xlsx'))

getsheet = book.sheet_by_index(0)

title = getsheet.row_values(0)

for row in range(1,getsheet.nrows):

row_values=getsheet.row_values(row)

datas.append(dict(zip(title,row_values)))

return datas

def runs(self):

# 获取到可执行的测试用例

run_list=[]

for item in self.getExcelDatas:

isRun=item[ExcelVarles.is_run]

if isRun == 'y':

run_list.append(item)

else:

pass

return run_list

def params(self):

'''对请求参数为空做处理'''

params_list=[]

for item in self.runs():

params=item[ExcelVarles.params]

if len(str(params).strip())==0:

pass

elif len(str(params).strip())>=0:

params=json.loads(params)

def case_prev(self,casePrev):

# 据前置测试条件找到关联的前置测试用例

for item in self.getExcelDatas:

if casePrev in item.values():

return item

return None

def res_find(self,data, pattern_data=p_data): # 查询

# pattern = re.compile('\${(.*)}\$')

pattern = re.compile(pattern_data)

re_res = pattern.findall(data)

return re_res

def res_sub(self,data, replace, pattern_data=p_data): # 替换

pattern = re.compile(pattern_data)

re_res = pattern.findall(data)

if re_res:

return re.sub(pattern_data, replace, data)

return re_res

def params_find(self,headers): # 验证请求中是否有${}$需要结果关联

if "${" in headers:

headers = self.res_find(headers)

return headers

yamlutil.py

import  yaml

from common.basepath import filePath

class OperationYaml:

def readYaml(self,fileDir='data',fileName='login.yaml'): ### 获取login测试用例

with open(filePath(fileDir=fileDir, fileName=fileName),'r',encoding='utf-8') as f:

return list(yaml.safe_load_all(f))

def readbaseyaml(self,fileDir='data',fileName='base.yaml'):

with open(filePath(fileDir=fileDir, fileName=fileName), 'r', encoding='utf-8') as f:

return yaml.safe_load(f)

def readgoodsyaml(self,fileDir='data',fileName='goods.yaml'): ### 获取商品测试用例

with open(filePath(fileDir=fileDir, fileName=fileName), 'r', encoding='utf-8') as f:

return list(yaml.safe_load_all(f))

6、运行入口层(运行测试用例,并生成报告)

以上是 巧用python进行接口自动化测试 的全部内容, 来源链接: utcz.com/z/387225.html

回到顶部