def suite_update(): ''' 更新测试集信息 Args: JSON sid:测试集id ''' if request.method == 'POST': if not g.user.uid: return jsonify(Const.errcode('1001')) req_data_json = request.json suite_dt = odb.update(TestSuite, 'sid', int(req_data_json['sid']), s_name=req_data_json['s_name'], s_desc=req_data_json['s_desc']) res = { 'suite': { "sid": suite_dt.sid, "new_s_name": suite_dt.s_name, "p_id": suite_dt.p_id } } return jsonify(Const.errcode('0', res=res)) return abort(404)
def login(): if request.method == 'POST': username = request.json['username'] password = request.json['password'] error = None user = odb.query_per(User, 'username', username) # check_password_hash() 以相同的方式哈希提交的 密码并安全的比较哈希值。 # 如果匹配成功,那么密码就是正确的。 # session 是一个 dict ,它用于储存横跨请求的值。 # 当验证 成功后,用户的 id 被储存于一个新的会话中。 # 会话数据被储存到一个 向浏览器发送的 cookie 中,在后继请求中,浏览器会返回它。 # Flask 会安全对数据进行 签名 以防数据被篡改。 if (user is None) or (not check_password_hash(user.password, password)): return jsonify(Const.errcode('1003')) if error is None: session.clear() session['user_id'] = user.uid session['user_name'] = user.username res = {"user_id": user.uid, "name": user.username} return jsonify(Const.errcode('0', res=res)) # flash(error) return abort(404)
def add_suite_case(): '''增加场景case''' if request.method == 'POST': if not g.user.uid: return jsonify(Const.errcode('1001')) req = request.json # 逐条入库,入表 _ = [ odb.add( SuiteCase( val['name'], len(odb.query_per_all(SuiteCase, 'sid', req['sid'])) + 1, # 新增用例,指定给用例的序顺号 '{}'.format(g.user.username), g.user.uid, val['desc'], val['method'], val['url'], repr(val['headers']), repr(val['body']), req['sid'])) for val in req['data'] ] return jsonify(Const.errcode('0')) return abort(404)
def register(): ''' 当用访问 /auth/register URL 时, register 视图会返回用于填写注册 内容的表单的 HTML 。 当用户提交表单时,视图会验证表单内容,然后要么再次 显示表单并显示一个出错信息, 要么创建新用户并显示登录页面。 ''' if request.method == 'POST': username = request.json['username'] password = request.json['password'] # 带有 ? 占位符 的 SQL 查询语句。占位符可以代替后面的元组参数中相应的值。 # 使用占位符的 好处是会自动帮你转义输入值,以抵御 SQL 注入攻击 。 # fetchone() 根据查询返回一个记录行。 如果查询没有结果,则返回 None 。 # 后面还用到 fetchall() ,它返回包括所有结果的列表。 # 使用 generate_password_hash() 生成安全的哈希值并储存 到数据库中。 # url_for() 根据登录视图的名称生成相应的 URL if not (username and password): return jsonify(Const.errcode('1003')) elif odb.query_per(User, 'username', username) is not None: return jsonify(Const.errcode('1004', res={"username": username})) odb.add(User(username, generate_password_hash(password))) return jsonify(Const.errcode('0')) return abort(404)
def create_suite(): ''' 创建测试集 Args: json s_name: 测试集名称 project_id: 项目ID ''' if request.method == 'POST': if not g.user.uid: return jsonify(Const.errcode('1001')) req_args = request.json test_suite = TestSuite(req_args['s_name'], g.user.username, req_args['project_id'], req_args['s_desc']) # 新增测试集,同步更新项目状态 odb.add(test_suite) odb.update(Project, 'p_id', req_args['project_id'], p_status=1) res = { "suite_id": test_suite.sid, "suite_name": req_args['s_name'], "description": req_args['s_desc'], "project_id": req_args['project_id'], "create_time": test_suite.create_time, "creator": test_suite.p_creator } return jsonify(Const.errcode('0', res=res)) return abort(404)
def delete_suite(): ''' 根据测试集ID,删除测试集 Args: JSON sid: 测试集ID ''' if request.method == 'POST': if not g.user.uid: return jsonify(Const.errcode('1001')) s_id_lst = request.json del_res = [] for sid in s_id_lst['sid']: dt = odb.delete(TestSuite, 'sid', int(sid)) del_res.append({ "sid": int(sid), "s_name": dt.s_name, "p_id": dt.p_id }) res = {'suite': del_res} return jsonify(Const.errcode('0', res=res)) return abort(404)
def create_project(): ''' 创建项目 ''' if request.method == 'POST': project_name = request.json['p_name'] p_desc = request.json['p_desc'] if not g.user.uid: return jsonify(Const.errcode('1001')) projects = Project(project_name, g.user.username, g.user.uid, p_desc) odb.add(projects) res = { "project_name": project_name, "p_id": projects.p_id, "p_desc": projects.p_desc, "p_creator": projects.p_creator, "p_status": projects.p_status, "p_createtime": projects.create_time } return jsonify(Const.errcode('0', res=res)) return abort(404)
def get_all_project_list(): ''' 获取所有项目 Args: page: url params请求参数, 不传默认为1 p_name: 项目名称查询 return: { "errcode": 0, "errmsg": "SUCCESS", "res": { "next_page": 3, "page": 2, "pages": 4, "per_page": 10, "prev_num": 1, "project": [ { "create_time": "Tue, 26 May 2020 17:30:32 GMT", "p_d": "xzdylyh", "p_desc": "这是项目描述,我最多支持150字符", "p_id": 11, "p_name": "我的第1个项目", "p_status": 0 }, { "create_time": "Tue, 26 May 2020 17:35:20 GMT", "p_d": "xzdylyh", "p_desc": "这是项目描述,我最多支持150字符", "p_id": 12, "p_name": "我的第1个项目", "p_status": 0 } ], "total": 39 } } ''' if request.method == 'POST': if not g.user.uid: return Const.errcode('1001') dt = odb.query_per_all(Project, 'p_creator', g.user.username) # response数据组装 res = { "project": [{ "create_time": item.create_time, "p_id": item.p_id, "p_name": item.p_name, "p_desc": item.p_desc, "p_status": item.p_status, "p_creator": item.p_creator } for item in dt] } return jsonify(Const.errcode('0', res=res)) return abort(404)
def upload_file(): ''' 根据用例ID,删除case Args: id [1,2,3] 测试用例id Method: POST Fmt: JSON Example: axios.post('/case/delete', params) Returns: { "errcode": 0, "errmsg": "success", "res": [ { "desc": "", "id": 1, "name": "/user/account" } ] } ''' if request.method == 'POST': # 验证授权 if not g.user.uid: return jsonify(Const.errcode('1004')) file = request.files['file'] res = {} # 文件是否在允许的类型内 if file and libs.allowed_file(file.filename): folder = os.path.join(setting.UPLOAD_FOLDER, str(g.user.uid) + g.user.username) libs.makedirs(folder) name = libs.md5_filename(file.filename) path = os.path.join(folder, name) if not libs.is_dirs_exist(path): file.save(path) res['filename'] = name return jsonify(Const.errcode('0', res=res)) else: return jsonify(Const.errcode('1006')) return jsonify(Const.errcode('1005')) return abort(404)
def update_suite_case(): '''更新场景case''' if request.method == 'POST': if not g.user.uid: return jsonify(Const.errcode('1001')) up = request.json # 1上移;2下移 if up['move'] == 1: try: # 根据scNo查询上一条用例scid号 squery = odb.query_per(SuiteCase, 'scNo', up['data']['scNo'] - 1) update1 = odb.update(SuiteCase, "scid", squery.scid, scNo=up['data']['scNo']) update = odb.update(SuiteCase, "scid", up['data']['scid'], scNo=squery.scNo - 1) except BaseException: odb.rollback() # 下移 if up['move'] == 2: try: # 根据scNo查询下一条用例scid号 squery = odb.query_per(SuiteCase, 'scNo', up['data']['scNo'] + 1) update1 = odb.update(SuiteCase, "scid", squery.scid, scNo=squery.scNo - 1) update = odb.update(SuiteCase, "scid", up['data']['scid'], scNo=up['data']['scNo'] + 1) except BaseException: odb.rollback() res = { "scid": update.scid, "scName": update.scName, "scNo": update.scNo, "scDesc": update.scDesc, "scUrl": update.scUrl } return jsonify(Const.errcode('0', res=res)) return abort(404)
def get_system_function(): ''' 获取系统函数 ''' if request.method == 'POST': if not g.user.uid: return jsonify(Const.errcode('1001')) res = SYS.function_get return jsonify(Const.errcode('0', res=res)) return abort(404)
def getSuiteCaseInfo(): ''' 根据场景ID, caseID,获取;场景用例内容 ''' if request.method == 'POST': if not g.user.uid: return jsonify(Const.errcode('1001')) req = request.json paginate = odb.query_per_paginate(SuiteCase, "sid", req['sid']) # 场景用例排序返回 sc = [adict.scNo for adict in paginate.items] sc.sort(reverse=False) paginate.items = [ adict for i in sc for adict in paginate.items if adict.scNo == i ] res = { "prev_num": paginate.prev_num, "per_page": paginate.per_page, "pages": paginate.pages, "total": paginate.total, "page": paginate.page, "next_page": paginate.next_num, "case": [{ "scid": sd.scid, "scno": sd.scNo, "scName": sd.scName, "scUrl": sd.scUrl, "scMethod": sd.scMethod, "create_time": sd.create_time, "scDesc": sd.scDesc, "sid": sd.sid, "scBody": eval(sd.scBody), "scHeaders": eval(sd.scHeaders), } for sd in paginate.items], "count": len(paginate.items) } return jsonify(Const.errcode('0', res=res)) return abort(404)
def create(): ''' 创建测试用例 Args: name 用例名称 method 请求方法 url 请求url地址 header 请求头部信息 body 请求体 desc 用例描述信息 Method: POST Fmt: JSON Example: axios.post('/case/create', params) Returns: { "name": "测试用例名称", "desc": "测试用例描述", "creator": "admin" } ''' if request.method == 'POST': if not g.user.uid: return jsonify(Const.errcode('1001')) para_json = request.json case_object = CaseInterface(para_json['name'], g.user.username, para_json['method'], para_json['url'], para_json['header'], para_json['body'], para_json['desc'], g.user.uid) odb.add(case_object) res = { "name": case_object.c_name, "desc": case_object.c_desc, "creator": g.user.username, "c_id": case_object.c_id } return jsonify(Const.errcode('0', res=res)) return abort(404)
def delete_suite_case(): '''删除场景case''' if request.method == 'POST': if not g.user.uid: return jsonify(Const.errcode('1001')) # 获取要删除的{'scid': [....]} scid_list = request.json['scid'] # 批量删除scid for scid in scid_list: odb.delete(SuiteCase, 'scid', scid) return jsonify(Const.errcode('0')) return abort(404)
def get_suite_by_sid(): ''' 根据sid获取测试集数据 ''' if request.method == 'POST': if not g.user.uid: return jsonify(Const.errcode('1001')) sid = request.json['sid'] dt = odb.query_per(TestSuite, 'sid', int(sid)) res = {'sid': dt.sid, 's_name': dt.s_name, 's_desc': dt.s_desc} return jsonify(Const.errcode('0', res=res)) return abort(404)
def delete_case(): ''' 根据用例ID,删除case Args: id [1,2,3] 测试用例id Method: POST Fmt: JSON Example: axios.post('/case/delete', params) Returns: { "errcode": 0, "errmsg": "success", "res": [ { "desc": "", "id": 1, "name": "/user/account" } ] } ''' if request.method == 'POST': # 验证授权 if not g.user.uid: return jsonify(Const.errcode('1004')) id_lst = request.json['id'] # 循环删除case res = [] for id in id_lst: dt = odb.delete(CaseInterface, 'c_id', id) res.append({"name": dt.c_name, "desc": dt.c_desc, "id": dt.c_id}) return jsonify(Const.errcode('0', res=res)) return abort(404)
def add(): ''' 增加全局变量 Args: name 变量名称 value 变量值 Example: http://127.0.0.1:5000/var/add Return: JSON { 'vid': 1, 'name': 'name', 'value': 'value', 'uid': 1 } ''' if request.method == 'POST': if not g.user.uid: return jsonify(Const.errcode('1001')) name = request.json['name'] value = request.json['value'] var_table = Variable(name, value, int(g.user.uid)) odb.add(var_table) res = { 'vid': var_table.vid, 'name': var_table.name, 'value': var_table.value, 'uid': var_table.uid } return jsonify(Const.errcode('0', res=res)) return abort(404)
def get_var(): ''' 根据用户uid,获取全局变量 Args: None Explame: http://127.0.0.1:5000/var/getVarByUid Return: { "errcode": 0, "errmsg": "success", "res": [ { "name": "name1", "uid": 1, "value": "value2", "vid": 1 } ] } ''' if request.method == 'POST': if not g.user.uid: return jsonify(Const.errcode('1001')) result = odb.query_per_all(Variable, 'uid', int(g.user.uid)) res = [{ 'vid': obj.vid, 'name': obj.name, 'value': obj.value, 'uid': obj.uid } for obj in result] return jsonify(Const.errcode('0', res=res)) return abort(404)
def edit_case(): ''' 编辑测试用例 ''' if request.method == 'POST': if not g.user.uid: return jsonify(Const.errcode('1001')) para_json = request.json result = odb.update(CaseInterface, 'c_id', para_json['caseId'], c_name=para_json['name'], c_method=para_json['method'], c_url=para_json['url'], c_headers=para_json['header'], c_body=para_json['body'], c_desc=para_json['desc']) return jsonify(Const.errcode('0')) return abort(404)
def delete_project(): ''' 删除项目,级联测试集也会删除 args: p_id: 项目ID ''' if request.method == 'POST': if not g.user.uid: return jsonify(Const.errcode('1101')) # 获取参数p_id p_id_lst = request.json del_res = [] for p_id in p_id_lst['p_id']: dt = odb.delete(Project, 'p_id', int(p_id)) del_res.append({"p_id": p_id, "p_name": dt.p_name}) res = {'project': del_res} return jsonify(Const.errcode('0', res=res)) return abort(404)
def update_project_info(): ''' 更新项目 method: post params: p_id, name ''' if request.method == 'POST': if not g.user.uid: return jsonify(Const.errcode('1001')) params = request.json # 按照项目ID,更新项目名称 dt = odb.update(Project, 'p_id', params['p_id'], p_name=params['p_name'], p_desc=params['p_desc']) res = {'project': {"p_id": dt.p_id, "new_p_name": dt.p_name}} return jsonify(Const.errcode('0', res=res)) return abort(404)
def get_all_suite_list(): ''' 获取所有测试集 Args: page: 当前页码,不传默认为1 return: { "errcode": 0, "errmsg": "success", "res": { "next_page": 2, "page": 1, "pages": 2, "per_page": 10, "prev_num": null, "project": [ { "create_time": "Tue, 02 Jun 2020 17:06:50 GMT", "p_creator": "xzdylyh", "p_id": 2, "s_name": "我的测试集", "sid": 1 }, { "create_time": "Tue, 02 Jun 2020 17:08:35 GMT", "p_creator": "xzdylyh", "p_id": 2, "s_name": "我的测试集", "sid": 2 } ], "total": 11 } } ''' if request.method == 'POST': if not g.user.uid: return jsonify(Const.errcode('1001')) page = request.args.get('page', 1) # 分页展示 paginate = odb.query_all_paginate(TestSuite, page=int(page)) res = { "prev_num": paginate.prev_num, "per_page": paginate.per_page, "pages": paginate.pages, "total": paginate.total, "page": paginate.page, "next_page": paginate.next_num, "project": [{ "create_time": item.create_time, "sid": item.sid, "s_name": item.s_name, "p_id": item.p_id, "p_creator": item.p_creator } for item in paginate.items] } return jsonify(Const.errcode('0', res=res)) return abort(404)
def get_project_list(): ''' 获取所有项目信息,带分页 Args: page: url params请求参数, 不传默认为1 p_name: 项目名称查询 return: { "errcode": 0, "errmsg": "SUCCESS", "res": { "next_page": 3, "page": 2, "pages": 4, "per_page": 10, "prev_num": 1, "project": [ { "create_time": "Tue, 26 May 2020 17:30:32 GMT", "p_d": "xzdylyh", "p_desc": "这是项目描述,我最多支持150字符", "p_id": 11, "p_name": "我的第1个项目", "p_status": 0 }, { "create_time": "Tue, 26 May 2020 17:35:20 GMT", "p_d": "xzdylyh", "p_desc": "这是项目描述,我最多支持150字符", "p_id": 12, "p_name": "我的第1个项目", "p_status": 0 } ], "total": 39 } } ''' if request.method == 'POST': # 是否登录授权 if not g.user.uid: return jsonify(Const.errcode('1001')) # 请求url参数page page = request.json.get('page', 1) p_name = request.json.get('p_name', '') p_id = request.json.get('p_id', '') # 可按pid与name查询,pid优先 if p_id: paginate = odb.query_per_paginate(Project, 'p_id', p_id, page=int(page)) elif p_name: paginate = odb.query_per_paginate(Project, 'p_name', p_name, page=int(page)) else: paginate = odb.query_all_paginate(Project, page=int(page)) # response数据组装 res = { "prev_num": paginate.prev_num, "per_page": paginate.per_page, "pages": paginate.pages, "total": paginate.total, "page": paginate.page, "next_page": paginate.next_num, "project": [{ "create_time": item.create_time, "p_id": item.p_id, "p_name": item.p_name, "p_desc": item.p_desc, "p_status": item.p_status, "p_creator": item.p_creator } for item in paginate.items] } return jsonify(Const.errcode('0', res=res)) return abort(404)
def debug(): ''' 执行单个测试用例 Args: name 用例名称 method 请求方法 url 请求url地址 header 请求头部信息 body 请求体 desc 用例描述信息 Method: POST Fmt: JSON Example: axios.post('/run/debug', params) Returns: { "name": "测试用例名称", "desc": "测试用例描述", "creator": "admin" } ''' if request.method == 'POST': if not g.user.uid: return jsonify(Const.errcode('1001')) req = request.json ''' Var: data_dict: dict类型data数据组合 files_list: form-data类型时files文件 how: form-data; x-xxx-form-urlencoded; raw类型 url: 请求url地址 headers:请求头信息 ''' body = req['body']['body'] data_dict = body['data'] files_list = body['files'] how = req['body']['how'] url = req['url'] headers = req['header'] method = req['method'] outParam_list = req['outParam'] data_dict, files, headers = client.data_to_parse( data_dict, files_list, how, headers) response = getattr(client, method)(url, data=data_dict, headers=headers, files=files) # 出参内容 ret_out_param = EXTS.get_out_parameters(outParam_list, response) content_type = response.headers.get("Content-Type", '') # 根据响应头,如果content-type类型是json返回json格式,否则返回text格式 res_data = response.json() if 'json' in content_type else response.text # 调试或保存 EXTS.debug_or_save(req, ret_out_param, response, odb) res_dt = { "headers": dict(response.headers), "url": response.url, "data": res_data, "cookies": libs.dict_from_cookiejar(response.cookies), "ok": response.ok, "encoding": response.encoding, "reason": response.reason, "status_code": response.status_code, "elapsed": int(response.elapsed.total_seconds() * 1000), "out_param_list": ret_out_param } return jsonify(Const.errcode('0', res=res_dt)) return abort(404)
def logout(): session.clear() return jsonify(Const.errcode('0'))
def wrapped_view(**kwargs): if g.user is None: return jsonify(Const.errcode('1001')) return view(**kwargs)
def get_all_suite_by_pid(): ''' 根据项目id获取,该项目下的所有测试集 Args: params参数 p_id: 项目ID Return: { "errcode": 0, "errmsg": "success", "res": { "count": 10, "next_page": 2, "page": 1, "pages": 2, "per_page": 10, "prev_num": null, "suite": [ { "create_time": "Tue, 02 Jun 2020 17:06:50 GMT", "creator": "xzdylyh", "p_id": 2, "s_name": "我的测试集", "sid": 1 }, { "create_time": "Tue, 02 Jun 2020 17:08:35 GMT", "creator": "xzdylyh", "p_id": 2, "s_name": "我的测试集", "sid": 2 } ], "total": 11 } } ''' if request.method == 'POST': if not g.user.uid: return jsonify(Const.errcode('1001')) pid = request.json['p_id'] dt_lst = odb.query_per_all(TestSuite, 'p_id', int(pid)) res = { "suite": [{ "sid": sd.sid, "s_name": sd.s_name, "create_time": sd.create_time, "creator": sd.p_creator, "p_id": sd.p_id } for sd in dt_lst], "count": len(dt_lst) } return jsonify(Const.errcode('0', res=res)) return abort(404)
def get_suite_by_pid(): ''' 根据项目id获取,该项目下的所有测试集 Args: params参数 p_id: 项目ID page: 页码,不传默认为1 Return: { "errcode": 0, "errmsg": "success", "res": { "count": 10, "next_page": 2, "page": 1, "pages": 2, "per_page": 10, "prev_num": null, "suite": [ { "create_time": "Tue, 02 Jun 2020 17:06:50 GMT", "creator": "xzdylyh", "p_id": 2, "s_name": "我的测试集", "sid": 1 }, { "create_time": "Tue, 02 Jun 2020 17:08:35 GMT", "creator": "xzdylyh", "p_id": 2, "s_name": "我的测试集", "sid": 2 } ], "total": 11 } } ''' if request.method == 'POST': if not g.user.uid: return jsonify(Const.errcode('1001')) pid = request.args.get('p_id', False) if not pid: return jsonify(Const.errcode('1002')) else: # 分页 paginate = odb.query_per_paginate( TestSuite, 'p_id', int(pid), page=int(request.args.get('page', 1)), ) res = { "prev_num": paginate.prev_num, "per_page": paginate.per_page, "pages": paginate.pages, "total": paginate.total, "page": paginate.page, "next_page": paginate.next_num, "suite": [{ "sid": sd.sid, "s_name": sd.s_name, "create_time": sd.create_time, "creator": sd.p_creator, "p_id": sd.p_id } for sd in paginate.items], "count": len(paginate.items) } return jsonify(Const.errcode('0', res=res)) return abort(404)
def get_case_list(): ''' 获取case信息 Args: page 当前页 name 按名称获取用例,可选 Method: POST Fmt: JSON Example: axios.post('/case/getcaselist', params) Returns: { "errcode": 0, "errmsg": "success", "res": { "case": [ { "body": "{}", "createtime": "Thu, 11 Jun 2020 14:05:03 GMT", "creator": "admin", "desc": "", "headers": "{}", "id": 1, "method": "post", "name": "/user/account", "url": "http://api.xxxx.acewill.net/user/account" }, { "body": "{}", "createtime": "Thu, 11 Jun 2020 14:19:20 GMT", "creator": "admin", "desc": "'这是一个测试用例描述'", "headers": "{}", "id": 2, "method": "post", "name": "/user/account", "url": "http://api.xxxx.acewill.net/user/account" } ], "next_num": null, "page": 1, "pages": 1, "per_page": 10, "prev_num": null, "total": 2 } } ''' if request.method == "POST": if not g.user.uid: return jsonify(Const.errcode('1001')) page = request.json.get('page', 1) name = request.json.get('name', '') task_filter = {CaseInterface.uid == int(g.user.uid)} if name == '' else \ {and_(CaseInterface.uid == int(g.user.uid), CaseInterface.c_name == name)} paginate = odb.query_per_paginates(CaseInterface, page=int(page), task_filter=task_filter) res = { "page": paginate.page, "pages": paginate.pages, "next_num": paginate.next_num, "per_page": paginate.per_page, "prev_num": paginate.prev_num, "total": paginate.total, "case": [{ "url": val.c_url, "name": val.c_name, "desc": val.c_desc, "method": val.c_method, "cid": val.c_id, "headers": val.c_headers, "body": eval(val.c_body), "creator": val.p_creator, "createtime": val.create_time } for val in paginate.items] } return jsonify(Const.errcode('0', res=res)) return abort(404)