def request(self, method, url, data=None): method = method.upper() # 将字符转换成大写 增强程序的健壮性 config = ReadConfig() pre_url = config.get("api", "pre_url") url = pre_url + url if data is not None and type(data) == str: #python中json和eval函数的区别: #1 json是跨语言的,而eval是python的函数,是基于python的格式进行转换的,用eval函数,只能是转换python格式的数据类型,eval的作用范围比较小,而eval函数的作用范围比较大,json的跨语言的数据格式 # data = eval(data) #如果是字符串就转回字典 data = json.loads(data) #如果是字符串就转回字典 logger.info('method: {0} url: {1}'.format(method, url)) logger.info('data: {0}'.format(data)) if method == 'GET': resp = self.session.request( method, url=url, params=data) # 调用get方法,使用params传参(url传参) logger.info('response: {0}'.format(resp.text)) return resp elif method == 'POST': resp = self.session.request(method, url=url, data=data) # 调用post方法,使用data传参(表单传参) logger.info('response: {0}'.format(resp.text)) return resp else: logger.info('un-support method!')
def request(self, method, url, data=None): method = method.upper() # 将字符串全部转化成大写 if data is not None and type( data) == str: # 从表格中读取的data是字符串类型,而request里需要字典 data = eval(data) # 将字符串转化成字典 # data = json.loads(data) #将json格式的字符串转化为字典 logger.info('url: {0}'.format(url)) config = ReadConfig() pre_url = config.get('api', 'pre_url') url = pre_url + url #URL拼接 logger.info('method: {0} 拼接后url: {1}'.format(method, url)) logger.info('data: {0}'.format(data)) # print('data: {0}'.format(data),type(data)) if method == 'GET': resp = self.session.request(method, url=url, params=data) # 调用get方法,使用params传参 logger.info('response: {0}'.format(resp.text)) return resp elif method == 'POST': resp = self.session.request(method, url=url, data=data) # 调用post方法,使用data传参 logger.info('response: {0}'.format(resp.text)) return resp else: logger.error('Un-support method !!!')
def test_reg(self, case): print("开始执行第{}个测试用例:".format(case.case_id)) import json data_dict = json.loads(case.data) if data_dict["mobilephone"] == "${register_mobile}": data_dict["mobilephone"] = int(self.max) + 1 read_config = ReadConfig() pre_url = read_config.get("api", "pre_url") resp = self.request.request(method=case.method, url=pre_url + case.url, data=data_dict) doexcels = doexcel.DoExcel(contants.case_file, "reg") try: self.assertEqual(case.expected, resp.text) doexcels.write_back(row=case.case_id + 1, col=8, value="PASS", sheet_name="reg") except AssertionError as e: doexcels.write_back(row=case.case_id + 1, col=8, value="FAIlED", sheet_name="reg") doexcels.write_back(case.case_id + 1, 7, resp.text, sheet_name="reg") print(resp.text)
def test_run_cases(self,case): print("执行第{0}条测试用例,测试title是:{1}".format(case['id'],case['title'])) #调用读取配置文件类 read_config = ReadConfig() url = read_config.get('api', 'pre_url') +case['url']#URL进行拼接 #查找参数化的测试数据,进行动态替换 data=context.replace(case['data']) # 使用封装好的HttpRequest类中的http_request方法来完成请求 res=self.request.http_request(case['method'],url,data) #断言 try: self.assertEqual(case['ExpectedResult'],int(res.json()['code'])) print("测试结果:Pass") TestResult = 'Pass' #判断是否加标成功,如果成功就按照借款人的ID去数据库查询最新的标记录 if res.json()['msg'] == '加标成功': loan_member_id = getattr(Context, 'loan_member_id') sql = "select id from future.loan where memberID='{0}'" \ " order by createTime desc limit 1".format(loan_member_id) loan_id = self.mysql.fetch_one(sql)[0] setattr(Context, 'loan_id',str(loan_id)) # 转成str,后续通过正则替换 except Exception as e: print("执行接口测试期望结果与实际结果不一致:{0}".format(e)) print("测试结果:Fail") TestResult = 'Fail' raise e finally: DoExcel(contants.cases_file, 'invest').write_back(case['id'] + 1, 7,str(res.json()['code'])) # 写入实际结果 DoExcel(contants.cases_file, 'invest').write_back(case['id'] + 1, 8, TestResult) # 写入测试结论
def request(self, method, url, data=None): # 因为共享session,所以这里不需要传cookie了 # 引入配置文件 拼接url config = ReadConfig() pre_url = config.get('api', 'pre_url') url = pre_url + url method = method.upper() # 将字符串全改成大写,兼容性 if data is not None and type(data) == str: data = eval(data) # 如果是字符串需转字典。否则运行结果为:...'手机号码不能为空' print('method:{0} url:{1}'.format(method, url)) print('data:{0}'.format(data)) if method == 'GET': # return self.session.request(method, url=url, params=data) # 注意方式params,data要传字典 resp = self.session.request(method, url=url, params=data) print('response:{0}'.format(resp.text)) return resp elif method == 'POST': # return self.session.request(method, url=url, data=data) # 注意方式data,data要传字典 resp = self.session.request(method, url=url, data=data) print('response:{0}'.format(resp.text)) return resp else: print('Un-support method !!!')
def request(self, method, url, data=None): method = method.upper() # 将字符转成全部大写 config = ReadConfig() pre_url = config.get('api', 'pre_url') url = pre_url + url if data is not None and type(data) == str: data = eval(data) # 如果是字符串就转成字典 logger.info('method:{0} url:{1}'.format(method, url)) logger.info('data:{}'.format(data)) if method == 'GET': resp = self.session.request(method, url=url, params=data) logger.info('response:{}'.format(resp.text)) return resp elif method == 'POST': resp = self.session.request(method, url=url, data=data) logger.info('response:{}'.format(resp.text)) return resp else: logger.error('Un-support method!!!')
def __init__(self): config = ReadConfig() host = config.get_value('DB', 'host') user = config.get_value('DB', 'user') pwd = config.get_value('DB', 'pwd') self.mysql = pymysql.connect(host=host, user=user, password=pwd, port=3306) # 连接数据库 self.cursor = self.mysql.cursor() # 获取操作游标
def __init__(self, return_dict=False): # 数据库参数修改请到配置文件下 self.database = pymysql.connect( host=ReadConfig().get_value("mysql-conf", "host"), # 如果是服务器,则输公网ip user=ReadConfig().get_value("mysql-conf", "user"), # 当时设置的数据超级管理员账户 passwd=ReadConfig().get_value("mysql-conf", "password"), # 当时设置的管理员密码 port=ReadConfig().get_int("mysql-conf", "port"), # MySQL数据的端口为3306,注意:切记这里不要写引号'' database=ReadConfig().get_value("mysql-conf", "database") # 当时 ) if return_dict: self.cursor = self.database.cursor(pymysql.cursors.DictCursor) # 指定每行数据以字典的形式返回 else: self.cursor = self.database.cursor() # 获取一个游标 — 也就是开辟一个缓冲区,用于存放sql语句执行的结果
def __init__(self): # 想想这块如何放到配置文件里面去??? # host = "test.lemonban.com" # user = "******" # password = "******" config = ReadConfig() host = config.get('db', 'host') user = config.get('db', 'user') password = config.get('db', 'pwd') port = config.getint('db', 'port') # 1,建立连接 self.mysql = pymysql.connect(host=host, user=user, password=password, port=port) # 2,新建一个查询 self.cursor = self.mysql.cursor()
def __init__(self,return_dacit=False): #建立数据库连接 # host = "test.lemonban.com" # user = "******" # password = "******" config = ReadConfig() host = config.get("database", "host") user = config.get("database","user") password = config.get("database","password") self.mysql = pymysql.connect(host=host, user=user, password=password, port=3306) # 新建一个查询页面 if return_dacit: self.cursor = self.mysql.cursor(pymysql.cursors.DictCursor)#指定每行数据以字典的形式返回 else: self.cursor = self.mysql.cursor()#指定每行数据以元组的形式返回
def __init__(self, return_dict=False): # 1.建立连接 config = ReadConfig() host = config.get('db', 'host') user = config.get('db', 'user') password = config.get('db', 'password') port = config.getint('db', 'port') self.mysql = pymysql.connect(host=host, user=user, password=password, port=port) if return_dict: self.cursor = self.mysql.cursor( pymysql.cursors.DictCursor) #指定每行数据以字典的形式返回 else: self.cursor = self.mysql.cursor() #指定每行数据以元祖的形式返回
def __init__(self, return_dict=False): config = ReadConfig() host = config.get('db', 'host') user = config.get('db', 'user') password = config.get('db', 'password') port = config.getint('db', 'port') self.mysql = pymysql.connect(host=host, user=user, password=password, port=port, charset="utf8") if return_dict: self.cursor = self.mysql.cursor( pymysql.cursors.DictCursor) # 指定每行数据以字典的形式返回 else: self.cursor = self.mysql.cursor() # 此语句放在初始化里面,表示多次查询建立一个查询页面
def __init__(self, return_dict=False): # 想想这块如何放到配置文件里面去??? # host = "test.lemonban.com" # user = "******" # password = "******" config = ReadConfig() host = config.get('db', 'host') user = config.get('db', 'user') password = config.get('db', 'pwd') port = config.getint('db', 'port') # 1,建立连接 self.mysql = pymysql.connect(host=host, user=user, password=password, port=port) # 2,新建一个查询 if return_dict: self.cursor = self.mysql.cursor(pymysql.cursors.DictCursor) # 指定每行数据以字典的形式返回 else: self.cursor = self.mysql.cursor() # 指定每行数据以元祖的形式返回
def request(self, url, method, params=None): method = method.upper() config = ReadConfig() pre_url = config.get_value("env-api", "pre_url") url = pre_url + url if params is not None and type(params) == str: params = MyJson().to_python_dict(params) if method == "GET": res = self.session.get(url=url, params=params) logger.info('response: {0}'.format(res.text)) elif method == "POST": res = self.session.post(url=url, data=params) logger.info('response: {0}'.format(res.text)) else: logger.error("请检查请求方式是否正确") raise Exception("请检查请求方式是否正确") return res
class RechargeTest(unittest.TestCase): do_excel = DoExcel(contants.case_file) # 传入cases.xlsx cases = do_excel.read('recharge') @classmethod def setUpClass(cls): # 每个测试类 里面取运行的操作放在类方法。一个类只一次 print("\n这是一个setUpClass类方法\n") # 登陆也可以放在这里做 cls.request = Request() # 实例化对象。为啥没传cookie,就因为这里封装request创建了会话 def setUp(self): # 每个测试方法 里面取运行的操作。一个方法一次 logger.info("这是一个setUp") pass # 引入配置文件,获取固定充值手机号 config = ReadConfig() pre_investor = config.get('investor', 'mobilephone') @data(*cases) def test_recharge(self, case): logger.info("开始执行第{0}条用例:{1}".format(case.case_id, case.title)) # 引入转换格式 替换固定充实手机号 import json data_dict = json.loads(case.data) if data_dict['mobilephone'] == '${investor}': data_dict['mobilephone'] = self.pre_investor print('pre_investor', type(self.pre_investor), self.pre_investor) print("data_dict['mobilephone']", type(data_dict['mobilephone']), data_dict['mobilephone']) resp = self.request.request(case.method, case.url, data_dict) # 将返回结果和期望结果进行匹配 try: self.assertEqual( case.expected, resp.json()['code'], "recharge error") # case.text变成resp.json()字典再取code值比对。 # 一致就写入Excel的结果位PASS,并且 self.do_excel.write_back(case.case_id + 1, resp.text, 'PASS') logger.info("第{0}用例执行结果:PASS".format(case.case_id)) except AssertionError as e: self.do_excel.write_back(case.case_id + 1, resp.text, 'FAIL') logger.error("第{0}用例执行结果:FAIL".format(case.case_id)) logger.error("断言出错了:{}".format(e)) raise e # my_logger.error('报错了信息:{}'.format(self.e)) # finally: # self.request.session.close() # 不能放在finally里面,否则每次运行都关闭了 def tearDown(self): pass @classmethod def tearDownClass(cls): cls.request.session.close() # request封装session对话用完要关闭
def test_run_cases(self,case): print("执行第{0}条测试用例,测试title是:{1}".format(case['id'],case['title'])) #调用读取配置文件类 read_config = ReadConfig() url = read_config.get('api', 'pre_url') +case['url']#URL进行拼接 # 使用封装好的HttpRequest类中的http_request方法来完成请求 res=self.request.http_request(case['method'],url,case['data']) #断言 try: self.assertEqual(eval(case['ExpectedResult']),res.json()) print("测试结果:Pass") TestResult = 'Pass' except Exception as e: print("执行接口测试期望结果与实际结果不一致:{0}".format(e)) print("测试结果:Fail") TestResult = 'Fail' raise e finally: DoExcel(contants.cases_file, 'recharge').write_back(case['id'] + 1, 7, str(res.json())) # 写入实际结果 DoExcel(contants.cases_file, 'recharge').write_back(case['id'] + 1, 8, TestResult) # 写入测试结论
def test_bindBankCard(self, value): url = ReadConfig().get_value("env-api", "pre_url") + value["url"] client = Client(url) # print(self.userRegister_data) # client.service.userRegister(self.userRegister_data) # print(self.verifyUserAuth_data) client.service.verifyUserAuth(self.verifyUserAuth_data) # 以上代码跑通 # 以下对绑定银行卡设计用例 data = eval(context.replace_new(value["data"])) data["uid"] = self.uid data["cre_id"] = self.verifyUserAuth_data["cre_id"] if value["title"] != "持卡人姓名为空": data['user_name'] = self.verifyUserAuth_data["true_name"] else: data['user_name'] = None if value["title"] == "证件id为空": data["cre_id"] = None if value["title"] == "uid为空": data["uid"] = None if value["title"] == "uid不存在": data["uid"] = "99999999" if value["title"] != "银行卡卡号格式不正确" and value["title"] != "银行卡卡号为空": data["cardid"] = "6212264301007974189" if value["title"] != "手机号码为空" and value["title"] != "手机号码格式不正确": data["mobile"] = self.mobile # print(data) res = self.client.service.bindBankCard(data) logger.info("请求成功,结果是{}".format(res)) # print(res) actual = str(res.retCode) expect = str(value["expect"]) id = value["id"] try: ''' 该接口有问题,所以数据校验没做 如果做,比对id等字段 表:user_db_xx.t_bind_card_x 按uid后三位分库分表,倒数2位代表user_db库,倒数第三位代表表的位置 ''' self.assertEqual(expect, actual) logger.info("状态码校验成功") self.excel.write_data(id + 1, 7, actual) self.excel.write_data(id + 1, 8, "PASS") except AssertionError as e: logger.error("数据校验失败") self.excel.write_data(id + 1, 7, actual) self.excel.write_data(id + 1, 8, "Failed") raise e
def request(self, method, url, data=None): method = method.upper() # 将字符串全部转成大写 config = ReadConfig() value = config.get('api', 'pre_url') url = value + url if data is not None and type(data) == str: data = json.loads(data) logger.info('method:{0} url:{1}'.format(method, url)) logger.info('data:{0}'.format(data)) if method == 'GET': resp = self.session.request(method, url=url, params=data) logger.info('response:{0}'.format(resp.text)) return resp elif method == 'POST': resp = self.session.request(method, url=url, data=data) logger.info('response:{0}'.format(resp.text)) return resp else: logger.error('unsupport method')
def test_invest(self,case): readconfig = ReadConfig() pre_url = readconfig.get("api","pre_url") print("开始执行第{}个测试用例:".format(case.case_id)) case.data = replace(case.data) resp = self.request.request(method=case.method,url = pre_url+case.url,data=case.data) doexcels = doexcel.DoExcel(contants.case_file, "invest") try: self.assertEqual(case.expected,resp.text) doexcels.write_back(row=case.case_id + 2, col=8, value="PASS", sheet_name="invest") #加一层判断,判断加标是否成功,如果成功,就把标的的ID查出来反射给类的属性,以便下一条用例取 if resp.json()["msg"] == "加标成功": load_member_id = getattr(Context,"loan_member_id") mysql = MysqlUtil() sql = "select Id from future.loan where MemberID={} order by CreateTime desc limit 1".format(load_member_id) loan_id = mysql.fetchone(sql)[0] setattr(Context,"loan_id",str(loan_id)) except AssertionError as e: doexcels.write_back(row=case.case_id + 2, col=8, value="FAIlED", sheet_name="invest") doexcels.write_back(case.case_id + 2,7,resp.text,sheet_name="invest") print(resp.text)
def setUp(self): self.MCode_data = eval( context.replace_new('{"mobile": "${mobile}", "tmpl_id": 1, "client_ip": "47.107.168.87"}')) self.mobile = self.MCode_data["mobile"] self.userRegister_data = eval(context.replace_new('{"channel_id": "1", "ip": "129.45.6.7",' ' "mobile": "${mobile}", "pwd": "453173", ' '"user_id": "${user_id}", "verify_code": "${verify_code}"}')) self.verifyUserAuth_data = eval(context.replace_new('{"uid": "${uid}", "true_name": "${true_name}",' ' "cre_id": "${cre_id}"}')) self.userRegister_data["mobile"] = self.mobile self.client01 = Client( ReadConfig().get_value("env-api", "pre_url") + "sms-service-war-1.0/ws/smsFacade.ws?wsdl") self.client01.service.sendMCode(self.MCode_data) self.userRegister_data["verify_code"] = MCode().getMcode(self.mobile) url = ReadConfig().get_value("env-api", "pre_url") + "finance-user_info-war-1.0/ws/financeUserInfoFacade.ws?wsdl" self.client = Client(url) self.client.service.userRegister(self.userRegister_data) self.verifyUserAuth_data["uid"] = self.uid = db_select.getuid(self.userRegister_data["user_id"]) self.true_name = self.verifyUserAuth_data["true_name"]
def test_addloan(self, case): readconfig = ReadConfig() pre_url = readconfig.get("api", "pre_url") print("开始执行第{}个测试用例:".format(case.case_id)) resp = self.request.request(method=case.method, url=pre_url + case.url, data=case.data) doexcels = doexcel.DoExcel(contants.case_file, "addloan") try: self.assertEqual(case.expected, resp.text) doexcels.write_back(row=case.case_id + 2, col=8, value="PASS", sheet_name="addloan") except AssertionError as e: doexcels.write_back(row=case.case_id + 2, col=8, value="FAIlED", sheet_name="addloan") doexcels.write_back(case.case_id + 2, 7, resp.text, sheet_name="addloan") print(resp.text)
def request(self, method, url, data=None): method = method.upper() url = ReadConfig().get_value('URL', 'pre_url') + url self.mylog.info('url:'.format(url)) self.mylog.info('data:{}'.format(data)) if data is not None and type(data) == str: data = eval(data) #如果data是字符串,转换成字典 if method == 'GET': resp = self.session.request(method=method, url=url, params=data) self.mylog.info('response:{}'.format(resp.text)) return resp elif method == 'POST': resp = self.session.request(method=method, url=url, data=data) self.mylog.info('response:{}'.format(resp.text)) return resp else: self.mylog.info('Un-supported method !!!')
class MysqlUntil: get_conf = ReadConfig() def __init__(self): # self.config.read(contains.conf_global, encoding='utf-8') host = self.get_conf.get('db', 'host') user = self.get_conf.get('db', 'user') password = self.get_conf.get('db', 'password') self.mysql = pymysql.connect(host=host, user=user, password=password, port=3306) self.cursor = self.mysql.cursor() def fetch_one(self, sql): #查询数据库 self.cursor.execute(sql) result = self.cursor.fetchone() return result def close_mysql(self): self.cursor.close() self.mysql.close()
def my_log(log_name): config = ReadConfig() log_level = config.get_value('LOG', 'log_level') #从配置文件中读取日志级别 console_level = config.get_value('LOG', 'console_level') #从配置文件读取控制台输出级别 file_level = config.get_value('LOG', 'file_level') #日志存放文件中的级别 formatter = config.get_value('LOG', 'formatter') #从配置文件读取输出格式 log_file = constant.log_file #获取log文件存放路径 my_logger = logging.getLogger(log_name) #创建一个日志收集器 my_logger.setLevel(log_level) formatter = logging.Formatter(formatter) ch = logging.StreamHandler() ch.setLevel(console_level) ch.setFormatter(formatter) fh = logging.FileHandler(log_file, encoding='utf-8') fh.setLevel(file_level) fh.setFormatter(formatter) my_logger.addHandler(ch) my_logger.addHandler(fh) return my_logger
def __init__(self, filepath, sheet_name): self.filepath = filepath self.sheet_name = sheet_name self.conf = ReadConfig().get_value("test_case_id", "button")
# File : mylog.py # IDE : PyCharm #1. 日志文件名参数化 #2.级别配置化 #3.输出路径参数化 import logging import logging.handlers import os from common.config import ReadConfig from common import contants conf = ReadConfig() def get_log(log_name): my_logger=logging.getLogger(log_name) #定义一个日志收集器 my_logger.setLevel('DEBUG') #定义收集器的级别 fmt=logging.Formatter('%(asctime)s-%(levelname)s-%(name)s-日志信息:%(message)s-(%(filename)s:%(lineno)d)') #设置格式 ch=logging.StreamHandler() #创建一个输出到控制台的渠道 level=conf.get('LogLevel','console')#从配置文件获取级别 ch.setLevel(level) ch.setFormatter(fmt) #设置输出格式
# !/usr/bin/python3 # -*- coding: utf-8 -*- # @Time :2019/1/6 16:52 # @Author :Yosef # E-mail :[email protected] # File :mylog.py # Software :PyCharm Community Edition import logging import logging.handlers from common.config import ReadConfig from common import contants config = ReadConfig() def get_logger(logger_name): logger = logging.getLogger(logger_name) logger.setLevel('DEBUG') # 直接设置为最低 # 定义输出格式 fmt = config.get_value("logs", "formatter") formate = logging.Formatter(fmt) file_handler = logging.handlers.RotatingFileHandler(contants.logs_log, maxBytes=20 * 1024 * 1024, backupCount=10, encoding="utf-8") level = config.get_value('logs', 'file_handler') file_handler.setLevel(level) file_handler.setFormatter(formate) console_handler = logging.StreamHandler() level = config.get_value('logs', 'console_handler') console_handler.setLevel(level) console_handler.setFormatter(formate)
# @Time : 2019-05-19 17:09:05 # @Author : lemon_xiuyu # @Email : [email protected] # @File : logger.py # @function : mongo老师的log新方法 import logging # 华华老师教的方法 import logging.handlers # 芒果老师的新方法 import os # 引入拼接 from common import contants # 引入根目录文件 from common.config import ReadConfig # 输出到文件,文件路径请使用绝对路径 logs目录下 # 输出到控制台,定义输出级别是debug # 不同的输出级别可配置 config = ReadConfig() # 实例化配置文件 def get_logger(logger_name): # 通过函数进行封装 logger = logging.getLogger(logger_name) # 实例化创建监听器,名字默认的是root logger.setLevel('INFO') # 监听器级别,直接设最低,写死不需配置 fmt = "%(asctime)s - %(name)s - %(levelname)s - %(message)s - [%(filename)s:%(lineno)s]" # 定义日志格式 formate = logging.Formatter(fmt) # 定义日志格式,Formatter里有格式 file_name = os.path.join(contants.logs_dir, 'case.log') # 读取配置文件-输出文件路径 file_handler = logging.handlers.RotatingFileHandler( file_name, maxBytes=20 * 1024 * 1024, backupCount=10, encoding='utf-8') # 输出到文件。 maxBytes是最大字节数,backupCount是备份次数 level = config.get('log', 'file_handler') # 读取配置文件-输出文件级别 file_handler.setLevel(level) # 输出文件级别 file_handler.setFormatter(formate) # 设置输出文件格式
def __init__(self): self.session = requests.sessions.session( ) #requests.sessions.Session`是一个建立会话的类 self.value = ReadConfig().get('api', 'pre_url') #读取配置文件的不同环境
# coding: utf-8 # web-action # logger # shen # 2019/3/17 19:59 import logging import logging.handlers from common import contants from common.config import ReadConfig config = ReadConfig() in_level = eval(config.get_value('LogNew', 'in_level')) out_level = eval(config.get_value('LogNew', 'out_level')) file_out_level = eval(config.get_value('LogNew', 'file_out_level')) data_formatter = config.get_value('LogNew', 'fmt') def get_logger(logger_name): """ :param logger_name: 定义日志输出的名称 :return: """ logger = logging.getLogger(logger_name) logger.setLevel(in_level) fmt = data_formatter formate = logging.Formatter(fmt) file_name = contants.log_file file_handler = logging.handlers.RotatingFileHandler( file_name, maxBytes=20*1024*1024, backupCount=10, encoding="utf-8")