前方高能!!正文开始!

在前几章做好的基础上
此章详细讲解数据关联的思路和用法!!

实现接口1的返回值的某一具体参数,在接口2中使用

1、新增文件test_data.txt:

#该文件用来存放 (存放接口1返回的数据):

数据关联与python python 数据关联_数据


2、在创建读取文件函数前先到setting.py内新增:

TEST_JSON = os.path.join(PROJECT_ROOT, 'database', 'test_data.txt')  #存放接口返回数据

3、创建文件后需要用方法读取、data_driver新增load_data()函数:
使用用setting.TEST_JSON代替读取路径
*函数作用:读取test_data内数据

def load_data() -> dict:
    """
    返回test_data内的数据
    :return:
    """
    #setting.TEST_JSON 为setting.py
    with open(setting.TEST_JSON, encoding='utf-8') as file_obj:
        for line in file_obj:
            token_data = eval(line)
            return token_data

4、data_driver新增data_association()函数:
函数作用:用来替换数据,返回替换完成后的数据

def data_association(replace_data, request_data):
    """
    判断是否调用上一个接口返回的数据当此次访问的参数,并返回数据
    :param replace_data: 上个接口返回的数据
    :param request_data: 当前接口的请求测试数据
    :return:请求参数 dict格式
    """
    # 正则表达式带^特殊符号开头的内容
    pattern = re.compile(r"'\^([\s\S]+?)'")
    # 拿到匹配的内容 key列表内的值为replace_data的键
    keys = re.findall(pattern, str(request_data))
    # 如果request_data内没有^,直接返回原数据
    if len(keys) <= 0:
        return request_data
    # 当前匹配出来的内容
    present = []
    # 拿着这个key 去上个接口里面得到想要的内容
    for key in keys:
        try:
            a = replace_data['{}'.format(key)]
        except Exception:
            a = request_data
        # 每次匹配出来内容都进行遍历装进list中
        present.append(a)
    # 从index 0开始  根据原值内容 直接进行替换,然后直接返回
    for i in range(0, len(present)):
        # key[i]是原来的值  present是获取的值 最后将特殊符号处理掉
        request_data = str(request_data).replace(keys[i], str(present[i])).replace('^', '')
    return request_data

写入如下代码测试结果(不然写一大堆最后执行不了很蛋疼!):

*先在test_data写入内容{‘code’: 0, ‘msg’: ‘ok’, ‘value’: 3}

数据关联与python python 数据关联_数据_02

if __name__ == '__main__':
    """
    用test_data数据{'code': 0, 'msg': 'ok', 'value': 3}中的code,value的值分别代替data内的code,value
    """
    data = {'a': '^code', 'b': '^value'}
    print('test_data内的数据:', load_data())  # test_data内的数据(接口1返回的结果)
    print('替换前的参数:', data)  # 未替换前的参数
    print('替换后的参数:', data_association(load_data(), data))  # 替换完成后的参数(接口2的请求数据)

运行成功打印如下信息:

数据关联与python python 数据关联_python_03

5、test_case.xlsx内新增数据字段如下:

新增前置条件字段,新增一条case

数据关联与python python 数据关联_数据_04


因为新增字段,需要修改excel_dict函数:

def excel_dict(data):
    """
    1.将excel头部替换成英文的
    2.处理成json/dict格式
    """
    header = {
        '用例编号': 'id',
        '请求类型': 'get_type',
        '测试url': 'url',
        '测试接口': 'interface',
        '用例标题': 'title',
        '测试数据': 'data',
        '预期结果': 'expected',
        '请求头': 'header',
        '响应数据状态/json返回数据的code': 'code',
        '状态码': 'status',
        '响应状态': 'msg',
        '前置条件': 'precondition' #新增对新字段的处理
    }
    head = []
    list_dict_data = []
    for d in data[1]:
        # 获取到英文的头部内容如果为中文,则替换成英文 进行改成一个k
        # 传入两个参数的作用是 查到则返回查到的数据查不到则返回传入的原数据
        d = header.get(d, d)
        # 将去除的头部英文装进list中
        head.append(d)
    # 获取到数据进行切片处理,0坐标为标题,1坐标是头部
    for b in data[2:]:
        # 头部和内容拼接为json串
        dict_data = {}
        for i in range(len(head)):
            # 之所以判断类型,如果不进行判断会出现str的错误,strip去除空格也有转str的用法
            if isinstance(b[i], str):
                dict_data[head[i]] = b[i].strip()
            else:
                dict_data[head[i]] = b[i]
        # list里面是字典格式
        list_dict_data.append(dict_data)
    return list_dict_data

6、修改send_request函数前在data_driver内新增data_processing()函数:
用来处理数据的类型

def data_processing(variate):
    """
    判断数据类型是否为字典,若不是dict则转换成dict
    :param variate:  数据
    :return:  dict
    """
    global false, null, true
    false = False
    null = None
    true = True
    if variate == '':
        return variate
    if isinstance(variate, str):
        return eval(variate)
    elif isinstance(variate, dict):
        return variate
    elif variate is None:
        return None

创建完成方法后:

  • 新增数据关联
  • 进入sendrequest.py文件内
def send_requests(apidata):
    """
    分析测试用例自带参数、发送请求
    :param apidata: 测试用例
    :return:
    """
    try:
        # 从读取的表格中获取响应的参数作为传递
        method = apidata["get_type"]
        url = apidata["url"]
        if apidata["header"] == '':
            header = None
        else:
            header = eval(apidata["header"])
        # 判断表内是否有测试数据
        if apidata["data"] == "":
            body_data = None
        else:
        	#使用data_association函数判断是否需要替换某些数据
            body_data = eval(data_association(load_data(), apidata['data'])) #新增数据关联的处理
        logging.info('请求参数:{}'.format(body_data)) #新增打印参数log,方便查看
        s = requests.session()
        re = s.request(method=method, url=get_test_url('loc') + url, headers=header,
                       json=body_data)
        return re
    except Exception as error:
        logging.error("错误信息", error)

写入如下代码测试结果(不然写一大堆最后执行不了很蛋疼!):

if __name__ == '__main__':
    case_dict = {'id': 3.0, 'get_type': 'post', 'interface': '相减接口', 'title': '参数正常-成功', 'header': '',
                 'precondition': '', 'url': '/less', 'data': "{'a': '^code', 'b':'^value'}",
                 'expected': "{'code': 1000, 'msg': 'success', 'value': -3}", 'code': 1000.0, 'status': 200.0,
                 'msg': 'success'}

    re = send_requests(case_dict)
    print(re.url)
    print(re.json())

运行结果如下:

数据关联与python python 数据关联_测试工程师_05

最后在函数TestCase内新增一段代码:

@ddt.ddt
class TestCase(unittest.TestCase):

    @ddt.data(*case_data('testcase'))
    def test_run_case(self, data):
        """
        执行测试脚本
        :param data: 参数化后测试用例|dict类型
        :return:
        """
        self.response = send_requests(data)  # 返回response
        print('________________________________')
        logging.info("页面返回信息:%s" % self.response.json())
        self.result = self.response.json()
        code = data['code']  # 获取表内code
        status = data['status']  # 获取表内状态码
        msg = data['msg']  # 获取响应状态
        # 判断前置条件是否为1 ---新增
        if data['precondition'] == 1:
            # 为1:将内容写进test_data文件用来替换下个接口的参数
            with codecs.open(setting.TEST_JSON, 'w', encoding='utf-8') as f:
                json.dump(self.result, f)

        if code == self.result['code'] and status == self.response.status_code \
                and msg == self.result['msg']:  # 判断返回数据是否和表内数据相同
            self.msg_data = "PASS"
        else:
            self.msg_data = "FAIl"
        Excel('w', results_root) \
            .write(write_result(value7=str(self.result), value8=self.msg_data))
        self.assertEqual(self.result['code'], code)
        self.assertEqual(self.response.status_code, status)
        self.assertEqual(self.result['msg'], msg)

运行testcase如下:

数据关联与python python 数据关联_python_06


这样就完成数据关联了! 第三条请求的参数等于第一个返回的数据(可自己进一步修改数据验证)