介面基礎知識: 簡單說下介面測試,現在常用的2種介面就是http api和rpc協議的介面,今天主要說:http api介面是走http協議通過路徑來區分調用的方法,請求報文格式都是key-value形式,返回報文一般是json串; 介面協議:http、webservice、rpc等。 請求方式:g ...
介面基礎知識:
簡單說下介面測試,現在常用的2種介面就是http api和rpc協議的介面,今天主要說:http api介面是走http協議通過路徑來區分調用的方法,請求報文格式都是key-value形式,返回報文一般是json串;
介面協議:http、webservice、rpc等。
請求方式:get、post方式
請求參數格式:
a. get請求都是通過url?param=xxx¶m1=xxx
b. post請求的請求參數常用類型有:application/json、application/x-www-form-urlencoded、multipart/form-data、text/html等。
還需要知道介面的url、參數類型、返回結果的數據格式、瞭解介面是否有header、cookie等信息。
介面的實現:
請求方式-get,介面的寫法:
1 import flask 2 from flask import request 3 from flask import jsonify 4 import tools 5 import OP_db 6 import settings 7 ''' 8 flask: web框架,可以通過flask提供的裝飾器@server.route()將普通函數轉換為服務 9 登錄介面,需要傳url、username、passwd 10 ''' 11 #創建一個服務,把當前這個python文件當做一個服務 12 server = flask.Flask(__name__)
13 #瀏覽器訪問介面時,返回的字元串顯示為utf-8的編碼,不是中文,可以使用以下代碼解決 13 server.config['JSON_AS_ASCII'] = False 14 15 # @server.route()可以將普通函數轉變為服務 登錄介面的路徑、請求方式 16 @server.route('/login', methods=['get']) 17 def login(): 18 # 獲取通過url請求傳參的數據 19 username = request.values.get('name') 20 # 獲取url請求傳的密碼,明文 21 pwd = request.values.get('pwd') 22 # 判斷用戶名、密碼都不為空,如果不傳用戶名、密碼則username和pwd為None 23 if username and pwd: 24 # 獲取加密後的密碼 25 password = tools.md5_pwd(pwd) 26 #執行sql,如果查詢的username和password不為空,說明資料庫存在admin的賬號 27 sql = 'select name,password from test where name= "%s" and password= "%s";' %(username, password) 28 # 從數據查詢結果後,res返回是元組 29 res = OP_db.getconn( 30 host=settings.mysql_info['host'], 31 user=settings.mysql_info['user'], 32 passwd=settings.mysql_info['pwd'], 33 db=settings.mysql_info['db'], 34 port=settings.mysql_info['port'], 35 sql=sql 36 ) 37 if res: #res的結果不為空,說明找到了username=admin的用戶,且password為加密前的123456 38 resu = {'code': 200, 'message': '登錄成功'} 39 return jsonify(resu) #將字典轉換為json串, json是字元串 40 else: 41 resu = {'code': -1, 'message': '賬號/密碼錯誤'} 42 return jsonify(resu) 43 else: 44 res = {'code': 999, 'message': '必填參數未填寫'} 45 return jsonify(res) 46 47 if __name__ == '__main__': 48 server.run(debug=True, port=8888, host=0.0.0.0) #指定埠、host,0.0.0.0代表不管幾個網卡,任何ip都可以訪問
md5加密、資料庫mysql的操作詳見我的其他博客~~~~~
get訪問介面:
項目啟動後,介面的地址是:http://127.0.0.1:5000/,預設埠是5000。
打開瀏覽器,輸入urlhttp://127.0.0.1:5000/xxx?name=xxx&pwd=123456,後面跟上介面的地址login,參數跟url直接使用?相連,每個請求參數直接使用&相連。請求成功,則返回{'code': 200, 'message': '登錄成功'}。
請求方式-post,介面的寫法:
1 import flask 2 from flask import jsonify 3 from flask import request 4 from conf import opMysql 5 from conf import md5_create 6 ''' 7 註冊介面: 8 post請求,請求參數入參類型json 9 { 10 "username":"aaa", 11 "pwd":"123456", 12 "c_pwd":"123456" 13 } 14 ''' 15 server = flask.Flask(__name__) 16 @server.route('/register', methods=['GET', 'POST']) 17 def registerPost(): 18 #判斷介面的請求方式是GET還是POST 19 if request.method == 'POST': 20 # 獲取請求參數是json格式,返回結果是字典 21 params = request.json 22 username = params.get('username') 23 pwd = params.get('pwd') 24 confirmpwd = params.get('confirmpwd') 25 if username and pwd and confirmpwd: # 判斷輸入的用戶名、密碼、確認密碼都不為空 26 select_sql = 'select username from lhldemo where username = "%s" ;'%username 27 # 查詢註冊的用戶是否存在資料庫,如果存在,則username不為空,否則username為空 28 res_mysql = opMysql.op_select(select_sql) 29 if res_mysql: 30 return jsonify({"code": 999, "mesg": "用戶已註冊"}) 31 else: 32 if pwd == confirmpwd: # 判斷pwd和confirmpwd一致 33 new_pwd = md5_create.md5_test(pwd) # 加密後的密碼 34 insert_sql = 'insert into lhldemo(username,password) values("%s", "%s") ;' % (username, new_pwd) 35 opMysql.op_insert(insert_sql) 36 return jsonify({"code": 200, "msg": "註冊成功"}) 37 else: 38 return jsonify({"code":998, "msg":"密碼不一樣"}) 39 else: 40 return jsonify({"code": 504, "msg": "必填項不能為空"}) 41 else: 42 return jsonify({"code": 201, "msg": "請求方式不正確"}) 43 44 if __name__ == '__main__': 45 #port可以指定埠,預設埠是5000 46 #host寫成0.0.0.0的話,其他人可以訪問,代表監聽多塊網卡上面,預設是127.0.0.1 47 server.run(debug=True, port=8899, host='0.0.0.0')
post訪問介面:
項目啟動後,介面的地址是:http://127.0.0.1:5000/,預設埠是5000。
打開瀏覽器,輸入urlhttp://127.0.0.1:5000/xxx,後面跟上介面的地址register,參數使用postman或jmeter進行請求,參數類型是json。請求成功,則返回{'code': 200, 'message': '登錄成功'}。
請求方式-get、post都可以訪問,寫法如下:
1 import flask 2 from flask import jsonify 3 from flask import request 4 from conf import opMysql 5 from conf import md5_create 6 ''' 7 註冊介面: 8 post請求,請求參數入參類型json 9 { 10 "username":"aaa", 11 "pwd":"123456", 12 "c_pwd":"123456" 13 } 14 ''' 15 server = flask.Flask(__name__) 16 @server.route('/register', methods=['get', 'post']) 17 def registerPost(): 18 #post請求獲取請求的參數,返回結果類型是str 19 username = request.values.get('username') 20 pwd = request.values.get('pwd') 21 confirmpwd = request.values.get('confirmpwd') 22 if username and pwd and confirmpwd: # 判斷輸入的用戶名、密碼、確認密碼都不為空 23 select_sql = 'select username from lhldemo where username = "%s" ;'%username 24 # 查詢註冊的用戶是否存在資料庫,如果存在,則username不為空,否則username為空 25 res_mysql = opMysql.op_select(select_sql) 26 if res_mysql: 27 return jsonify({"code": 999, "mesg": "用戶已註冊"}) 28 else: 29 if pwd == confirmpwd: # 判斷pwd和confirmpwd一致 30 new_pwd = md5_create.md5_test(pwd) # 加密後的密碼 31 insert_sql = 'insert into lhldemo(username,password) values("%s", "%s") ;' % (username, new_pwd) 32 opMysql.op_insert(insert_sql) 33 return jsonify({"code": 200, "msg": "註冊成功"}) 34 else: 35 return jsonify({"code": 998, "msg": "密碼不一樣"}) 36 else: 37 return jsonify({"code": 504, "msg": "必填項不能為空"}) 38 39 40 if __name__ == '__main__': 41 #port可以指定埠,預設埠是5000 42 #host預設是127.0.0.1,寫成0.0.0.0的話,其他人可以訪問,代表監聽多塊網卡上面, 43 server.run(debug=True, port=8899, host='0.0.0.0')
可以通過以下2種方式進行post請求,一種如下:
通過url拼接參數:
第二種訪問方式:通過key-value方式進行訪問:
redis相關操作,添加hash類型的值到redis內,介面實現如下:
1 import flask 2 from flask import jsonify 3 from conf import opRedis 4 from flask import request 5 ''' 6 redis添加數據,存入數據的類型是hash類型,格式如下: 7 post請求,請求參數入參類型json 8 {name:{"key":"value"}} 9 {"username":"url"} 10 ''' 11 server = flask.Flask(__name__) 12 @server.route('/set_sties', methods =['post']) 13 def set_sties(): 14 # 獲取url請求參數,返回結果是字典{"username":"byz","url":"http://www.baidu.com"} 15 res_dic = request.json 16 if res_dic.get('username') and res_dic.get('url'): 17 username = res_dic.get('username') 18 url = res_dic.get('url') 19 #調用redis的hset方法,將username、url存入redis 20 opRedis.get_hashall('sites', username, url) 21 return jsonify({"code":20}) 22 else: 23 return jsonify({"code": 204, "msg": "必填項不能為空"}) 24 25 if __name__ == '__main__': 26 #port可以指定埠,預設埠是5000 27 #host預設是127.0.0.1,寫成0.0.0.0的話,其他人可以訪問,代表監聽多塊網卡上面, 28 server.run(debug=True, port=8899, host='0.0.0.0')
hash類型結構如下:
{name:{key,value}},介面訪問成功後,redis內數據存儲結構如下:
redis添加完數據後,讀取redis內的數據,介面實現如下:
1 import flask 2 from flask import jsonify 3 from conf import opRedis 4 from flask import request 5 ''' 6 讀取redis內的數據,redis數據存儲類型是hash類型,格式如下 7 {name:{"key":"value"}} 8 思路: 1.通過redis的hgetall(name)方法讀取redis所有數據,返回結果類型是字典 9 2. 迴圈字典內容,將元素類型轉換為str,並將結果存放到字典內 10 ''' 11 server = flask.Flask(__name__) 12 @server.route('/get_sties', methods =['get', 'post']) 13 def get_sties(): 14 #獲取redis內所有的數據信息,返回結果類型是字典,裡面元素是bytes類型,name=sites 15 dic = opRedis.get_hashall('sites') 16 redisList = [] 17 for key, value in dic.items(): 18 redis_dic = {} 19 #將字典內元素的類型由bytes轉換為str 20 k = key.decode() 21 v = value.decode() 22 #字典redis_dic內結構{"username:k, "url":v} 23 redis_dic['username'] = k 24 redis_dic['url'] = v 25 redisList.append(redis_dic) 26 return jsonify({"code": 200, "msg": redisList}) 27 28 if __name__ == '__main__': 29 #port可以指定埠,預設埠是5000 30 #host預設是127.0.0.1,寫成0.0.0.0的話,其他人可以訪問,代表監聽多塊網卡上面, 31 server.run(debug=True, port=8899, host='0.0.0.0')
通過postman方法介面,返回數據如下:
查詢用戶,需要傳token值,實現方法如下:
登錄介面:
1 import flask 2 from flask import jsonify 3 from conf import opRedis 4 from conf import opMysql 5 from conf import md5_create 6 from flask import request 7 import time 8 ''' 9 登錄介面,需要傳用戶名、密碼,通過查詢資料庫判斷用戶是否登錄成功,若登錄成功則將用戶名和token存入redis內 10 ''' 11 server = flask.Flask(__name__) 12 @server.route('/login', methods=['get','post']) 13 def set_cookies(): 14 name = request.values.get('username') 15 pwd = request.values.get('pwd') 16 if name and pwd: 17 #加密後的密碼 18 new_pwd = md5_create.md5_test(pwd) 19 sql = 'select username,password from lhldemo where username="%s" and password="%s" ; ' % (name, new_pwd) 20 res_sql = opMysql.op_select(sql) 21 if res_sql: 22 token = name + time.strftime('%Y%m%d%H%M%S') 23 new_token = md5_create.md5_test(token) 24 #用戶登錄成功後,將name和token存入redis,存入數據類型是hash類型 25 opRedis.get_hashall('user', name, new_token) 26 return jsonify({"code": 200}) 27 else: 28 return jsonify({"code": 204}) 29 else: 30 return jsonify({"code": 304})
查詢用戶,需要傳用戶名和token值,實現方法如下:
1 import flask 2 from flask import jsonify 3 from conf import opRedis 4 from conf import opMysql 5 from conf import md5_create 6 from flask import request 7 import time 8 ''' 9 登錄介面,需要傳用戶名、密碼,通過查詢資料庫判斷用戶是否登錄成功,若登錄成功則將用戶名和token存入redis內 10 ''' 11 server = flask.Flask(__name__) 12 @server.route('/search_user', methods=['get','post']) 13 def set_cookies(): 14 name = request.values.get('username') 15 token = request.values.get('token') 16 17 if name and token: 18 #查看資料庫,看查詢的用戶是否存在,若存在則返回用戶id 19 sql = 'select id from lhldemo where username="%s" ; ' % (name) 20 res_sql = opMysql.op_select(sql) 21 if res_sql: 22 #從redis中獲取user下的用戶名對應的token值 23 res_token = opRedis.getRedis('user:'+name)26 if res_token == token: 27 return jsonify({"msg": "用戶id", "id": res_sql}) 28 else: 29 return jsonify({"msg": "token錯誤"}) 30 else: 31 return jsonify({"code": "用戶不存在"}) 32 else: 33 return jsonify({"code": "必填項不能為空"}) 34 35 if __name__ == '__main__': 36 #port可以指定埠,預設埠是5000 37 #host預設是127.0.0.1,寫成0.0.0.0的話,其他人可以訪問,代表監聽多塊網卡上面, 38 server.run(debug=True, port=8899, host='0.0.0.0')
文件的上傳、下載介面實現:
上傳介面:
1 import flask 2 from flask import request 3 from flask import jsonify 4 import time 5 6 server = flask.Flask(__name__) 7 @server.route('/upload', methods=['post']) 8 def upload(): 9 #獲取請求參數,傳參類型是file,返回結果類型是一個對象:<class 'werkzeug.datastructures.FileStorage'> <FileStorage: '新建文本文檔.txt' ('text/plain')> 10 file = request.files.get('file_name', None) 11 #判斷file是否為空,若為空則沒有上傳文件 12 if file: 13 cur_time = time.strftime('%Y%m%d%H%M%S') #獲取當前時間 14 upload_name = file.filename #獲取上傳文件的名稱 15 new_file_name = cur_time+upload_name #給文件重命名,防止有重覆文件覆蓋 16 # 保存文件,指定文件上傳的路徑 17 file.save('E:/python_workspace/base-code/day8/test_requests/'+new_file_name) 18 return jsonify({"code": "ok"}) 19 else: 20 return jsonify({"code": "請上傳文件"}) 21 22 server.run(debug=True)
通過postman訪問介面:
下載介面:
1 @server.route('/get_file', methods = ['get']) 2 def get_file(): 3 #獲取請求參數,返回結果類型是str 4 filename = request.values.get('filename', None) 5 if filename: 6 #判斷請求的參數,也就是要下載的文件,在當前目錄下是否是一個文件,而不是文件夾 7 if os.path.isfile('E:/python_workspace/base-code/'+filename): 8 #返回要下載的文件 9 return send_from_directory('.', filename, as_attachment=True) 10 else: 11 return jsonify({"msg": "文件不存在!"}) 12 else: 13 return jsonify({'msg': '文件名不能為空'}) 14 15 if __name__ == '__main__': 16 server.run(debug=True)
以上就是工作中常用的一些介面場景,測試支付相關介面、或者第三方介面時,可以自己mock介面返回假數據操作~~~~