day23-20200511_pymysql封装_参数化_数据校验
1、pymysql封装
注意点:
连接参数直接从yaml文件中获取,创建对象的时候直接连接数据库和创建游标
增删改查的调用,传入sql,和sql中引入的参数,参数默认为None,sql返回是否为None,通过 is not None进行判断
最后关闭游标和数据库
再创建跟项目相关的方法,跟项目相关,但和sql无关,所以创建静态方法
import pymysql import random from scripts.handle_yaml import do_yaml class HandleMysql: """ 执行sql语句 """ def __init__(self): self.conn = pymysql.connect(host=do_yaml.get_data('mysql', 'host'), user=do_yaml.get_data('mysql', 'user'), password=do_yaml.get_data('mysql', 'password'), db=do_yaml.get_data('mysql', 'db'), port=do_yaml.get_data('mysql', 'port'), charset='utf8', # 这里只能写为utf8 cursorclass=pymysql.cursors.DictCursor) self.cursor = self.conn.cursor() def get_one_value(self, sql, args=None): self.cursor.execute(sql, args=args) self.conn.commit() return self.cursor.fetchone() def get_values(self, sql, args=None): self.cursor.execute(sql, args=args) self.conn.commit() return self.cursor.fetchall() def close(self): self.cursor.close() self.conn.close() @staticmethod def create_mobile(): """ 随机生成11位手机号 :return: 返回一个手机号字符串 """ start_mobile = ['138', '139', '188'] start_mobile = random.choice(start_mobile) end_num = ''.join(random.sample('0123456789', 8)) return start_mobile + end_num def is_existed_mobile(self, mobile): """ 判断指定的手机号在数据库中是否存在 :param mobile: 11位手机号组成的字符串 :return: True or False """ # sql = "SELECT mobile_phone FROM member WHERE mobile_phone=%s;" sql = do_yaml.get_data('mysql', 'select_user_sql') if self.get_one_value(sql, args=[mobile]): # 手机号已经存在,则返回True,否则返回False return True else: return False def create_not_existed_mobile(self): """ 随机生成一个在数据库中不存在的手机号 :return: 返回一个手机号字符串 """ while True: one_mobile = self.create_mobile() if not self.is_existed_mobile(one_mobile): break return one_mobile ''' 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 def get_not_existed_loan_id(self): sql = do_yaml.get_data('mysql', 'select_max_loan_id_sql') not_existed_id = self.get_one_value(sql).get('id') + 1 # 获取最大的用户id + 1 return not_existed_id ''' if __name__ == '__main__': # mobile = '13888888888' # sql_1 = "SELECT * FROM member WHERE mobile_phone=%s" # sql_2 = "SELECT * FROM member LIMIT 0, 10;" do_mysql = HandleMysql() # res1 = do_mysql.get_one_value(sql_1, args=(mobile, )) # print(res1) # # res2 = do_mysql.get_values(sql_2) # print(res2) do_mysql.create_not_existed_mobile()
2、参数化
注意点:
万能匹配 : .*? 匹配任意数据
创建全局数据池类,每个接口调用,直接先创建三个用户,set属性,然后用例中调用这三个属性
to_parma(src)字符串中包含${XXXX}的变量全部从全局变量中获取对应的参数值
# 0、导入re模块 import re # 1、创建全局数据池类 # 存储全局数据(三个用户账号、未注册的手机号等) class GlobalData: pass # 2、定义原始字符串 # {"mobile_phone": "${not_existed_tel}", "pwd": "12345678", "type": 1, "reg_name": "KeYou"} # {"mobile_phone": "18900001111", "pwd": "12345678", "type": 1, "reg_name": "KeYou"} # one_str = '{"mobile_phone": "${not_existed_tel}", "pwd": "12345678", "type": 1, "reg_name": "KeYou"}' # one_str = '{"mobile_phone": "${not_existed_tel}", "pwd": "12345678", "uid":" ${user_id}", "type": 1, "reg_name": "KeYou"}' # 3、定义正则表达式 # a.findall方法将正则匹配上的值放在列表中返回 # b.第一个参数为正则表达式,需要在字符串前加r # c.第二个参数为待匹配的字符串 # d.如果匹配不上,会返回空列表 # e.$有特殊含义,所以需要使用\来转义 # f. .*?可以匹配任意数据,为非贪婪模式进行匹配 # result = re.findall(r"\${.*?}", one_str) # for item in result: # data = getattr(GlobalData, item) # one_str = one_str.replace(item, str(data)) class Parameterize: @staticmethod def to_parma(src): # a.把src字符串中的说哟${}查询出来,返回一个列表 result = re.findall(r"\${.*?}", src) for item in result: # b.从全局数据池中读取参数 data = getattr(GlobalData, item) # c.替换指定的数据,然后将原始字符串src覆盖 # 也可以使用re.sub去替换 src = src.replace(item, str(data)) return src if __name__ == '__main__': # one_str = '{"mobile_phone": "${not_existed_tel}", "pwd": "12345678", "uid":" ${user_id}", "type": 1, "reg_name": "KeYou"}' two_str = '{"mobile_phone": "${invest_user_tel}", "pwd": "12345678", "reg_name": "KeYou"}' setattr(GlobalData, "${not_existed_tel}", "18911112222") setattr(GlobalData, "${user_id}", "3333") setattr(GlobalData, "${invest_user_tel}", "18911114444") Parameterize.to_parma(two_str) pass
创建用户的封装
先查询这个用户是否存在,不存在才创建,注册后保存三个属性
并设置全局变量池的属性
from scripts.handle_request import HandleRequest from scripts.handle_mysql import HandleMysql from scripts.handle_yaml import do_yaml from scripts.handle_parameterize import GlobalData def create_user(reg_name, password=12345678, type=1): """ 创建用户并将用户信息,添加至全局数据池中 :param reg_name: 用户昵称 :param password: 用户密码,默认为12345678 :param type: 用户类型,默认为1,普通用户 :return: """ do_request = HandleRequest() do_mysql = HandleMysql() # 获取未注册手机号 mobile_phone = do_mysql.create_not_existed_mobile() # 构造请求参数 param = { "mobile_phone": mobile_phone, "pwd": password, "reg_name": reg_name, "type": type } # 构造请求url路径 url = "http://api.lemonban.com/futureloan/member/register" # 获取api头信息 do_request.add_headers(do_yaml.get_data("api", "api_version")) # 进行注册 res = do_request.send("POST", url, json=param) # sql = do_yaml.get_data("mysql", "select_user_sql") # do_mysql.get_values(sql, ) # 从响应报文中获取用户id user_id = res.json()["data"]["id"] # 关闭相关连接 do_request.close() do_mysql.close() # 将用户信息添加至全局数据池中 setattr(GlobalData, "${" + reg_name + "_user_tel}", mobile_phone) setattr(GlobalData, "${" + reg_name + "_user_pwd}", password) setattr(GlobalData, "${" + reg_name + "_user_id}", user_id) # setattr(GlobalData, f"{reg_name}_user_pwd", password) # setattr(GlobalData, f"{reg_name}_user_id", user_id) def generate_three_user(): """ 创建三个用户,管理员、投资员、借款人 :return: """ create_user("admin", type=0) create_user("invest") create_user("borrow") if __name__ == '__main__': # print(create_user("admin", type=0)) # print(create_user("invest")) # print(create_user("borrow")) # create_user("admin", type=0) generate_three_user()
3、数据校验
用例中获取全局变量和参数进行数值替换
@ddt.data(*testcases_data) def test_register(self, one_testcase): # 在每条用例执行之前,获取未注册的手机号码,然后更新全局数据池 setattr(GlobalData,"${not_existed_tel}",self.do_mysql.create_not_existed_mobile()) # 将excel中读取的请求参数进行转化 new_data = Parameterize.to_parma(one_testcase.data)
@ddt.data(*testcases_data) def test_login(self, one_testcase): # 获取全局变量 getattr(GlobalData, "${invest_user_tel}") new_data = Parameterize.to_parma(one_testcase.data)
登录后进行其他操作时,先有个登录接口调用,然后保存token到全局变量,方便其他用例调用
# 假如登录成功,则获取token,写入消息头 if "token_info" in res.text: token = res.json()["data"]["token_info"]["token"] self.do_request.add_headers("Authorization", f"Bearer {token}")