def __init__(self): super(UpdateAction, self).__init__() self.env = config.get('updateActionAPI') self.hosts = config.get('hosts').get(self.env) self.interfaces_path = '../../interfaces/%s/' % config.get( 'projectName') self.template_path = './template/'
class User(object): host_ip = config.get('hosts').get(config.get('run')) def __init__(self, mobile, account_type='user', **kwargs): self.db_user_info = DBUserInfo() self.request = Request() us = UserSession(mobile, account_type, **kwargs) self.token = us.token self.phone = mobile self.email = mobile self.user_id = us.userId self.device_id = us.deviceId
class SessionTool(object): host_ip = config.get('hosts').get(config.get('run')) def __init__(self): pass def get_user_session(self, mobile, account_type='user', **kwargs): """ 追花族-邮箱密码登录 :param:account 邮箱 :param: account_type 密码 :param: password 密码 :param: wxcode 微信临时授权code,可以直接使用数据已绑定的微信openid :return: """ data = {"appId": "FLOWER_CHASERS", "deviceType": "ANDROID", "deviceId": "cc4feebe419791332bbcff5e0fdf084a", "mobile": mobile, "verifyCode": 8888} host = config.get('loginhosts').get(config.get('run')).get('PASSPORT') if account_type == 'user': session = Request().post(url=host + "/mobile/sso/sms-login", data=data) elif account_type == 'employee': session = Request().post(url=host + "/admin/sso/email-login", data=data) elif account_type == 'web-mp': data['deviceType'] = 'WEB' session = Request().post(url=host + "/admin/sso/sms-login", data=data) elif account_type == 'wf_account': datas = {'appId': 'WORLD_FARM', 'deviceType': 'IOS', 'deviceId': 'qaTeam', 'account': mobile, 'password': kwargs['password']} session = Request().post(url=host + "/mobile/sso/email-login", data=datas) elif account_type == 'wxshop': data.update(kwargs) session = Request().post(url=host + "/web/sso/mall-login-wx", data=data) else: raise Exception("account_type非法, 仅支持user/employee") if account_type in ('web-mp') and json.loads(session).get('status') == 'OK': headers = Request.headers.copy() headers['_Device-Id_'] = json.loads(session)['content']['deviceId'] headers['_Token_'] = json.loads(session)['content']['token'] host = host.replace('world-passport', 'fc-bee') resp = Request().post(url=host + '/admin/fc-user/permission-check', headers=headers) if json.loads(resp).get('status') == 'ERROR': session = resp return session
class DBUserInfo(object): host_ip = config.get('database').get(config.get('run')).get('host_ip') def mgr_query_user_info_by_account(self, account): sql = """ SELECT tu.phone, tu.username, tk.*, tu.is_delete FROM `world-user`.t_user tu LEFT JOIN (SELECT user_id, device_id, token, create_time FROM `world-passport`.t_login_token tlt WHERE is_delete = 0) AS tk ON tu.id = tk.user_id WHERE (tu.phone = '%s' or tu.email = '%s') AND tu.is_delete = 0 ORDER BY create_time DESC LIMIT 1; """ % (account, account) user_info = DataBaseOperate().operate(self.host_ip, sql) return user_info
def __init__(self): # 初始化数据库链接 self.SQLALCHEMY_MIGRATE_REPO = os.path.join( os.path.abspath(os.path.dirname(__file__)), 'db_repository') self.dataBaseURI = decrypt(config.get('dataBaseURI')) # self.dataBaseURI = 'mysql+pymysql://jira:[email protected]:3306/jira' self.__engine = create_engine( self.dataBaseURI, max_overflow=5, # 超过连接池大小外最多创建的数量, pool_size=5, # 连接池的大小 pool_timeout=30, # 池中没有线程最多等待的时间 pool_recycle=-1, # 多久之后对线程中的线程进行一次连接的回收(重置) encoding="utf-8", echo=False) Base.metadata.create_all(self.__engine) self.session = None
def skip_case(case_level): """ 判断是否需要跳过用例 设置执行用例等级5个,按优先级执行 1.主流程执行用例,保证接口调通,非必填字段全部填写 2.主流程执行用例,保证接口调通,非必填字段可用不填写 3.分支流程,校验必填字段错误类型 4.分支流程,校验非必填字段错误类型 5.其他 :param level: 用例等级 :return: 返回布尔值 """ run_level = config.get('RUN_LEVEL') if run_level > 5: log.info('设置跳过运行等级不能大于5') return if 0 < run_level <= case_level: return True return False
class Request(object): version = config.get('version') headers = { "Content-Type": "application/x-www-form-urlencoded", "Accept": "application/json", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) " "AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/68.0.3440.106 Safari/537.36", "_App-Version_": version, "_Device-Type_": "iOS", "region": "online", "Accept_Language": "zh" } api_headers = { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9", "Cache-Control": "max-age=0", "Connection": "keep-alive", "Host": "qa-gateway.worldfarm.com", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36" } @staticmethod def url_encode(string): cn = '' for ch in string.decode('utf-8'): if u'\u4e00' <= ch <= u'\u9fff': cn += urllib.quote(ch.encode('utf-8')) else: cn += ch.encode('utf-8') return cn def post(self, url, data=None, headers=None, jsons=None, hosts=None): client = requests.session() if headers is None: headers = self.headers.copy() if url.find('mgr.agrrobot.com') > 0: headers['Authentication-Token'] = data.get('_tk_') if url.find('admin/supplier/add') > 0 or url.find( "/admin/supplier/edit") > 0: headers["Content-Type"] = 'application/json;charset=UTF-8' if jsons is not None: headers["Content-Type"] = 'application/json;charset=UTF-8' response = client.post(url=url, data=data, json=jsons, headers=headers, cookies=None) content = response.content log.info('headers: %s' % headers) Content_Type = response.headers.get('Content-Type') log.info(Content_Type) if not Content_Type.find('excel'): content = content.decode("utf-8") log.debug('\n\trequest: %s\n\tdata: %s\n\tjson: %s\n\tresponse: %s' % (url, data, jsons, content)) try: response_json = json.loads(content) log.debug("\n" + json.dumps(response_json, ensure_ascii=False, sort_keys=True, indent=2, separators=(',', ': '))) except ValueError: log.debug(content) # rea().reload_data(host_name=hosts, url=url) client.close() return content def get(self, url, hosts=None, params=None): client = requests.session() if url.find('/v2/api-docs'): headers = None else: headers = self.headers response = client.get(url=url, headers=headers, params=params).content try: log.debug('\n\trequest: %s\n\tresponse: %s\n\t' % (url, response.decode("utf-8"))) response_json = json.loads(response.decode("utf-8")) # log.debug("\n" + json.dumps(response_json, ensure_ascii=False, # sort_keys=True, indent=2, separators=(',', ': '))) log.debug("\n" + json.dumps(response_json)) except ValueError: log.debug(response) # rea().reload_data(host_name=hosts, url=url) client.close() return response.decode("utf-8") def post_file(self, url, file_path, data=None, hosts=None): file_name = file_path.split("/")[-1:][0] file_bin_data = open(file_path, 'rb') content_type = str( mimetypes.types_map.get("." + file_path.split(".")[-1:][0], None)) files = {'file': (file_name, file_bin_data, content_type)} headers = self.headers.copy() headers.pop('Content-Type') if url.find('mgr.agrrobot.com') > 0: headers['Authentication-Token'] = data.get('_tk_') response = requests.post(url=url, data=data, files=files, headers=headers).content log.debug('\n\trequest: %s\n\tfile: %s\n\tresponse: %s' % (url, file_path, response.decode("utf-8"))) try: response_json = json.loads(response) log.debug("\n" + json.dumps(response_json, ensure_ascii=False, sort_keys=True, indent=2, separators=(',', ': '))) except ValueError: log.debug(response) # rea().reload_data(host_name=hosts, url=url) return response.decode("utf-8")
def get_database_data(self, host): log.info("从数据库获取接口信息") session = self.__db_engine.creat_session() # 获取该服务器下所有接口 whichService = session.query(Server.id).filter( or_(Server.qaURL == host, Server.devURL == host), and_(Server.serverStatus == 1)).first() if whichService == [] or whichService is None: servername = '' for i in self.env.keys(): if self.env.get(i) == host: servername = i break serverid = session.query(Server).filter( and_(Server.serverName == servername, Server.serverStatus == 1)).first() if config.get('updateActionAPI') in ('DEV_API', 'DEV'): devurl = host qaurl = config.get('hosts').get('QA').get(servername) else: qaurl = host devurl = config.get('hosts').get('DEV').get(servername) if serverid == [] or serverid is None: addserver = Server(serverName=servername, swaggerURI='/v2/api-docs', qaURL=qaurl, devURL=devurl, serverStatus=1) session.add(addserver) else: log.info('数据库中已有相同的服务名:%s' % servername) session.commit() whichService = session.query(Server.id).filter( or_(Server.qaURL == host, Server.devURL == host)).first() whichService = whichService.id apis = session.query(Interface.id, Interface.apiPath, Interface.apiDesc, Interface.apiRequestMethod).filter( and_(Interface.apiServerId == whichService, Interface.apiStatus == 1)).all() api_result = {} # 获取接口中所有参数信息 for api in apis: api_id = api[0] api_path = api[1] api_desc = api[2] api_method = api[3] # 组装要返回的api请求响应参数信息 api_result.update({ api_path: { "desc": api_desc, "method": api_method, "inParameter": None, "outParameter": None } }) # 组装请求字段信息 try: in_parameter = session.query( InputParameters.inParameter).filter( and_(InputParameters.apiId == api_id, InputParameters.inParameterStatus == 1)).one() api_result.get(api_path).update( {"inParameter": json.loads(in_parameter[0])}) except orm.exc.NoResultFound: api_result.get(api_path).update({"inParameter": None}) # 组装响应字段信息 try: out_parameter = session.query( ExtractParameters.extParameter).filter( and_(ExtractParameters.apiId == api_id, ExtractParameters.extParameterStatus == 1)).one() api_result.get(api_path).update( {"outParameter": json.loads(out_parameter[0])}) except orm.exc.NoResultFound: api_result.get(api_path).update({"outParameter": None}) self.__db_engine.close_session() return api_result
def __init__(self): self.__db_engine = DBEngine() # self.database_data = self.get_database_data() self.env = config.get('hosts').get(config.get('updateActionAPI'))
def __init__(self, env): self.hosts = config.get('hosts').get(env)
def create_action(self, url_host: str, host_name: str): """ 解析参数牲畜对应action文件 :param url_host: :param host_name: :return: """ urldict = config.get('urldict') # 生成类和构造方法 account_type = config.get('accounttype') action_name = urldict.get(url_host) lower_action = action_name.lower() url_host = url_host # 读取模板文件,替换相应的字段 action_template = open(self.template_path + 'action_template.txt', 'r', encoding='utf-8').read() rep = { 'lower_action': lower_action, 'action_name': action_name, 'url_host': url_host, 'accounttype': account_type } rep = dict((re.escape(k), v) for k, v in rep.items()) pattern = re.compile("|".join(rep.keys())) action_template = pattern.sub(lambda m: rep[re.escape(m.group(0))], action_template) # 创建action文件 now = datetime.datetime.now().strftime("%Y-%m-%d_%H%M%S") import os # todo action_file_name = self.interfaces_path + action_name.capitalize( ) + "Action_%s.py" % now # 读取方法模板文件 fun_template = open(self.template_path + 'fun_post_template.txt', 'r').read() with open(action_file_name, "w", encoding='utf-8') as f: f.writelines(action_template) # 解析数据源组成方法参数 path_detail_list = self.get_api_paths(host_name) for api_data in path_detail_list: for api, value in api_data.items(): f.write('\n') # 获取接口替换特殊符号,生成方法名 fun_str = "[\/\-\【\】 \{\}]" fun_name = re.sub(fun_str, '_', api[1:]).replace(".", "") fun_data = param_data = param_datas = '' if isinstance(value[2], dict): paramlist = list(value[2].keys()) for param in paramlist: param = re.sub('[\.\-]', '_', param) if account_type == 'wf_account': param_data += ", '%s': %s" % (param, param) param_datas += "'%s': %s, " % (param, param) fun_data += ", " + param + '=None' else: param_data += ", '%s': %s" % (param, param + '_') param_datas += "'%s': %s, " % (param, param + '_') fun_data += ", " + param + '_=None' fun_str = self.constitute_request_method( request_method=value[1], param_data=param_data, lower_action=lower_action, fun_name=fun_name, param_datas=param_datas, fun_data=fun_data, api=api) f.writelines(fun_str)