def borrow_user_id_replace(cls, data): """ 替换参数化的借款用户id :param data: :return: """ do_config = HandleConfig(USER_ACCOUNTS_FILE_PATH) borrow_user_id = do_config("borrow_user", "id") if re.search(cls.borrow_user_id_pattern, data): data = re.sub(cls.borrow_user_id_pattern, str(borrow_user_id), data) if re.search(cls.not_existed_borrow_user_id_pattern, data): handle_mysql = HandleMysql() sql = "SELECT MAX(Id) AS max_id FROM member;" cls.not_existed_user_id = str(handle_mysql(sql)["Id"]+800) data = re.sub(cls.not_existed_borrow_user_id_pattern, cls.not_existed_user_id, data) return data
def invest_user_id_repalce(cls, data): id_config = HandleConfig(CONFIGS_USER_ACCOUNTS) if re.search(cls.invest_user_id_pattern, data): invest_id = id_config.get_value('invest_user', 'id') data = re.sub(cls.invest_user_id_pattern, invest_id, data) return data
def invest_user_pwd_replace(cls, data): pwd_config = HandleConfig(CONFIGS_USER_ACCOUNTS) if re.search(cls.invest_user_pwd_pattern, data): invest_pwd = pwd_config.get_value('invest_user', 'pwd') data = re.sub(cls.invest_user_pwd_pattern, invest_pwd, data) return data
def invest_user_tel_replace(cls, data): do_conig = HandleConfig(CONFIGS_USER_ACCOUNTS) if re.search(cls.invest_user_tel_pattern, data): invest_tel = do_conig.get_value('invest_user', 'mobilephone') data = re.sub(cls.invest_user_tel_pattern, invest_tel, data) return data
class TestRecharge(unittest.TestCase): do_config = HandleConfig(CONFIG_REQUEST) do_re = Handle_Re() do_request = HandleRequest() do_excel = HandleExcel(sheetname='recharge') cases = do_excel.get_cases() pass_result = do_config.get_value('result', 'pass_result') fail_result = do_config.get_value('result', 'fail_result') @classmethod def setUpClass(cls): cls.do_mysql = HandleMysql() cls.one_file = open(REPORTS_ALL_PATH, mode='a+', encoding='utf-8') cls.one_file.write('{:=^40s}\n'.format('开始执行充值接口用例')) @classmethod def tearDownClass(cls): cls.do_mysql.close() cls.one_file.write('{:=^40s}\n\n'.format('充值接口用例执行结束')) cls.one_file.close() @data(*cases) def test_recharge(self, one_case): # 拼接头部 url 和表格中的接口具体内容 new_url = self.do_config.get_value('url', 'head_url') + one_case['url'] # 获取表格中的请求方法 method = one_case['method'] # 获取表格中的接口请求数据 # input_data = one_case['input_data'] # 获取表格中check_sql 字段是否有内容 have_sql = one_case['check_sql'] if have_sql: # 如果 check_sql 的内容不为空 # SELECT LeaveAmount FROM member WHERE MobilePhone="${investors_login_mobile}" # 对sql语句进行参数化,并替换check_sql have_sql = self.do_re.recharge_parameterization(have_sql) # 去数据库查询充值之前的金额 recharge_before_amount = self.do_mysql.do_execute(have_sql) # 对获取到的数据进行转换,获取到的是decimal格式 recharge_before_amount = float( recharge_before_amount['LeaveAmount']) recharge_before_amount = round(recharge_before_amount, 2) # 对获取的数据进行参数化 new_data = self.do_re.recharge_parameterization(one_case['input_data']) # 向接口发送请求数据 result_data = self.do_request.send_request(url=new_url, data=eval(new_data), method=method).text try: self.assertIn(one_case['expected'], result_data, msg='充值接口请求成功') if have_sql: # 再次请求数据库,查询充值之后的金额 mysql_data = self.do_mysql.do_execute(have_sql) # 将金额转换为float类型的数 # 再将金额转换成float格式的数再次转换成带2位小数的数 recharge_after_amount = round(float(mysql_data['LeaveAmount']), 2) # 将表格中的数据转换成字典格式 # recharge_amount_dict = json.loads(new_data, encoding='utf-8') # 获取到所充值的金额 recharge_amount = float( json.loads(new_data, encoding='utf-8')['amount']) real_amount = round( float(recharge_before_amount + recharge_amount), 2) self.assertEqual(real_amount, recharge_after_amount, msg='数据库中充值的数据有误') self.one_file.write('{},执行的结果为:{}\n'.format( one_case['title'], self.pass_result)) self.do_excel.write_cell(row=one_case['case_id'] + 1, column=7, actual=result_data, result=self.pass_result) except AssertionError as err: self.one_file.write('{}执行的结果为:{},具体的异常为:{}\n'.format( one_case['title'], self.fail_result, err)) self.do_excel.write_cell(row=one_case['case_id'] + 1, column=7, actual=result_data, result=self.fail_result) raise err self.do_request.close_request()
class Handle_Re: # 注册接口:不存在手机号的参数化信息 register__unregistered_mobile = r"\${unregistered_mobile}" # 注册接口:存在手机号的参数化信息 register__investors_mobile = r"\${investors_login_mobile}" # 登录接口:已存在手机号的参数化信息 login__investors_login_mobile = r"\${investors_login_mobile}" # 登录接口:已存在手机对应的密码的参数化信息 login__investors_login_pwd = r"\${investors_login_pwd}" # 充值接口:已存在手机号码参数化信息 recharge__investors_login_mobile = r"\${investors_login_mobile}" # 充值接口:已存在手机对应的密码的参数化信息 recharge__investors_login_pwd = r"\${investors_login_pwd}" # 加标接口:管理员手机号码参数化信息 add__borrower_login_mobile = r"\${borrower_login_mobile}" # 加标接口:管理员密码参数化信息 add__borrower_login_pwd = r"\${borrower_login_pwd}" # 加标接口:借款人id参数化信息 add__borrower_member_id = r"\${borrower_member_id}" # 投资接口:管理员手机号参数化信息 invest__admin_login_mobile = r"\${admin_login_mobile}" # 投资接口:管理员密码参数化信息 invest__admin_login_pwd = r"\${admin_login_pwd}" # 投资接口:借款人ID invest__borrow_member_id = r"\${borrow_id}" # 投资接口:标ID参数化信息 invest__loan_id = r"\${loan_id}" # 投资接口:投资人id invest__investors_id = r"\${investors_login_id}" # 投资接口:投资人密码 invest__investors_pwd = r"\${investors_login_pwd}" do_config = HandleConfig(CONFIG_USER) @classmethod def register_not_existed_replace(cls, data): ''' 不存在手机号进行参数化 ''' if re.search(cls.register__unregistered_mobile, data): do_mysql = HandleMysql() data = re.sub(cls.register__unregistered_mobile, do_mysql.create_not_existed_mobile(), data) do_mysql.close() return data @classmethod def register_have_existed_replace(cls, data): ''' 存在手机号进行参数化 ''' if re.search(cls.register__investors_mobile, data): invest_user_mobile = cls.do_config.get_value( 'invest_user', 'mobile') data = re.sub(cls.register__investors_mobile, invest_user_mobile, data) return data @classmethod def register_parameterization(cls, data): # 注册参数化 data = cls.register_not_existed_replace(data) data = cls.register_have_existed_replace(data) return data @classmethod def login_have_existed_mobile_pwd_replace(cls, data): if re.search(cls.login__investors_login_mobile, data): invest_mobile = cls.do_config.get_value('invest_user', 'mobile') data = re.sub(cls.login__investors_login_mobile, invest_mobile, data) if re.search(cls.login__investors_login_pwd, data): invest_pwd = cls.do_config.get_value('invest_user', 'pwd') data = re.sub(cls.login__investors_login_pwd, invest_pwd, data) return data @classmethod def login_parameterization(cls, data): # 登录参数化 data = cls.login_have_existed_mobile_pwd_replace(data) return data @classmethod def recharge_have_existed_mobile_pwd_replace(cls, data): if re.search(cls.recharge__investors_login_mobile, data): invest_mobile = cls.do_config.get_value('invest_user', 'mobile') data = re.sub(cls.recharge__investors_login_mobile, invest_mobile, data) if re.search(cls.recharge__investors_login_pwd, data): invest_pwd = cls.do_config.get_value('invest_user', 'pwd') data = re.sub(cls.recharge__investors_login_pwd, invest_pwd, data) return data @classmethod def recharge_parameterization(cls, data): # 充值参数化 data = cls.recharge_have_existed_mobile_pwd_replace(data) return data @classmethod def add_admin_user_mobile_pwd_replace(cls, data): ''' 加标:对管理员手机号码和密码进行参数化 ''' # 在传入的data数据中查找是否存在 borrower_login_mobile = r"\${borrower_login_mobile}" 的内容 if re.search(cls.add__borrower_login_mobile, data): # 获取管理员的手机号码 borrow_admin_user_mobile = cls.do_config.get_value( 'admin_user', 'mobile') # 对传入的data数据进行参数化, 在 data 数据里把 cls.borrower_login_mobile 的内容修改为 borrow_admin_user_mobile data = re.sub(cls.add__borrower_login_mobile, borrow_admin_user_mobile, data) # 在传入的data数据中查找是否存在 borrower_login_pwd = r"\${borrower_login_pwd}" 的内容 if re.search(cls.add__borrower_login_pwd, data): # 获取管理员的密码 borrow_admin_user_pwd = cls.do_config.get_value( 'admin_user', 'pwd') # 对传入的data数据进行参数化, 在 data 数据里把 cls.borrower_login_pwd 的内容修改为 borrow_admin_user_pwd data = re.sub(cls.add__borrower_login_pwd, borrow_admin_user_pwd, data) # 把最后参数化的内容返回 return data @classmethod def add_borrow_id_replace(cls, data): ''' 加标:对借款人id进行参数化 ''' if re.search(cls.add__borrower_member_id, data): borrow_user_id = cls.do_config.get_value('borrow_user', 'user_id') data = re.sub(cls.add__borrower_member_id, borrow_user_id, data) return data @classmethod def add_parameterization(cls, data): # 管理员信息:手机号码和密码参数化 data = cls.add_admin_user_mobile_pwd_replace(data) # 借款人信息:id参数化 data = cls.add_borrow_id_replace(data) return data @classmethod def invest_admin_user_mobile_pwd_replace(cls, data): if re.search(cls.invest__admin_login_mobile, data): exists_admin_mobile = cls.do_config.get_value( 'admin_user', 'mobile') data = re.sub(cls.invest__admin_login_mobile, exists_admin_mobile, data) if re.search(cls.invest__admin_login_pwd, data): exists_admin_pwd = cls.do_config.get_value('admin_user', 'pwd') data = re.sub(cls.invest__admin_login_pwd, exists_admin_pwd, data) return data @classmethod def invest_borrow_id_replace(cls, data): if re.search(cls.invest__borrow_member_id, data): exists_borrow_id = cls.do_config.get_value('borrow_user', 'user_id') data = re.sub(cls.invest__borrow_member_id, exists_borrow_id, data) return data @classmethod def invest_investor_id_pwd_replace(cls, data): if re.search(cls.invest__investors_id, data): investor_id = cls.do_config.get_value('invest_user', 'user_id') data = re.sub(cls.invest__investors_id, investor_id, data) if re.search(cls.invest__investors_pwd, data): investor_pwd = cls.do_config.get_value('invest_user', 'pwd') data = re.sub(cls.invest__investors_pwd, investor_pwd, data) return data @classmethod def invest_loan_id_replace(cls, data): if re.search(cls.invest__loan_id, data): loan_id = str(getattr(Handle_Re, "loan_id")) data = re.sub(cls.invest__loan_id, loan_id, data) return data @classmethod def invest_parameterization(cls, data): data = cls.invest_admin_user_mobile_pwd_replace(data) data = cls.invest_borrow_id_replace(data) data = cls.invest_investor_id_pwd_replace(data) data = cls.invest_loan_id_replace(data) return data
class Id_Account: ''' MIUI sug接口ID统计类 ''' # 创建封装requests请求类实例对象 do_requests = DoRequests() # 创建封装pymysql类实例对象 do_mysql = HandleMySQL() # 创建DoParameterize参数化类实例对象 do_parameterize = DoParameterize() # 配置文件config.ini的路径 config_path = os.path.join(CONFIGS_DIR, 'config.ini') # 创建DoParameterize参数化类实例对象 do_config = HandleConfig(config_path) # 创建DoParameterize参数化类实例对象 do_log = HandleLog(config_path).get_logger() # 创建ExtractKeywords类实例对象 extract_keywords = ExtractKeywords() # 请求参数data data_request = """{"q": "${query}", "f": 0, "sd": "xhdpi", "hl": "zh_CN", "p": 0, "nt": "wifi", "lo": 21.8, "la": 51.8, "se": None,"sp": "china mobile", "imei": None, "dm": "MIX 2S", "di": None, "sv": "MIUI 10.3.5", "vr": "4.4.4","vs": "19","sid": 5, "s": 1, "n": 50, "_sl": True, "addr": "北京市海淀区清河朱房路", "cv": 0, "cc": None, "ti": None,"from": None, "h_t": None, "cd": True}""" # data_request = """{"q": "${query}", "_sl": True}""" # data = """{"q": "${query}", "f": 0, "d": True, "sd": "xhdpi", "hl": "zh_CN", "p": 0, "nt": "wifi", "lo": 21.8, "la": 51.8, "se": None,"sp": "china mobile", "imei": None, "dm": "MIX 2S", "di": None, "sv": "MIUI 10.3.5", "vr": "4.4.4","vs": "19", "sid": 5, "s": 1, "n": 50, "_sl": True, "addr": "北京市海淀区清河朱房路", "cv": 0, "cc": None, "ti": None,"from": None, "h_t": None, "cd": True}""" # data = {"q": "中秋节", "f": 0, "sd": "xhdpi", "hl": "zh_CN", "p": 0, "nt": "wifi", "lo": 21.8, "la": 51.8, "se": None, # "sp": "china mobile", "imei": None, "dm": "MIX 2S", "di": None, "sv": "MIUI 10.3.5", "vr": "4.4.4", # "vs": "19", "sid": 5, "s": 1, "n": 50, "_sl": True, "addr": "北京市海淀区清河朱房路", "cv": 0, "cc": None, "ti": None, # "from": None, "h_t": None, "cd": True} # 请求url url = do_config.get_value('handle_interface', 'base_url') + '/sug' # 请求方式 method = 'POST' def __init__(self): ''' 初始化函数 ''' # 创建requests的session会话管理器 self.do_requests.__init__() # 创建数据库连接 self.do_mysql.__init__() def generate_timestamp_long(self): ''' 获取当前时间戳long类型 :return:当前时间戳long类型 ''' current_time = "{:%Y%m%d%H%M%S}".format(datetime.datetime.now()) return current_time def generate_timestamp(self): ''' 获取当前时间戳 :return:当前时间戳 ''' current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") return current_time def execute_requests(self): ''' 请求sug接口方法 :return: ''' # 替换请求数据data中的查询关键字query data_new = self.do_parameterize.query_parametric(data=self.data_request) # print(data_new) data_dict = eval(data_new) # 将请求字段中的sid重新赋值为当前时间戳long类型 data_dict['sid'] = self.generate_timestamp_long() # print(type(data_dict), data_dict) try: # 接口请求 response = self.do_requests.handle_requests(url=self.url, method=self.method, data=data_dict) # 获取响应体dict类型 response_dict = response.json() # 打印响应体数据 print(response_dict) if response_dict['message'] == 'success' and response_dict['status'] == 0: if response_dict['result']: global id_list id_list = [] # 循环追加到id_list列表中 # print('不为空') for result in response_dict['result']: # 如果只传query的话,先key:data判断是否在result内才不会报错 # if 'data' in result: for data in result['data']: # 先判断key 'type'在data中是否存在 if 'type' in data: # 先判断key 'id'在data中是否存在,因为type=images是没有id的 if 'id' in data: id_list.append(data['type']) id_list.append(data['id']) # print(id_list) # 获取相同type类型的数据的数量,data_type_dict示例:{'news': 3, 'video': 8, 'book': 1, 'weibo': 3, 'web': 3} data_type_dict = {} for i in range(len(id_list) - 1): if i % 2 == 0: data_type_dict[id_list[i]] = id_list.count(id_list[i]) # print('data_type_dict', data_type_dict) # 插入单条数据sql语句 # sql = "insert into dpqadb.metrics(app,metric,`value`,`time`) values ('integrity','idcount',{}, '{}');".format(len(id_list_new),self.generate_timestamp()) # data_sql_list1示例:[('news', 3), ('video', 8), ('book', 1), ('weibo', 3), ('web', 3)] data_sql_list1 = [] data_sql_list2 = [] for item in data_type_dict.items(): data_sql_list1.append(item) # print(data_sql_list1) # data_sql_list2示例(动态创建需要插入的多条sql数据): # [('idcount_news', 3, '2019-10-08 15:54:41'), ('idcount_video', 8, '2019-10-08 15:54:41'), # ('idcount_book', 1, '2019-10-08 15:54:41'), ('idcount_weibo', 3, '2019-10-08 15:54:41'), # ('idcount_web', 3, '2019-10-08 15:54:41')] for i in data_sql_list1: sql = ('idcount_' + i[0], i[-1], self.generate_timestamp()) data_sql_list2.append(sql) # 插入的多条数据,var为一个嵌套tuple的list var = data_sql_list2 # print(data_sql_list2) # 插入多条数据sql语句 sql = "insert into dpqadb.metrics(app,metric,`value`,`time`) values ('integrity', %s, %s, %s);" # print(sql) # print(response_dict) # 执行一次性插入多条数据的sql语句 # self.do_mysql.sql_insert_more_execute(sql=sql, args=var) # 打印出本次请求的日志保存到sug_requests.log日志文件中 self.do_log.info( '本次请求Query:{},Search_Result:{},Response_ID_Details(TYPE-ID):{}'.format( response.json()['query'], response.json()['count'], id_list)) else: # 如果获取的响应结果的result列表值为空的话,就重新更换query搜索关键词,然后调用execute_requests()方法重发一次请求 self.do_log.info(msg='本次请求搜索关键字为:{},搜索结果result为空,将更换query搜索关键词重发一次请求!'.format(response_dict['query'])) # print('为空,更换query搜索关键字!') # 重新更换query搜索关键词 self.extract_keywords.write_query_single() # 调用execute_requests()方法重发一次请求 self.execute_requests() except Exception as err: self.do_log.error('程序执行时报错了,具体异常为:{}'.format(err)) print(err) # 关闭session self.do_requests.session_close() # 关闭mysql连接 self.do_mysql.close_mysql()
# -*- coding: utf-8 -*- from scripts.handle_log import HandleLogging from scripts.handle_config import HandleConfig from scripts.handle_excel import HandleExcel from scripts.handle_request import do_http_requests from scripts.contants import TEST_DATA_FILES_PATH_CASES from scripts.contants import CONFIGS_FILE_TESTCASE1 from scripts.handle_context import HandleContext import unittest from libs.ddt import ddt,data handexcel = HandleExcel(TEST_DATA_FILES_PATH_CASES,'login') cases =handexcel.get_case() do_logger = HandleLogging().get_logging() do_config = HandleConfig(CONFIGS_FILE_TESTCASE1) @ddt class TestLogin(unittest.TestCase): @classmethod def setUpClass(cls): do_logger.debug('{}'.format('开始执行登录接口用例。。。。')) @classmethod def tearDownClass(cls): do_logger.debug('{}'.format('测试用例执行完毕,登录接口用例停止执行。。。。')) @data(*cases) def test_login(self,one_case):
# @Author : lyx # @File : handle_context.py # @Project : QianChengDai_API_Project """ 该模块用来处理测试数据的参数化 """ import re import os from scripts.handle_sql import HandleSql from scripts.handle_config import HandleConfig from scripts.contants import CONFIG_PATH # config_file = config_dir + "\\" + "mobile.ini" # 这种拼接路径方法容易忘掉中间加上\ mobile_config_file = os.path.join(CONFIG_PATH, "account.ini") # 要保存管理人、投资人、借款人三个账号的配置文件 do_conf = HandleConfig(mobile_config_file) class HandleContext: """ 处理测试数据参数化 """ # 将excel中data(参数)中的要匹配的模式都定义为类属性 not_register_mobile_patten = r"\${not_register_mobile}" # 未注册的号码 模式字符串 investor_mobile_patten = r"\${investor_mobile}" # 投资人号码 模式字符串 investor_pwd_patten = r"\${investor_pwd}" # 投资人账号密码 模式字符串 investor_id_patten = r"\${investor_ID}" # 投资人id 模式字符串 ing_loanid_patten = r"\${ing_loan_ID}" # 竞标中状态的标id 模式字符串 not_ready_loanid_patten = r"\${not_ready_loan_ID}" # 不在竞标中状态的标id 模式字符串 already_loanid_patten = r"\${already_loan_ID}" # 已满标状态的标id 模式字符串 manager_mobile_pattern = r"\${manager_mobile}" # 管理人号码 模式字符串
class HandleMySQL: ''' mysql封装类 ''' # 配置文件config.ini的路径 config_path = os.path.join(CONFIGS_DIR, 'config.ini') do_config = HandleConfig(config_path) def __init__(self): ''' host:服务器IP地址 user:数据库用户名 password:数据库密码 database:需要连接的数据库名 port:端口号 cursorclass:游标类 ''' # 创建连接对象 self.conn = pymysql.connect( host=self.do_config.get_value('handle_mysql', 'host'), user=self.do_config.get_value('handle_mysql', 'user'), password=self.do_config.get_value('handle_mysql', 'password'), database=self.do_config.get_value('handle_mysql', 'database'), port=self.do_config.get_int('handle_mysql', 'port'), cursorclass=pymysql.cursors.DictCursor) # 指定游标类为字典游标类 # 创建游标对象 self.cursor = self.conn.cursor() def sql_select_execute(self, sql, args=None, is_more=False): ''' 执行查询SQL语句的方法 :param sql: SQL语句 :param args: SQL语句中传的元组 :return:is_more=True->返回多条查询结果, is_more=False->返回单条查询结果 ''' self.cursor.execute(sql, args=args) self.conn.commit() if is_more: # 获取多条数据 return self.cursor.fetchall() else: # 获取单条数据 return self.cursor.fetchone() def sql_insert_execute(self, sql): ''' 插入单条数据的方法 :param sql: SQL语句 :return: ''' self.cursor.execute(sql) self.conn.commit() def sql_insert_more_execute(self, sql, args): ''' 批量插入多条数据的方法 :param sql: SQL语句 :param args: 嵌套tuple的list :return: ''' self.cursor.executemany(sql, args=args) self.conn.commit() def close_mysql(self): ''' 关闭游标和数据库连接 :return: ''' # 关闭游标对象 self.cursor.close() # 关闭数据库连接对象 self.conn.close()
return self.session.post(url, json=data) else: # is_json 为False ,代表传入的参数为json格式,返回 session 的post方法 return self.session.post(url, data=data) else: # 返回空内容 return None print('暂不支持其他格式') # close_request 方法,用来关闭 Session 会话 def close_request(self): self.session.close() if __name__ == '__main__': do_config = HandleConfig(scripts.path_constants.CONFIG_REQUEST) mobile = do_config.get_value('user', 'mobile', type='int') pwd = do_config.get_value('user', 'password', type='int') login_url = do_config.get_value('url', 'login_url') login_data = {'mobilephone': mobile, 'pwd': pwd} recharge_url = do_config.get_value('url', 'recharge_url') recharge_data = {'mobilephone': mobile, 'amount': 100} do_handle_request = HandleRequest() login_req = do_handle_request.send_request(login_url, data=login_data, method='post') recharge_req = do_handle_request.send_request(recharge_url, data=recharge_data, method='post')
class HandleMysql: ''' PyMysql 的封装类 ''' def __init__(self): # 创建配置文件对象 self.config = HandleConfig(CONFIG_MYSQL) # 读取配置文件的内容 # self.config.read(CONFIG_MYSQL, encoding='utf-8') # 获取配置文件的内容 section = 'mysql' # 创建数据库连接 self.connect = pymysql.connect( host=self.config.get_value(section, 'mysql_host'), user=self.config.get_value(section, 'mysql_user'), password=self.config.get_value(section, 'mysql_password'), db=self.config.get_value(section, 'mysql_db'), port=self.config.get_int(section, 'mysql_port'), charset='utf8', cursorclass=pymysql.cursors.DictCursor) # 创建游标对象 self.cursor = self.connect.cursor() # sql语句执行方法 def do_execute(self, sql, args=None, is_one_data=True): ''' @sql : 传入要执行的sql语句 @args: sql语句有占位符需传入其他参数 @is_one_data: sql语句查询的是否是单条数据,默认为True ''' # 执行传入的sql语句,和可变参数 self.cursor.execute(sql, args=args) # 提交要执行的sql语句对数据库进行操作 self.connect.commit() # 如果is_one_data为True,则代表该sql语句会返回一条数据 if is_one_data: # 则 fetchone 返回执行sql语句后的数据 return self.cursor.fetchone() # 如果is_one_data为True,则代表该sql语句返回的数据不止为一条 else: # 则 fetchall 返回执行sql语句后的所有数据 return self.cursor.fetchall() @staticmethod def create_mobile(): ''' 创建手机号码的静态类 ''' # 定义一些3位数开头的手机号码 head_number = [ '130', '131', '132', '138', '139', '150', '159', '176', '185' ] # 调用 random.choice() 方法在 head_number 列表中随机选择一个 head_mobile_number = random.choice(head_number) # 调用 random.sample() 方法在0-9中随机出8个数字 other_mobile_number = random.sample('0123456789', 8) # 将选出的号码开头和随机出的8个数字进行组合,生成一个手机号码 mobile_number = head_mobile_number + ''.join(other_mobile_number) # 并将该手机号码返回 return mobile_number def is_existed_mobile(self, mobile): ''' 判断手机号码是否存在的方法 ''' # 定义一个查询号码的sql语句 sql = "SELECT * FROM member WHERE MobilePhone = %s;" # 调用 do_execute() 方法来执行该sql语句,获取查询的结果 # 如果返回的是个字典,就代表已经注册,返回True if self.do_execute(sql, args=(mobile, )): return True # 返回None就代表还没有注册,返回False else: return False def create_not_existed_mobile(self): ''' 创建一个不存在的手机号码 ''' # 进行一个 while 循环,来生成手机号 while True: # mobile 接收调用 create_mobile() 方法返回的手机号码 mobile = self.create_mobile() # 调用 is_existed_mobile(mobile) 来判断创建的手机号是否存在 if not self.is_existed_mobile(mobile): # 如果不存在,将 break 跳出循环 break # 并将该手机号码插入到数据库中 # 准备好插入的sql语句 ''' sql = "INSERT INTO `future`.`member`(`Id`," \ " `RegName`," \ " `Pwd`," \ " `MobilePhone`," \ " `Type`," \ " `LeaveAmount`) VALUES (1," \ " 'want'," \ " 'want'," \ " %s," \ " 1," \ " 0)" ''' return mobile # 关闭方法 def close(self): # 先关闭游标对象 self.cursor.close() # 接着关闭与数据库的连接 self.connect.close()
# @Time : 2019/8/8 10:30 # @Author : lyx # @File : handle_account.py # @Project : QianChengDai_API_Project """ 此模块用来初始时注册管理人、投资人、借款人三个账号,并保存至配置文件中 """ import json import os from scripts.handle_sql import HandleSql from scripts.handle_request import HandleRequest from scripts.contants import CONFIG_PATH from scripts.handle_config import HandleConfig from scripts.handle_logging import log_operate conf_operate = HandleConfig(os.path.join(CONFIG_PATH, "account.ini")) account_file_name = os.path.join(CONFIG_PATH, "account.ini") # 保存三个账号信息的配置文件名 class HandleAccount: """ 该封装类是用来注册管理人、投资人、借款人三个账号,并将其保存至配置文件中的 """ def __init__(self): self.do_sql = HandleSql() self.do_request = HandleRequest() def register_member_mobile(self, regname=None): """ 注册号码 :param regname: 昵称 可为空
def admin_user_pwd_replace(cls, data): admin_pwd_config = HandleConfig(CONFIGS_USER_ACCOUNTS) if re.search(cls.admin_use_pwd_pattern, data): admin_user_pwd = admin_pwd_config.get_value('admin_user', 'pwd') data = re.sub(cls.admin_use_pwd_pattern, admin_user_pwd, data) return data
data=data, **kwargs) else: do_log.error("不支持的请求方法") return None return res def close(self): self.one_session.close() # 只是做了资源回收,并没有中断回话 send_request = HandleRequest() if __name__ == '__main__': # 1.构造url do_config = HandleConfig(CONFIGS_FILE_PATH) # register_url = "http://192.168.65.128:8080/futureloan/mvc/api/member/register" register_url = do_config("api", "url") + "/member/register" login_url = "http://test.lemonban.com:8080/futureloan/mvc/api/member/login" recharge_url = "http://test.lemonban.com:8080/futureloan/mvc/api/member/recharge" # 2.创建请求参数 register_params = {"mobilephone": "13652168740", "pwd": "123456"} login_params = {"mobilephone": "13652168740", "pwd": "123456"} recharge_params = {"mobilephone": "13652168740", "amount": 1000} do_request = HandleRequest() response = do_request(method="post", url=register_url, data=register_params)
def borrow_user_id_replace(cls, data): borrow_user_config = HandleConfig(CONFIGS_USER_ACCOUNTS) if re.search(cls.borrow_user_id_pattern, data): borrow_user_id = borrow_user_config.get_value('borrow_user', 'id') data = re.sub(cls.borrow_user_id_pattern, borrow_user_id, data) return data
import json import os from libs.ddt import ddt, data from scripts.handle_excel import HandleExcel from scripts.handle_config import HandleConfig from scripts.handle_logging import HandleLog from scripts.handle_context import HandleContext from scripts.content_os import EXCEL_FILE_PATH, CONFIG_FILE_PATH, LOG_FILE_PATH from scripts.handle_webservice_request import HandleWebserviceRequest excel_dir = os.path.join(EXCEL_FILE_PATH, "webservice_api_test_cases.xlsx") do_excel = HandleExcel(excel_dir, "sendmcode") cases = do_excel.get_all_case() conf_dir = os.path.join(CONFIG_FILE_PATH, "api_config.ini") do_conf = HandleConfig(conf_dir) do_log = HandleLog().get_logger() do_context = HandleContext() @ddt class TestSendMCode(unittest.TestCase): """ 测试发送短信验证码接口 """ @classmethod def setUpClass(cls): url = do_conf.get_data("interface url", "sendmcode_api_url") # cls.client = Client(url) # 创建Client对象 cls.do_request = HandleWebserviceRequest(url)
class TestAdd(unittest.TestCase): do_re = Handle_Re() do_request = HandleRequest() do_config = HandleConfig(CONFIG_REQUEST) # 初始化HandleExcel对象 do_excel = HandleExcel(sheetname='add') # 获取所有的用例 cases = do_excel.get_cases() pass_result = do_config.get_value('result', 'pass_result') fail_result = do_config.get_value('result', 'fail_result') @classmethod def setUpClass(cls): cls.do_mysql = HandleMysql() cls.one_file = open(REPORTS_ALL_PATH, mode='a+', encoding='utf-8') cls.one_file.write('{:=^40s}\n'.format('开始执行加标接口用例')) @classmethod def tearDownClass(cls): cls.do_mysql.close() cls.one_file.write('{:=^40s}\n\n'.format('加标接口用例执行结束')) cls.one_file.close() @data(*cases) # 对所有用例进行拆包 def test_add(self, one_case): # 获得单个的用例,获取单个用例的请求数据 # data = one_case['input_data'] # 对请求数据进行参数化,获取到参数化后的数据 new_data = self.do_re.add_parameterization(one_case['input_data']) # 获取请求的url地址 url = self.do_config.get_value('url', 'head_url') + one_case['url'] # 获取接口请求方式 method = one_case['method'] # 对接口发送请求,获取请求后的返回数据 result_data = self.do_request.send_request(url=url, data=eval(new_data), method=method).text # 获取接口请求成功的标识 # expected = one_case['expected'] try: self.assertIn(one_case['expected'], result_data, msg='加标接口请求成功') self.one_file.write('{}执行的结果为:{}\n'.format(one_case['title'], self.pass_result)) self.do_excel.write_cell(row=one_case['case_id'] + 1, column=7, actual=result_data, result=self.pass_result) except AssertionError as err: self.one_file.write('{}执行的结果为:{},具体的异常为:{}\n'.format( one_case['title'], self.fail_result, err)) self.do_excel.write_cell(row=one_case['case_id'] + 1, column=7, actual=result_data, result=self.fail_result) raise err self.do_request.close_request()
class Context: ''' ''' not_existed_tel_parttern = r'\$\{not_exited_tel\}' existed_tel_parttern = r'\$\{invest_user_tel\}' existed_pwd_pattern = r'\$\{invest_user_pwd\}' borrow_user_pattern = r'\$\{borrow_user_id\}' admin_user_pattern = r'\$\{admin_user_tel\}' admin_pwd_pattern = r'\$\{admin_user_pwd\}' load_id_parttern = r'\$\{loan_id\}' invest_user_id = r'\$\{invest_user_id\}' do_config = HandleConfig(USER_ACCOUNTS_FILE_PATH) @classmethod def not_existed_tel_replace(cls, data): ''' :param data:待替换的原始字符串 :return: ''' handle_mysql = HandleMysql() if re.search(cls.not_existed_tel_parttern, data): not_exist_tel = handle_mysql.create_not_existed_mobile() data = re.sub(cls.not_existed_tel_parttern, not_exist_tel, data) handle_mysql.close() return data @classmethod def existed_tel_replace(cls, data): handle_mysql = HandleMysql() if re.search(cls.existed_tel_parttern, data): exist_tel = handle_mysql.get_existed_mobile() data = re.sub(cls.existed_tel_parttern, exist_tel, data) handle_mysql.close() return data ''' =左边的data是已经替换后的字符串, 在第二次和exist模式匹配的时候不会匹配上,所以返回第一次已替换的字符串 ''' @classmethod def invest_mobile_replace(cls, data): if re.search(cls.existed_tel_parttern, data): invest_tel = cls.do_config.get_value('invest_user', 'mobilephone') data = re.sub(cls.existed_tel_parttern, invest_tel, data) return data @classmethod def invest_pwd_replace(cls, data): if re.search(cls.existed_pwd_pattern, data): invest_pwd = cls.do_config.get_value('invest_user', 'pwd') data = re.sub(cls.existed_pwd_pattern, invest_pwd, data) return data @classmethod def invest_id_replace(cls, data): if re.search(cls.invest_user_id, data): invest_id = cls.do_config.get_value('invest_user', 'id') data = re.sub(cls.invest_user_id, invest_id, data) return data @classmethod def borrow_user_replace(cls, data): if re.search(cls.borrow_user_pattern, data): borrow_user_id = cls.do_config.get_value('browser_user', 'id') data = re.sub(cls.borrow_user_pattern, borrow_user_id, data) return data @classmethod def admin_user_tel_pwd_replace(cls, data): if re.search(cls.admin_user_pattern, data): admin_user_mobile = cls.do_config.get_value( 'admin_user', 'mobilephone') data = re.sub(cls.admin_user_pattern, admin_user_mobile, data) if re.search(cls.admin_pwd_pattern, data): admin_user_pwd = cls.do_config.get_value('admin_user', 'pwd') data = re.sub(cls.admin_pwd_pattern, admin_user_pwd, data) if re.search(cls.borrow_user_pattern, data): borrow_user_id = cls.do_config.get_value('browser_user', 'id') data = re.sub(cls.borrow_user_pattern, borrow_user_id, data) return data @classmethod def register_parameterization(cls, data): data = cls.not_existed_tel_replace(data) #第二个,再来替换已注册的手机号码 data = cls.existed_tel_replace(data) #需要实现 return data @classmethod def recharge_parameterization(cls, data): data = cls.invest_mobile_replace(data) data = cls.invest_pwd_replace(data) data = cls.invest_id_replace(data) return data @classmethod def add_parameterization(cls, data): data = cls.borrow_user_replace(data) return data @classmethod def loan_id_replace(cls, data): print(data, type(data)) loan_id = getattr(cls, 'loan_id') print('handle里面动态获取loan_id', loan_id, type(loan_id)) # loan_id = cls.loan_id if re.search(cls.load_id_parttern, data): print('if找到了') data = re.sub(cls.load_id_parttern, str(loan_id), data) print('handle处理后的data值', data) return data @classmethod def invest_parameterization(cls, data): # loan_id = getattr(cls, 'loan_id') print('-----------------') print(data) if 'loan_id' in data: data = cls.loan_id_replace(data) print('handle处理后的data值2222222', data) data = cls.admin_user_tel_pwd_replace(data) data = cls.borrow_user_replace(data) data = cls.recharge_parameterization(data) data = cls.existed_tel_replace(data) return data
class TestInvest(unittest.TestCase): do_re = Handle_Re() do_request = HandleRequest() do_config = HandleConfig(CONFIG_REQUEST) # 初始化HandleExcel对象 do_excel = HandleExcel(sheetname='invest') # 获取所有的用例 cases = do_excel.get_cases() pass_result = do_config.get_value('result', 'pass_result') fail_result = do_config.get_value('result', 'fail_result') @classmethod def setUpClass(cls): cls.do_mysql = HandleMysql() cls.one_file = open(REPORTS_ALL_PATH, mode='a+', encoding='utf-8') cls.one_file.write('{:=^40s}\n'.format('开始执行投资接口用例')) @classmethod def tearDownClass(cls): cls.do_mysql.close() cls.one_file.write('{:=^40s}\n\n'.format('投资接口用例执行结束')) cls.one_file.close() @data(*cases) # 对所有用例进行拆包 def test_invest(self, one_case): # 获得单个的用例,获取单个用例的请求数据 # data = one_case['input_data'] # 对请求数据进行参数化,获取到参数化后的数据 new_data = self.do_re.invest_parameterization(one_case['input_data']) # 获取请求的url地址 new_url = self.do_config.get_value('url', 'head_url') + one_case['url'] # 获取接口请求方式 method = one_case['method'] # 对接口发送请求,获取请求后的返回数据 result_data = self.do_request.send_request(url=new_url, data=eval(new_data), method=method).text if "加标成功" in result_data: check_sql = one_case['check_sql'] if check_sql: # 对sql语句进行参数化 check_sql = self.do_re.invest_parameterization(check_sql) # 获取到执行后的sql语句后的内容 result_sql = self.do_mysql.do_execute(check_sql) # loan_id = result_sql['Id'] # loan_id = result_data.get('Id') # Handle_Re.loan_id = result_data['Id'] # 第一个参数:实例对象,则会为该实例对象创建实例属性 # 第一个参数为类,则会创建类属性 # 第二个参数为属性名 # 第三个参数为具体的值 setattr(Handle_Re, "loan_id", result_sql.get('Id')) # 获取接口请求成功的标识 expected = one_case['expected'] try: self.assertIn(expected, result_data, msg='投资接口请求成功') self.one_file.write('{}执行的结果为:{}\n'.format(one_case['title'], self.pass_result)) self.do_excel.write_cell(row=one_case['case_id'] + 1, column=7, actual=result_data, result=self.pass_result) except AssertionError as err: self.one_file.write('{}执行的结果为:{},具体的异常为:{}\n'.format( one_case['title'], self.fail_result, err)) self.do_excel.write_cell(row=one_case['case_id'] + 1, column=7, actual=result_data, result=self.fail_result) raise err self.do_request.close_request()
data = cls.not_existed_tel_repalce(data) return data @classmethod def add_paramaterization(cls, data): data = cls.admin_user_tel_replace(data) data = cls.admin_user_pwd_replace(data) data = cls.borrow_user_id_replace(data) return data @classmethod def invest_paramaterization(cls, data): data = cls.admin_user_tel_replace(data) data = cls.admin_user_pwd_replace(data) data = cls.borrow_user_id_replace(data) data = cls.invest_loan_id_replace(data) data = cls.invest_user_tel_replace(data) data = cls.invest_user_pwd_replace(data) data = cls.invest_user_id_repalce(data) return data if __name__ == '__main__': context = HandleContext() data1 = '{"mobilephone":"${not_existed_tel}","pwd":"123456","regname":"jason"}' data2 = '{"mobilephone":"18934567","pwd":"123456","regname":"jason"}' print(context.not_existed_tel_repalce(data1)) print(context.not_existed_tel_repalce(data2)) o_conig = HandleConfig(CONFIGS_USER_ACCOUNTS) invest_tel = o_conig.get_value('invest_user', 'mobilephone') print(invest_tel)
import json from libs.ddt import ddt, data from scripts.handle_excel import HandleExcel from scripts.content_os import EXCEL_FILE_PATH, CONFIG_FILE_PATH from scripts.handle_config import HandleConfig from scripts.handle_context import HandleContext from scripts.handle_mysql import HandleMySql from scripts.handle_logging import HandleLog from scripts.handle_webservice_request import HandleWebserviceRequest do_log = HandleLog().get_logger() do_context = HandleContext() do_conf = HandleConfig(os.path.join(CONFIG_FILE_PATH, "api_config.ini")) excel_dir = os.path.join(EXCEL_FILE_PATH, "webservice_api_test_cases.xlsx") do_excel = HandleExcel(excel_dir, "register") cases = do_excel.get_all_case() @ddt class TestRegister(unittest.TestCase): """ 测试注册接口封装类 """ @classmethod def setUpClass(cls): do_log.debug("{:=^50s}".format("注册接口测试用例开始执行")) sendcode_url = do_conf.get_data("interface url", "sendmcode_api_url") regist_url = do_conf.get_data("interface url", "register_api_url")
def __init__(self): self.handle_mysql = HandleMysql() self.do_config = HandleConfig(CONFIGS_FILE_TESTCASE2)