接口自动化框架搭建 pytest

接口自动化框架搭建,持续更新中。。。

接口自动化框架架构

请添加图片描述
简介:
一个excel文件代表一个项目,一个项目中的每个sheet就是一个模块,一个模块中写正常用例和异常用例,extract列用来提取返回参数中的数据,提取后将保存于variables.ini配置文件中,引用时用${变量}引用变量或者${func()}引用自定义方法,如随机数生成方法。运行前先指定环境,根据环境匹配对应环境的域名,可以选择项目、模块、具体用例进行运行。运行后生成测试报告。django实现web前端页面,不用再关注代码进行接口自动化。用jenkins实现定时运行,异常时发邮件告警。
分层:
在这里插入图片描述

1.用例管理✅

一个excel文件就是一个项目,一个项目中的每个sheet就是一个模块,一个模块中写正常用例和异常用例
在这里插入图片描述

2.提取数据进行数据关联 ——>难点

✅用一列来专门提取数据,格式是字典,key为被赋值的变量,value为jsonpath要查询的接口返回的字段key,运行时
判断如果有需要提取数据,则将数据进行保存到ini配置文件中
✅引用时通过${变量}方式提取,用re库操作,re.sub()或直接replace()进行替换
✅引用自定义函数(如要生成随机数等),${func()}进行引用,用反射原理来执行函数并返回内容,然后re.sub() 或者 replace()进行替换。

提取变量:

# 提取参数
def extract(extract, res_text):
    vaiable_ini = '%s/config/variable.ini' % BASEDIR
    try:
        if extract and isinstance(eval(extract), dict):
            extract = eval(extract)
            print(type(res_text))
            for k, v in extract.items():
                value = str(jsonpath.jsonpath(json.loads(res_text), '$..%s' % v))[1:-1]  # jsonpath进行模糊匹配
                Config(vaiable_ini).write_varables(section='response',
                                                   option=extract.get(k),
                                                   value=value
                                                   )
    except NameError:
        print('返回参数提取异常:', traceback.format_exc())

variable.ini文件:
在这里插入图片描述
自定义的方法
在这里插入图片描述

引用变量和自定义方法变量(有部分代码写的冗余,暂不进行优化):

# 参数引用${variable}、${func()}
def quote(headers, payloads)->tuple:
    """re.sub()进行动态替换"""
    """
    1.re.findall() 匹配到所有的${} 和 ${func()} 各返回一个列表,
    2.检查是否存在于ini配置文件中,存在则re.sub替换,重新赋值给新的headers或payloads变量
    3.用反射的方式检查类中是否有这个方法,有则执行,返回结果,然后再re.sub替换或replace(),重新赋值给headers或payloads变量
    """

    # 正则匹配到所有引用变量列表,格式如:['random()', 'token', 'name']
    headers_virables_quotes = re.findall(r'\$\{(.*?)\}', headers)
    payloads_virables_quotes = re.findall(r'\$\{(.*?)\}', payloads)

    valiadate_ini = '%s/config/variable.ini' % BASEDIR


    # 对headers的操作
    for hvq in headers_virables_quotes:
        if hvq.endswith('()'):
            # 进行反射操作
            if hasattr(CustomFunc(), hvq[:-2]):
                fun = getattr(CustomFunc(), hvq[:-2])
                value = fun()
                headers = headers.replace('${%s}' % hvq, "\'%s\'" % value)  # 注意:header的value必须都是字符串
            else:
                raise Exception('没有找到对应变量${%s}' % hvq)
        else:
            # 在ini文件中判断是否存在变量
            if Config(valiadate_ini).has_option('custom', hvq):
                quote_value = Config(valiadate_ini).read_variables('custom', hvq)
                headers = headers.replace('${%s}' % hvq, quote_value)
            elif Config(valiadate_ini).has_option('response', hvq):
                quote_value = Config(valiadate_ini).read_variables('response', hvq)
                headers = headers.replace('${%s}' % hvq, quote_value)
            else:
                raise Exception('没有找到对应变量${%s}' % hvq)

    # 对payloads的操作
    for pvq in payloads_virables_quotes:
        if pvq.endswith('()'):
            # 进行映射操作
            if hasattr(CustomFunc(), pvq[:-2]):
                fun = getattr(CustomFunc(), pvq[:-2])
                value = fun()
                payloads = payloads.replace('${%s}' % pvq, str(value))
            else:
                raise Exception('没有找到对应变量${%s}' % pvq)
        else:
            # 在ini文件中判断是否存在变量
            if Config(valiadate_ini).has_option('custom', pvq):
                quote_value = Config(valiadate_ini).read_variables('custom', pvq)
                payloads = payloads.replace('${%s}' % pvq, quote_value)
            elif Config(valiadate_ini).has_option('response', pvq):
                quote_value = Config(valiadate_ini).read_variables('response', pvq)
                payloads = payloads.replace('${%s}' % pvq, quote_value)
            else:
                raise Exception('没有找到对应变量${%s}' % pvq)

    return headers, payloads

3.url组合✅

excel表格中用path,运行时通过输入环境参数,和表中的服务名,在ini配置文件中进行匹配对应的域名,和path组合成完整的url
env_host.ini:
在这里插入图片描述
url_util():

# 根据环境,选择对应的域名
def url_util(host_dev, svr_name, path)->str:
    if host_dev == 'dev':
        host = Config(Run.env_ini).read_variables('host-dev', svr_name)
    elif host_dev == 'test':
        host = Config(Run.env_ini).read_variables('host-test', svr_name)
    else:
        host = Config(Run.env_ini).read_variables('host-yace', svr_name)

    url = 'http://%s%s' % (host, path)

4.run运行时选择环境与指定用例执行范围✅

指定环境:
Run函数运行是,先确定环境:fixfure函数通过读取ini配置文件中的配置信息,进行传入环境参数,进而在测试用例里通过服务名,组合成对应环境的url
在这里插入图片描述
指定范围:
在这里插入图片描述

    # 用于指定项目、模块运行
    def handel_data(self, *args) ->list:
        # 格式校验
        if len(args) <= 0:
            raise Exception("请输人正确的运行用例范围,如:全部-->all,项目-->project,项目、模块-->project, module1, module2")

        all_cases = []  # 全部用例,格式[{},{},{}]
        excel_files = os.listdir('%s/data/excelcases' % BASEDIR)  # 用例文件 【文件1, 文件2】
        excel_files.pop(excel_files.index('__init__.py'))

        # 运行全部项目用例
        if args[0] in ['all', '全部']:
            # 获取所有excel用例文件目录
            for excel_file in excel_files:
                path = '%s/data/excelcases/%s' % (BASEDIR, excel_file)
                result_values = list(self.read_excel(path).values())
                # print(result_values)
                for result_value in result_values:
                    for value in result_value:
                        all_cases.append(value)
            return all_cases

        # 运行全部冒烟(正常)用例
        elif args[0] in ['冒烟', '正常']:
            print('走冒烟')
            # 获取所有excel用例文件目录
            for excel_file in excel_files:
                path = '%s/data/excelcases/%s' % (BASEDIR, excel_file)
                result_values = list(self.read_excel(path).values())
                # print(result_values)
                for result_value in result_values:
                    for value in result_value:
                        # print(value)
                        if '冒烟' in value['case_name'] or '正常' in value['case_name']:
                            all_cases.append(value)
            print("all cases:\n", all_cases)
            return all_cases


        # 根据项目、模块自定义选择运行
        else:
            if args[0] not in excel_files:
                raise Exception('%s项目excel文件不存在,请核实!', args[0])
            else:
                path = '%s/data/excelcases/%s' % (BASEDIR, args[0])
                result = self.read_excel(path)
                print(result)
                result_new = {}
                args_modules = args[1:]
                # print(args)
                result_keys = list(result.keys())

                # print(result_keys)
                if len(args_modules) == 0:   # 指定项目运行(运行项目下的全部)
                    result_values = list(result.values())
                    for result_value in result_values:
                        for case in result_value:
                            all_cases.append(case)
                else:   # 指定项目-模块运行
                    for arg in args_modules:
                        if arg not in result_keys:
                            raise Exception('%s项目中不存在模块%s' % (args[0], arg))
                        else:
                            result_new[arg] = result[arg]

                    result_values = list(result_new.values())

                    for result_value in result_values:
                        for value in result_value:
                            # print(value)
                            all_cases.append(value)

            # print("all cases:\n", all_cases)
            return all_cases

        # 根据接口名,或接口id,运行指定的接口:todo

5.用例前后置✅

使用conftest.py 和 fixture来实现

# 用例运行前后置的操作
@pytest.fixture(scope='module', autouse=True)
def setup_teardown(request):
    variable_ini = '%s/config/variable.ini' % BASEDIR  # 保存变量文件

    # 1.所有用例运行前,清空variable.ini中[response]下的变量
    options = Config(variable_ini).get_options('response')
    print("运行前操作:\n1.删除response下的optons变量%s" % options)
    if options:
        for option in options:
            Config(variable_ini).rm_option('response', option)
    yield
    print("运行后操作:\n暂无。")

✅6.生成测试报告

生成html的测试报告,报告优化,将接口返回都给展示

生成allure测试报告,优化报告

⏸7.测试结果回填excel表

⏸8.日志实现

⏸9.有异常时发送邮件,并带附件

⏸10.指定执行错误的用例、跳过用例、运行冒烟用例等

⏸11.用django实现web调用,页面的方式进行选择运行项目,模块,并可查看报告

⏸12.将项目容器化运行

⏸13.用jenkins进行定时运行

  • 6
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Python请求库`requests`是一个非常流行的库,用于向HTTP服务器发送请求和处理响应。`pytest`则是一个用于编写自动化测试的框架,结合`requests`可以很方便地搭建一个Python接口自动化测试框架搭建Python接口自动化测试框架的步骤如下: 1. 安装`requests`和`pytest`库:在命令行中使用pip工具安装这两个库。例如,运行 `pip install requests pytest`。 2. 创建测试目录和文件:创建一个目录来保存测试用例和相关文件。可以将这个目录命名为“tests”。在此目录中创建一个Python文件,用于编写测试用例。 3. 编写测试用例:在测试文件中,使用`pytest`框架提供的装饰器`@pytest.mark`来标记测试用例。然后在测试用例中,使用`requests`库来发送请求,并对响应进行断言验证。 4. 运行测试:在命令行中进入测试文件所在的目录,运行`pytest`命令来运行测试用例。`pytest`会自动去发现并执行测试文件中以`test_`开头的函数。 5. 查看测试报告:`pytest`会输出详细的测试报告,包括每个测试用例的执行结果、断言失败的信息等。 为了让测试代码更加组织和可维护,可以考虑使用`pytest`提供的一些功能,如夹具(fixtures)和参数化(parametrization)。夹具可以在测试用例之前或之后执行一些前置或后置操作,例如设置和清理测试环境。参数化可以让一个测试用例根据不同的输入数据运行多次,减少重复的代码。 总结一下,使用`pytest`框架结合`requests`库可以很方便地搭建一个Python接口自动化测试框架。通过编写测试用例和使用`pytest`的一些功能,可以实现高效、可维护的接口自动化测试,并生成详细的测试报告。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值