接口自动化(3)

requests工具类

请求:

定义方法传递关键参数url,method,header,body,……(只有url和method是必须的)

先判断是get还是post,再判断post的是JSON格式还是data格式。

定义空字典存放封装所有的响应。

import requests


class RequestSend:
    def api_run(self,url,method,data=None,headers=None,cookies=None):
        res=None
        if method=='get':
            res=requests.get(url=url,data=data,headers=headers,cookies=cookies)
        if method=='post':
            if headers == {"Content-Type": "application/json"}:
                # 发送http请求,方法为post,参数使用json=data
                res = requests.post(url, json=data, headers=headers, cookies=cookies)
                # 判断headers内容,如果是application/x-www-form-urlencoded格式
            elif headers == {"Content-Type": "application/x-www-form-urlencoded"}:
                # 发送http请求,方法为post,参数使用data=data
                res = requests.post(url, data=data, headers=headers, cookies=cookies)
        code=res.status_code
        cookies=res.cookies.get_dict()
        headers=res.headers
        try:
            body=res.json()
        except:
            print('error')
        dict1=dict()
        dict1['code']=code
        dict1['body']=body
        dict1['headers']=headers
        dict1['cookies']=cookies
        return dict1
    def send(self,url,method,**kwargs):
        return self.api_run(url,method,**kwargs)

res是赋值了get或者post方法response的对象。

send方法的参数传递方式是关键字,用的时候要用url=url的形式确定位置,毕竟不是位置参数传递。

接口测试核心:

import pytest

from utils.caseutil import RdTestCase
from utils.logutil import logger
from utils.requestutil import RequestSend

gongju2=RdTestCase()
gongju4=RequestSend()
case_list=gongju2.is_run_data('okr-api')
@pytest.mark.parametrize('case',case_list)
class TestApi:
    def test_run(self,case):
        url=gongju2.loadConfKey('atstudy_okr','url_api')+case['url']
        method=case['method']
        headers=eval(case['headers'])
        cookies = eval(case['cookies'])
        data=eval(case['request_body'])
        case_name=case['title']
        relation=case['relation']
        # print(f'============={case_name}=============')
        # print('................',type(relation))
        try:
            logger.info(f'the case {case_name} is running......')
            logger.debug(f'===={case_name}====')
            res_data=gongju4.send(url,method,data=data,headers=headers,cookies=cookies)
            logger.info(f'the result is {res_data}')
        except:
            logger.error(f'something is wrong......')
            assert False
if __name__ == '__main__':
    pytest.main(['-vs','test_run.py'])

case_list刚好是[]里面一个个的字典,传入参数化的pytest可以实现每条用例的传入。

截取case中的各种信息,交给send方法,注意:原本为字典的数据用eval()方法变回去,json.loads()方法更好。

url要拼接使用。

pytest.main([‘-vs’,’test_run.py’])的中括号不能少。

上下游接口:

上下游直接用变量传递不行,因为return,而且pytest构造方法不能改,有继承关系,会覆盖。

用动态属性或数据库共享数据。

思路:

1 准备文件 类来用来存放数据(临时)

2 判断上游用例(有授权码的),存到临时类里面

3判断下游用例(根据${}),取出数据,替换${},交给requests工具类,发出请求。

setattr方法的语法:

setattr(类对象,“属性名字”,“属性值”)  设置属性~

上游接口方法和调用:

import pytest

from config.settings import DynamicParam
from utils.caseutil import RdTestCase
from utils.logutil import logger
from utils.requestutil import RequestSend

gongju2=RdTestCase()
gongju4=RequestSend()
case_list=gongju2.is_run_data('okr-api')
@pytest.mark.parametrize('case',case_list)
class TestApi:
    def test_run(self,case):
        url=gongju2.loadConfKey('atstudy_okr','url_api')+case['url']
        method=case['method']
        headers=eval(case['headers'])
        cookies = eval(case['cookies'])
        data=eval(case['request_body'])
        case_name=case['title']
        relation=str(case['relation'])
        # print(f'============={case_name}=============')
        # print('................',type(relation))
        try:
            logger.info(f'the case {case_name} is running......')
            # logger.debug(f'===={case_name}====')
            res_data=gongju4.send(url,method,data=data,headers=headers,cookies=cookies)
            logger.info(f'the result is {res_data}')
            # 判断res_data是否存在
            if res_data:
                # res_data存在后,判断relation不为None
                if relation:
                    # 根据响应结果,以及关联信息(token=cookies.admin-token),设置变量token的值为响应结果的信息
                    self.set_relation(relation, res_data)  # 将需要关联的数据保留下来
                    logger.info("#####(the var is saved(^.^))######")

        except:
            logger.error(f'something is wrong......')
            assert False

        return res_data
    def set_relation(self,relation,res_data):
        # 异常处理
        try:
            if relation:
                # 根据=进行分割
                var = relation.split("=")

                left = var[0]

                right = var[1]
                print(f"var_tmp{right}")
                print(f"res_data{res_data}")

                res = res_data.get("headers").get(right, "no var!!!")
                # 打印信息
                print("res:", res)
                # 把定义的变量名称以及值 以属性的方式设置到DynamicParam类中,实现动态存储
                setattr(DynamicParam, left, res)
                # 验证:
                # 查看是否从结果中提取出了关联数据到DynamicParam
                print("验证是否存放了token数据:", left, getattr(DynamicParam, left, "没有提取到"))
        # 捕获异常
        except:
            print("处理断言失败")
if __name__ == '__main__':
    pytest.main(['-vs','test_run.py'])

下游接口代码:


评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注