使用openpyxl实现自动生成接口用例

前言

编写接口用例时,很多反向用例条件是一样的,例如:值为空、值为乱码、值为特殊字符等。

这些工作可以使用脚本实现,解放双手,提高效率。

目录

自动生成接口用例Excel文档

脚本一:辅助填写接口信息

思路:

代码:

脚本二:读取接口信息,并生成接口用例文档

思路:

代码:

资源下载


自动生成接口用例Excel文档

该脚本的本质是:按照接口用例的固定格式,把接口信息填写在对应的单元格里。

那么接口信息就需要使用者进行填写,如果接口很多,填写时不够方便;

可以再写一个脚本,辅助使用者填写接口信息。

所以一共需要填写两个脚本,

脚本一:辅助填写接口信息

脚本二:读取接口信息,并生成接口用例文档

脚本一:辅助填写接口信息

思路:

使用者把json格式的请求信息和响应结果,分别放到B1单元格和B2单元格;

脚本读取请求信息把参数名称和参数值读取出来,填写到sheet页的其他单元格里;

还有其他必须的接口信息,也填写到接口信息单元格里,并填入默认值;

最后使用者根据实际情况填入正确的接口信息。

另外,需要支持多个接口的填写,每个sheet页一个接口信息。

代码:

import json
import time
import openpyxl


# 输入接口信息
def interface(lujing):
    interface_info = openpyxl.load_workbook(lujing)  # 打开工作表
    sheets = interface_info.worksheets  # 获取所有工作簿
    for sheet in sheets:  # 遍历所有的工作簿,每个工作簿都需要辅助填写
        sheet = interface_info[sheet.title]  # 根据工作簿名称获取工作簿
        value1 = sheet['B1'].value  # 获取请求参数的值
        value2 = json.loads(value1)  # 将json值转换为字典
        result = sheet['B2'].value  # 获取返回结果的值
        result1 = json.loads(result)  # 将json值转换为字典

        month = int(time.strftime('%m'))
        day = int(time.strftime('%d'))
        if day <= 8:
            version = month + 0.1
        elif 8 < day <= 22:
            version = month + 0.2
        else:
            version = month + 1.1

        # 填写内容
        sheet['A4'].value = '接口名称'
        sheet['B4'].value = 'XXXX接口'
        sheet['A5'].value = '请求方式'
        sheet['B5'].value = 'POST'
        sheet['A6'].value = 'URL'
        sheet['C4'].value = '成功状态码'
        sheet['C5'].value = '失败状态码'
        sheet['D5'].value = 400
        sheet['C6'].value = '版本号'
        sheet['D6'].value = version
        sheet['A8'].value = '参数'
        sheet['B8'].value = '参数1'
        sheet['C8'].value = '值'
        sheet['D8'].value = '是否必填'
        # 读取返回的成功状态码 并填入,若没有默认200
        if 'status' in result1:
            sheet['D4'].value = result1['status']
        else:
            sheet['D4'].value = 200

        # 把字典的参数和值放到列表中
        i = 9  # 设定行数
        for x, y in value2.items():  # 遍历请求参数字典
            sheet["A" + str(i)].value = x  # 把参数放到表格里
            if isinstance(y, dict):  # 判断值是否为字典
                i += 1  # 行数+1
                for a, b in y.items():  # 遍历字典
                    sheet["B" + str(i)].value = a  # 参数放到表格里
                    sheet["C" + str(i)].value = b  # 值放到表格里
                    sheet["D" + str(i)].value = '是'  # 默认为必填
                    i += 1  # 行数+1
            else:
                sheet["C" + str(i)].value = y  # 把值放到表格里
                sheet["D" + str(i)].value = '是'  # 默认为必填
                i += 1  # 行数+1
    interface_info.save(lujing)  # 保存


if __name__ == '__main__':
    lujing = '/Users/practice/工作簿2.xlsx'
    interface(lujing)

脚本二:读取接口信息,并生成接口用例文档

思路:

首先获取接口信息文档中的信息;

把用例文档的表头填写好,调整好列宽;

填写正向用例,把相应的正向用例信息填入单元格;

填写反向用例,考虑值为空、值为null、值为乱码、值为其他类型参数的情况;

其中需要考虑两层json的情况

代码:

import json
import openpyxl
# import requests as requests
from openpyxl.styles import Alignment
from openpyxl.styles import Font


def interfaceCase(lujing, lujing_info):
    # 创建接口用例文档
    interface_case = openpyxl.Workbook(lujing)  # 创建接口用例文档
    # 从接口信息文档中获取数据
    interface_info = openpyxl.load_workbook(lujing_info)  # 打开接口信息文档
    sheets = interface_info.worksheets  # 获取所有的sheet页
    for info_sheet in sheets:  # 获取每个sheet页,并遍历
        # info_sheet = interface_info.active # 获取接口信息默认sheet页
        title1 = info_sheet['B4'].value[0:-2]  # 名称
        request_method = info_sheet['B5'].value+'\n'+info_sheet['B6'].value  # 前提条件,请求方式+URL
        base_url = info_sheet['B6'].value
        request_parameters = info_sheet['B1'].value  # 具体步骤,请求参数
        Response = info_sheet['B2'].value  # 预期结果,响应结果
        status = str(info_sheet['D5'].value)  # 需要获取异常状态码
        status_code = str(info_sheet['D4'].value)  # 需要获取正常状态码
        version = str(info_sheet['D6'].value)  # 获取版本号

        # 创建sheet页
        interface_case.create_sheet(title1)
        interface_case.save(lujing)  # 保存接口用例文档
        # 打开文档
        interface_case = openpyxl.load_workbook(lujing)  # 打开接口用例文档
        sheet = interface_case[title1]
        # 输入表头
        sheet['A1'].value = '名称'
        sheet['B1'].value = '优先级'
        sheet['C1'].value = '类型'
        sheet['D1'].value = '开始版本'
        sheet['E1'].value = '前提条件'
        sheet['F1'].value = '具体步骤'
        sheet['G1'].value = '预期结果'
        sheet['H1'].value = '备注'
        sheet['I1'].value = '标签'
        sheet['J1'].value = 'RD结论'
        sheet['K1'].value = 'QA结论'

        # 编写正向用例
        sheet['A2'].value = title1+'-正向'
        sheet['B2'].value = '最高(0)'
        sheet['C2'].value = '手工用例'
        sheet['D2'].value = version
        sheet['E2'].value = request_method
        sheet['E2'].alignment = Alignment(wrapText=True)  # 防止openpyxl修改样式,保持换行格式
        parameters = json.loads(request_parameters)
        parameters_new = json.dumps(parameters, ensure_ascii=False, indent=4)
        sheet['F2'].value = parameters_new  # 写入调整格式后的json
        sheet['F2'].alignment = Alignment(wrapText=True)
        Response1 = json.loads(Response)
        Response_new = json.dumps(Response1, ensure_ascii=False, indent=4)
        sheet['G2'].value = Response_new
        sheet['G2'].alignment = Alignment(wrapText=True)
        # 正向用例字体颜色调整为红色
        font = Font(name='宋体', color='ff3300')
        for i in range(1, 8):
            sheet.cell(2, i).font = font
        # 设置列宽
        sheet.column_dimensions['A'].width = 35
        sheet.column_dimensions['F'].width = 35
        sheet.column_dimensions['G'].width = 35
        sheet.column_dimensions['B'].width = 10
        sheet.column_dimensions['C'].width = 10
        sheet.column_dimensions['D'].width = 10
        sheet.column_dimensions['E'].width = 45

        def reverse_cases(case_name='为NULL-异常', value=None):  # 第一层参数反向用例
            sheet['A' + i] = title1 + '-' + row[0] + case_name
            sheet['B' + i] = '中高(1)'
            sheet['C' + i] = '手工用例'
            sheet['D' + i] = version
            sheet['E' + i] = request_method
            sheet['E' + i].alignment = Alignment(wrapText=True)
            # 编辑参数的值
            parameters = json.loads(request_parameters)
            parameters[row[0]] = value
            parameters_new = json.dumps(parameters, indent=4, ensure_ascii=False)
            sheet['F' + i] = parameters_new  # 具体步骤——请求参数
            sheet['F' + i].alignment = Alignment(wrapText=True)
            if row[3] == '是' and value is None:  # 必填 且 值为null  提示参数为必填
                sheet['G' + i] = 'status为' + status + ',' + row[0] + '为必填项'
            elif row[3] == '否' and value is None:  # 非必填 且 值为null  正确显示返回值
                sheet['G' + i] = '1、status为' + status_code + ',操作成功' + '\n' + '2、返回值与mrd定义一致'
                sheet['G' + i].alignment = Alignment(wrapText=True)  # 防止openpyxl修改样式,保持换行格式
            else:  # 非null且必填 非null且非必填  提示参数错误
                sheet['G' + i] = 'status为' + status + ',' + row[0] + '参数异常'

            # 发起post请求,根据响应状态码判断是否通过,并且填写QA结论
            # result = requests.post(url=base_url, data=parameters_new)
            # if result.status_code == status:
            #     sheet['K' + i] = 'pass'
            # else:
            #     sheet['K' + i] = 'fail'

        def reverse_cases_two(case_name='为NULL-异常', values=None):  # 第二层参数反向用例
            sheet['A' + i] = title1 + '-' + row[1] + case_name
            sheet['B' + i] = '中高(1)'
            sheet['C' + i] = '手工用例'
            sheet['D' + i] = version
            sheet['E' + i] = request_method
            sheet['E' + i].alignment = Alignment(wrapText=True)
            # 编辑参数的值
            parameters = json.loads(request_parameters)
            for key, value in parameters.items():  # 循环遍历字典
                if isinstance(value, dict):  # 判断字典中的值是否为字典
                    if row[1] in value:  # 是字典,再判断第二个参数是否在这个字典里
                        value[row[1]] = values  # 在字典里,对这个参数进行赋值
            parameters_new = json.dumps(parameters, indent=4, ensure_ascii=False)
            sheet['F' + i] = parameters_new  # 具体步骤——请求参数
            sheet['F' + i].alignment = Alignment(wrapText=True)
            if row[3] == '是' and values is None:  # 必填 且 值为null  提示参数为必填
                sheet['G' + i] = 'status为' + status + ',' + row[1] + '为必填项'
            elif row[3] == '否' and values is None:  # 非必填 且 值为null  正确显示返回值
                sheet['G' + i] = '1、status为' + status_code + ',操作成功' + '\n' + '2、返回值与mrd定义一致'
                sheet['G' + i].alignment = Alignment(wrapText=True)  # 防止openpyxl修改样式,保持换行格式
            else:  # 非null且必填 非null且非必填  提示参数错误
                sheet['G' + i] = 'status为' + status + ',' + row[1] + '参数异常'

            # 发起post请求,根据响应状态码判断是否通过,并且填写QA结论
            # result = requests.post(url=base_url, data=parameters_new)
            # if result.status_code == status:
            #     sheet['K' + i] = 'pass'
            # else:
            #     sheet['K' + i] = 'fail'

        # 编写异常用例
        i = 3  # 设置当前行数interfaceCase
        for row in list(info_sheet.values)[8:]:  # 遍历interfaceInfo的接口信息
            i = str(i)
            # 第四个单元格有值,做进一步判断(有值说明是值不是字典,没有值说明该值为字典)
            if row[3]:
                # 第一个参数有值,使用第一个参数填写用例
                if row[0]:
                    # 第一个反向用例:不输入该参数-异常
                    sheet['A'+i] = title1+'-'+row[0]+'为空-异常'
                    sheet['B'+i] = '中高(1)'
                    sheet['C'+i] = '手工用例'
                    sheet['D'+i] = version
                    sheet['E'+i] = request_method
                    sheet['E'+i].alignment = Alignment(wrapText=True)
                    # 移除字典中的值
                    parameters = json.loads(request_parameters)
                    parameters.pop(row[0])
                    parameters_new = json.dumps(parameters, indent=4, ensure_ascii=False)
                    sheet['F' + i] = parameters_new  # 具体步骤——请求参数
                    sheet['F' + i].alignment = Alignment(wrapText=True)
                    if row[3] == '是':  # 判断该参数是否为必填项
                        sheet['G' + i] = 'status为' + status + ',' + row[0] + '为必填项'
                    else:
                        sheet['G' + i] = '1、status为' + status_code + ',操作成功' + '\n' + '2、返回值与mrd定义一致'
                        sheet['G' + i].alignment = Alignment(wrapText=True)  # 防止openpyxl修改样式,保持换行格式

                    # 该参数第一个反向用例写入完成,换行写入第二条反向用例,为null-异常
                    i = int(i)
                    i += 1
                    i = str(i)
                    reverse_cases('为null-异常', None)

                    # 该参数第二个反向用例写入完成,换行写入第三条反向用例,为乱码-异常
                    i = int(i)
                    i += 1
                    i = str(i)
                    reverse_cases('为乱码-异常', '5rhGF325b2Zsq2c3AX8KXI6YFiXg1')

                    # 该参数第三个反向用例写入完成,换行写入第四条反向用例,为其他类型参数-异常
                    i = int(i)
                    i += 1
                    i = str(i)
                    if type(row[2]) == float:
                        input_value = str("字符串类型")
                    elif type(row[2]) == int:
                        input_value = str("字符串类型1")
                    elif type(row[2]) == str:
                        input_value = 500
                    reverse_cases('为其他类型参数-异常', input_value)

                # 第一个参数没有值,使用第二个参数填写用例
                else:
                    sheet['A' + i] = title1 + '-' + row[1] + '为空-异常'
                    sheet['B' + i] = '中高(1)'
                    sheet['C' + i] = '手工用例'
                    sheet['D' + i] = version
                    sheet['E' + i] = request_method
                    sheet['E' + i].alignment = Alignment(wrapText=True)
                    # 移除嵌套字典中的值
                    parameters = json.loads(request_parameters)
                    for key, value in parameters.items():  # 循环遍历字典
                        if isinstance(value, dict):  # 判断字典中的值是否为字典
                            if row[1] in value:  # 是字典,再判断第二个参数是否在这个字典里
                                value.pop(row[1])  # 在字典里,就移除这个参数
                    parameters_new = json.dumps(parameters, indent=4)
                    sheet['F' + i] = parameters_new  # 具体步骤——请求参数
                    sheet['F' + i].alignment = Alignment(wrapText=True)
                    if row[3] == '是':  # 判断该参数是否为必填项
                        sheet['G' + i] = 'status为'+status+','+row[1]+'为必填项'
                    else:
                        sheet['G' + i] = '1、status为'+status_code+',操作成功'+'\n'+'2、返回值与mrd定义一致'
                        sheet['G' + i].alignment = Alignment(wrapText=True)  # 防止openpyxl修改样式,保持换行格式

                    # 该参数第一个反向用例写入完成,换行写入第二条反向用例,为null-异常
                    i = int(i)
                    i += 1
                    i = str(i)
                    reverse_cases_two('为null-异常', None)

                    # 该参数第二个反向用例写入完成,换行写入第三条反向用例,为乱码-异常
                    i = int(i)
                    i += 1
                    i = str(i)
                    reverse_cases_two('为乱码-异常', '5rhGF325b2Zsq2c3AX8KXI6YFiXg1')

                    # 该参数第三个反向用例写入完成,换行写入第四条反向用例,为其他类型参数-异常
                    i = int(i)
                    i += 1
                    i = str(i)
                    if type(row[2]) == float:
                        input_value = str("字符串类型")
                    elif type(row[2]) == int:
                        input_value = str("字符串类型1")
                    elif type(row[2]) == str:
                        input_value = 500
                    reverse_cases_two('为其他类型参数-异常', input_value)

                i = int(i)
                i += 1  # 设置当前行数

    # 保存工作表
    interface_case.save(lujing)


if __name__ == '__main__':
    # lujing 接口用例 生成地址+文件名称
    # lujing_info 接口信息文档 地址+文件名称
    lujing = '/Users/v_wangaiguo/Documents/practice/工作簿2测试用例.xlsx'
    lujing_info = '/Users/v_wangaiguo/Documents/practice/interfaceInfo模板.xlsx'
    interfaceCase(lujing=lujing, lujing_info=lujing_info)

资源下载

想要直接拿来用的同学,可以直接下载,里面有具体的操作说明

自动生成接口用例工具.zip-项目管理文档类资源-CSDN下载

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值