1、参数化梳理
所有excel里要引用的变量,都放到全局变量里
生成的三个用户信息,满足大部分的变量
少数变量,使用setter进行设置
# 创建一个不存在的用户id,并加入到全局数据池中 setattr(GlobalData, "${not_existed_id}", cls.do_mysql.get_not_existed_user_id())
# 不存在的用户ID获取sql方法
def get_not_existed_user_id(self): sql = do_yaml.get_data('mysql', 'select_max_userid_sql') not_existed_id = self.get_one_value(sql).get('id') + 1 # 获取最大的用户id + 1 return not_existed_id
2、数据校验
多个断言校验-将获取的返回值转化为字典,然后excel的json也转化为字典
多次断言对应的字段
@ddt.data(*testcases_data) def test_login(self, one_testcase): # 获取全局变量 getattr(GlobalData, "${invest_user_tel}") new_data = Parameterize.to_parma(one_testcase.data) new_url = do_yaml.get_data("api", "base_url") + one_testcase.url res = self.do_request.send(one_testcase.method, new_url, json=new_data) # 判断两个及两个以上断言方法 # 步骤1:接口调用返回结果返回为字典类型 actual_value = res.json() # 步骤2:将excel中读取的expected_value期望值转为字典类型, expect_value = json.loads(one_testcase.expected_value, encoding='utf-8') try: # for item in eval(one_testcase.expected_value): # self.assertIn(item, # res.text, # one_testcase.name) # 步骤3:结果对比 self.assertEqual(expect_value.get('code'), actual_value.get('code'), one_testcase.name) self.assertEqual(expect_value.get('msg'), actual_value.get('msg'), one_testcase.name) except AssertionError as e: # my_logger.error(f"{one_testcase.name}:具体异常为{e}") do_log.error(f"{one_testcase.name}:具体异常为{e}") self.do_excel.write_data(one_testcase, res.text, "失败") raise e else: self.do_excel.write_data(one_testcase, res.text, "成功")
3、mock
mock其实就是mock后的值(
mock.Mock(return_value=one_dict)
),赋值给还没写好的方法或者不能测试的接口(
alipay
)
# 一、哪些场景下会用到mock呢? # 1、第三方接口 # a.别人的接口 # b.在测试阶段,可能无法调用 # 2、开发未完成的接口 # a.一个业务流需要依赖未完成的接口才能测 # b.有必要使用假数据(接口)来辅助测试 from unittest import mock import requests def alipay(): """ 此函数类比为支付宝的支付接口(在测试阶段不能访问) 当前不能调用的支付宝的接口 :return: """ # url乱写的,模拟不能访问的场景 res = requests.get("http://sddhosd.lemon/shoshsohsd") return res.status_code def do_pay(card_num, password): """ 类比为开发写的支付流程接口,需要调用第三方支付宝接口 :param card_num: :param password: :return: """ print("1、验证账号信息成功") print("2、调用支付宝接口进行支付") return alipay() if __name__ == '__main__': # do_pay("1000", "123456") one_dict = { "code": "10001", "msg": "支付成功" } # a.创建一个Mock对象,将第三方支付函数覆盖 # b.do_pay函数调用alipay函数时,不会真正去调用支付宝的接口,而是直接返回我们指定的返回值(return_value) alipay = mock.Mock(return_value=one_dict) result = do_pay("1000", "123456") print(result)
4、V3版本
假如为V3版本才导入加密的
HandleSign
timestamp+token+sign
当X-Lemonban-Media-Type请求头值为lemonban.v3时,接口使用timestamp+token+sign 鉴权。除注册、登录和项目列表接口,其它接口需要进行如下设置:
1. 设置Authorization请求头,值为Bearer token值
2. 请求体json 设置timestamp参数,值为当前时间戳(注意是秒级时间戳),类型为long
3. 请求体json设置sign参数,取token前50位再拼接上timestamp值,然后通过RSA公钥加 密得到的字符
# 获取api版本信息 api_version = do_yaml.get_data("api", "api_version").get("X-Lemonban-Media-Type") if api_version == "lemonban.v3": # 如果为v3版本, 才导入HandleSign from scripts.handle_sign import HandleSign
请求体中添加参数
if hasattr(self, 'token') and api_version == "lemonban.v3": # 如果为v3版本, 则添加sign参数 sign_dict = HandleSign.generate_sign(getattr(self, "token")) # 生成sign和timestamp组成的字典 # 由于json传参和www-form-encode 不会同时传递 # 只要某一个参数不为None,则合并sign和timestamp参数 if kwargs["json"] is not None: kwargs["json"].update(sign_dict) elif kwargs["data"] is not None: kwargs["data"].update(sign_dict)