def test_recharge(self, data): url = do_conifg.get_value(section="API", option="url")+data["url"] expect = data["expected"] check_sql = data["check_sql"] form_data = self.do_context.invest_parameterization(data["data"]) res = do_request.send_request(method=data["method"], url=url, data=form_data) if check_sql: if "加标成功" in res.text: check_sql = self.do_context.invest_parameterization(check_sql) mysql_data = self.do_sql.get_value(sql=check_sql) OperationContext.loan_id = str(mysql_data["Id"]) else: pass log.info(res.text) if res.status_code == 200: actual = int(res.json()["code"]) log.info(f"请求地址:{url}\n请求参数:{form_data}\n预期结果:{expect}\n实际结果:{actual}") try: self.assertEqual(expect, actual) log.info("用例执行通过\n") self.oe.write_data(row=data["case_id"]+1, actual=actual, result="PASS") except Exception as e: log.error(f"用例执行失败{e}\n") self.oe.write_data(row=data["case_id"]+1, actual=actual, result="FAIL") raise e
def select_registered_phone(self): """ 数据库查找已注册的手机号 :return:未注册的手机号(数据库中查不到的手机号) """ sql = do_conifg.get_value(section="SQL", option="select_registered_phone") phone = self.get_value(sql=sql)["MobilePhone"] return phone
class InitData: sql = do_conifg.get_value(section="SQL", option="select_user_info") url = do_conifg.get_value(section="API", option="url") + "/member/register" user_list = eval(do_conifg.get_value(section="INITDATA", option="users")) user_info = eval( do_conifg.get_value(section="INITDATA", option="user_info")) def create_user(self, regname, pwd="test1234"): """ 创建新用户,从配置文件中获取需要获得的用户信息,然后从接口中 获得这些信息组合成字典 :param regname: 用户名 :param pwd: 密码 默认test1234 :return: 区域名、选项名、选项值组成的嵌套字典的字典 """ do_sql = OperationMysql() while True: mobile = do_sql.create_unregistered_phone() data = {"mobilephone": mobile, "pwd": pwd, "regname": regname} do_request.send_request(method="post", url=self.url, data=data) result = do_sql.get_value(sql=self.sql, args=mobile) if result: break user_info_dict = dict.fromkeys(self.user_info) for i in self.user_info: value = result[i] user_info_dict[i] = value user_info_dict["Pwd"] = pwd user_dict = {regname: user_info_dict} return user_dict do_sql.close_db() do_request.close() def generate_user_info(self): """ 生成用户信息,从配置文件中获取要生成的用户名,并将用户信息写入 初始化数据的配置文件中 :return: """ for user in self.user_list: data = self.create_user(regname=user) do_conifg.write_config(filename=INIT_DATA_DIR, datas=data)
def test_login(self, data): url = do_conifg.get_value(section="API", option="url")+data["url"] expect = data["expected"] form_data = self.do_context.login_parameterization(data["data"]) log.info(form_data) actual = do_request.send_request(method=data["method"], url=url, data=form_data).text log.info(f"请求地址:{url}\n请求参数:{form_data}\n逾期结果:{expect}\n实际结果:{actual}") try: self.assertEqual(expect, actual) log.info("用例执行通过\n") self.oe.write_data(row=data["case_id"]+1, actual=actual, result="PASS") except Exception as e: log.error(f"用例执行失败{e}\n") self.oe.write_data(row=data["case_id"]+1, actual=actual, result="FAIL") raise e
def test_recharge(self, data): url = do_conifg.get_value(section="API", option="url") + data["url"] expect = data["expected"] check_sql = data["check_sql"] if check_sql: check_sql = self.do_context.recharge_parameterization(check_sql) mysql_data = self.do_sql.get_value(sql=check_sql) amount_before = round(float(mysql_data["LeaveAmount"]), 2) form_data = self.do_context.recharge_parameterization(data["data"]) res = do_request.send_request(method=data["method"], url=url, data=form_data) if res.status_code == 200: actual = int(res.json()["code"]) log.info( f"请求地址:{url}\n请求参数:{form_data}\n预期结果:{expect}\n实际结果:{actual}") try: self.assertEqual(expect, actual) if check_sql: mysql_data = self.do_sql.get_value(sql=check_sql) amount_after = round(float(mysql_data["LeaveAmount"]), 2) recharge_amount = json.loads(data["data"])["amount"] expect_amount = amount_before + recharge_amount self.assertEqual(expect_amount, amount_after, msg="充值金额不一致") log.info(f"预期金额:{expect_amount}实际金额:{amount_after}") log.info("用例执行通过\n") self.oe.write_data(row=data["case_id"] + 1, actual=actual, result="PASS") except Exception as e: log.error(f"用例执行失败{e}\n") self.oe.write_data(row=data["case_id"] + 1, actual=actual, result="FAIL") raise e
def test_register(self, data): url = do_conifg.get_value(section="API", option="url1") + data["url"] expect = data["expected"] data = json.dumps(data) form_data = self.do_context.register_parameterization(data) data = json.loads(form_data) check_sql = data["check_sql"] form_data = json.loads(form_data) actual = do_request.send_request(url=url, method=data["method"], data=json.loads(form_data["data"])) actual = dict(actual) actual = str(actual["retInfo"]) if check_sql: # OperationContext.mobile = str(form_data["mobile"]) # check_sql = self.do_context.register_parameterization(check_sql) mysql_data = self.do_sql.get_value(sql=check_sql) OperationContext.verify_code = str(mysql_data["fverify_code"]) OperationContext.send_code_phone = json.loads( form_data["data"])["mobile"] print(json.loads(form_data["data"])["mobile"]) log.info(f"请求地址:{url}\n请求参数:{data}\n逾期结果:{expect}\n实际结果:{actual}") try: self.assertEqual(expect, actual) log.info("用例执行通过\n") self.oe.write_data(row=data["case_id"] + 1, actual=actual, result="PASS") except Exception as e: log.error(f"用例执行失败{e}\n") self.oe.write_data(row=data["case_id"] + 1, actual=actual, result="FAIL") raise e
class OperationMysql: """ 操作mysql数据库 """ host = do_conifg.get_value(section="MYSQL", option="host") user = do_conifg.get_value(section="MYSQL", option="username") pwd = do_conifg.get_value(section="MYSQL", option="password") port = do_conifg.get_int_value(section="MYSQL", option="port") db = do_conifg.get_value(section="MYSQL", option="database") sql = do_conifg.get_value(section="SQL", option="select_user_info") def __init__(self): """ 初始化实例中的数据库连接和游标对象 """ self.db_content = pymysql.connect( host=self.host, user=self.user, password=self.pwd, database=self.db, port=self.port, charset="utf8", cursorclass=pymysql.cursors.DictCursor) # 定义游标类输出结果为字典 self.cursor = self.db_content.cursor() def get_value(self, sql, args=None, is_all=False): """ 获取SQL执行结果 :param sql: sql语句 :param args: sql中的参数 :param is_all:是否返回全部数据 :return:查询结果 """ self.cursor.execute(sql, args=args) self.db_content.commit() if is_all: result = self.cursor.fetchall() else: result = self.cursor.fetchone() return result def close_db(self): """ 关闭游标和数据库连接 :return: None """ self.cursor.close() self.db_content.close() @staticmethod def create_phone(): """ 随机生成11位的手机号 :return:返回11位手机号组成的字符串 """ roughly = ["136", "137", "138", "158", "188", "180", "139", "133"] mantissa = "".join(random.sample("0123456789", 5)) phone = random.choice(roughly) + mantissa + "456" return phone def is_existed_phone(self, phone): """ 判断手机号在数据库中是否存在,存在返回True,不存在返回False :param phone:11位手机号组成的字符串 :return:Ture or False """ result = self.get_value(sql=self.sql, args=phone) if result: return True else: return False def create_unregistered_phone(self): """ 生成一个随机的手机号,判断它在数据库中是否存在,存在继续重复前面操作,不存在跳出循环,返回手机号 :return:未注册的手机号(数据库中查不到的手机号) """ while True: phone = self.create_phone() if not self.is_existed_phone(phone): break return phone def select_registered_phone(self): """ 数据库查找已注册的手机号 :return:未注册的手机号(数据库中查不到的手机号) """ sql = do_conifg.get_value(section="SQL", option="select_registered_phone") phone = self.get_value(sql=sql)["MobilePhone"] return phone
class OperationContext: """ 参数化测试数据 """ init_data_config = OperationConfig(filename=INIT_DATA_DIR) unregister_phone_pattern = do_conifg.get_value(section="PARAMETER", option="unregister") invest_phone_pattern = do_conifg.get_value(section="PARAMETER", option="invest_user") lender_pwd_pattern = do_conifg.get_value(section="PARAMETER", option="lender_pwd") admin_phone_pattern = do_conifg.get_value(section="PARAMETER", option="admin_user") admin_pwd_pattern = do_conifg.get_value(section="PARAMETER", option="admin_pwd") borrower_memberid_pattern = do_conifg.get_value(section="PARAMETER", option="borrower_memberid") lender_memberid_pattern = do_conifg.get_value(section="PARAMETER", option="lender_memberid") loan_id_pattern = do_conifg.get_value(section="PARAMETER", option="loan_id") verify_code_pattern = do_conifg.get_value(section="PARAMETER", option="verify_code") send_code_phone_pattern = do_conifg.get_value(section="PARAMETER", option="send_code_phone") @classmethod def unregister_phone_replace(cls, data): """ 未注册手机号的参数替换,如果从参数中匹配到模式字符串,则替换,否则不替换 :param data:原始字符串,data中的data值 :return:已替换手机号的原始字符串 """ if re.search(pattern=cls.unregister_phone_pattern, string=data): do_mysql = OperationMysql() unregistered_phone = do_mysql.create_unregistered_phone() data = re.sub(pattern=cls.unregister_phone_pattern, repl=unregistered_phone, string=data) do_mysql.close_db() return data @classmethod def register_phone_replace(cls, data): """ 已注册手机号的参数替换,如果从参数中匹配到模式字符串,则替换,否则不替换 :param data:原始字符串,data中的data值 :return: """ if re.search(pattern=cls.invest_phone_pattern, string=data): do_mysql = OperationMysql() registered_phone = cls.init_data_config.get_value( section="lender", option="mobilephone") data = re.sub(pattern=cls.invest_phone_pattern, repl=registered_phone, string=data) do_mysql.close_db() return data @classmethod def lender_pwd_replace(cls, data): """ 出借人密码的参数替换,如果从参数中匹配到模式字符串,则替换,否则不替换 :param data:原始字符串,data中的data值 :return: """ if re.search(pattern=cls.lender_pwd_pattern, string=data): do_mysql = OperationMysql() lender_pwd = cls.init_data_config.get_value(section="lender", option="pwd") data = re.sub(pattern=cls.lender_pwd_pattern, repl=lender_pwd, string=data) do_mysql.close_db() return data @classmethod def admin_phone_replace(cls, data): """ 管理员账号的参数替换,如果从参数中匹配到模式字符串,则替换,否则不替换 :param data:原始字符串,data中的data值 :return: """ if re.search(pattern=cls.admin_phone_pattern, string=data): do_mysql = OperationMysql() admin_phone = cls.init_data_config.get_value(section="admin", option="mobilephone") data = re.sub(pattern=cls.admin_phone_pattern, repl=admin_phone, string=data) do_mysql.close_db() return data @classmethod def admin_pwd_replace(cls, data): """ 管理员密码的参数替换,如果从参数中匹配到模式字符串,则替换,否则不替换 :param data:原始字符串,data中的data值 :return: """ if re.search(pattern=cls.admin_pwd_pattern, string=data): do_mysql = OperationMysql() admin_pwd = cls.init_data_config.get_value(section="admin", option="pwd") data = re.sub(pattern=cls.admin_pwd_pattern, repl=admin_pwd, string=data) do_mysql.close_db() return data @classmethod def borrower_memberid_replace(cls, data): """ 借款人id的参数替换,如果从参数中匹配到模式字符串,则替换,否则不替换 :param data:原始字符串,data中的data值 :return: """ if re.search(pattern=cls.borrower_memberid_pattern, string=data): do_mysql = OperationMysql() borrower_memberid = cls.init_data_config.get_value( section="borrower", option="id") data = re.sub(pattern=cls.borrower_memberid_pattern, repl=borrower_memberid, string=data) do_mysql.close_db() return data @classmethod def lender_memberid_replace(cls, data): """ 出借人id的参数替换,如果从参数中匹配到模式字符串,则替换,否则不替换 :param data:原始字符串,data中的data值 :return: """ if re.search(pattern=cls.lender_memberid_pattern, string=data): do_mysql = OperationMysql() lender_memberid = cls.init_data_config.get_value(section="lender", option="id") data = re.sub(pattern=cls.lender_memberid_pattern, repl=lender_memberid, string=data) do_mysql.close_db() return data @classmethod def loan_id_replace(cls, data): """ 项目ID的参数替换,如果从参数中匹配到模式字符串,则替换,否则不替换 :param data:原始字符串,data中的data值 :return: """ if re.search(pattern=cls.loan_id_pattern, string=data): do_mysql = OperationMysql() loan_id = OperationContext.loan_id data = re.sub(pattern=cls.loan_id_pattern, repl=loan_id, string=data) do_mysql.close_db() return data @classmethod def verify_code_replace(cls, data): """ 项目ID的参数替换,如果从参数中匹配到模式字符串,则替换,否则不替换 :param data:原始字符串,data中的data值 :return: """ if re.search(pattern=cls.verify_code_pattern, string=data): do_mysql = OperationMysql() verify_code = OperationContext.verify_code data = re.sub(pattern=cls.verify_code_pattern, repl=verify_code, string=data) do_mysql.close_db() return data @classmethod def send_code_phone_replace(cls, data): """ 项目ID的参数替换,如果从参数中匹配到模式字符串,则替换,否则不替换 :param data:原始字符串,data中的data值 :return: """ if re.search(pattern=cls.send_code_phone_pattern, string=data): do_mysql = OperationMysql() send_code_phone = OperationContext.send_code_phone data = re.sub(pattern=cls.send_code_phone_pattern, repl=send_code_phone, string=data) do_mysql.close_db() return data @classmethod def register_parameterization(cls, data): """ 注册模块用例参数化 :param data: 原始字符串 :return: 替换后的字符串 """ data = cls.unregister_phone_replace(data) data = cls.register_phone_replace(data) data = cls.lender_pwd_replace(data) data = cls.verify_code_replace(data) data = cls.send_code_phone_replace(data) return data @classmethod def login_parameterization(cls, data): """ 登录模块用例参数化 :param data: 原始字符串 :return: 替换后的字符串 """ data = cls.register_phone_replace(data) data = cls.lender_pwd_replace(data) return data @classmethod def recharge_parameterization(cls, data): """ 充值模块用例参数化 :param data: 原始字符串 :return: 替换后的字符串 """ data = cls.register_phone_replace(data) data = cls.lender_pwd_replace(data) return data @classmethod def add_parameterization(cls, data): """ 添加项目用例参数化 :param data: 原始字符串 :return: 替换后的字符串 """ data = cls.admin_phone_replace(data) data = cls.admin_pwd_replace(data) data = cls.borrower_memberid_replace(data) return data @classmethod def invest_parameterization(cls, data): """ 投资接口用例参数化 :param data: 原始字符串 :return: 替换后的字符串 """ data = cls.register_phone_replace(data) data = cls.lender_pwd_replace(data) data = cls.lender_memberid_replace(data) data = cls.admin_phone_replace(data) data = cls.admin_pwd_replace(data) data = cls.borrower_memberid_replace(data) data = cls.loan_id_replace(data) return data
# @Time :2019/7/24 22:53 # @Author :jinbiao import logging from common.operation_config import do_conifg from common.constans import LOG_DIR stream_level = do_conifg.get_value(section="LOG", option="stream_level") file_level = do_conifg.get_value(section="LOG", option="file_level") log_format = do_conifg.get_value(section="LOG", option="log_format") class OperationLog: """ 操作日志 """ def __init__(self, logger_name): """ 定义日志对象 :param logger_name: logger对象名称 """ self.logger = logging.getLogger(logger_name) # 定义日志收集器 self.logger.setLevel(level=logging.DEBUG) # 设置收集器的日志级别 handler_stream = logging.StreamHandler() # 定义日志输出渠道(控制台) handler_file = logging.FileHandler(filename=LOG_DIR, encoding="utf-8") # 定义日志输出渠道(文件) handler_stream.setLevel(level=stream_level) # 定义渠道日志输出级别 handler_file.setLevel(level=file_level) formatter = logging.Formatter(log_format) # 格式化日志 handler_file.setFormatter(formatter) handler_stream.setFormatter(formatter) self.logger.addHandler(handler_stream) # 收集器添加渠道