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)

|-------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 | 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、运行入口层(运行测试用例,并生成报告)

2023超详细的Python接口自动化测试进阶教程合集,真实模拟企业项目实战

相关推荐
m0_748236114 分钟前
Calcite Web 项目常见问题解决方案
开发语言·前端·rust
倔强的石头10612 分钟前
【C++指南】类和对象(九):内部类
开发语言·c++
老大白菜12 分钟前
Python 爬虫技术指南
python
Watermelo61716 分钟前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
古希腊掌管学习的神1 小时前
[搜广推]王树森推荐系统——矩阵补充&最近邻查找
python·算法·机器学习·矩阵
半盏茶香1 小时前
在21世纪的我用C语言探寻世界本质 ——编译和链接(编译环境和运行环境)
c语言·开发语言·c++·算法
Evand J2 小时前
LOS/NLOS环境建模与三维TOA定位,MATLAB仿真程序,可自定义锚点数量和轨迹点长度
开发语言·matlab
LucianaiB2 小时前
探索CSDN博客数据:使用Python爬虫技术
开发语言·爬虫·python
Ronin3052 小时前
11.vector的介绍及模拟实现
开发语言·c++
计算机学长大白3 小时前
C中设计不允许继承的类的实现方法是什么?
c语言·开发语言