【作者: 艾裡艾蘭 】Python+requests+unittest+excel實現介面自動化測試框架
阿新 • • 發佈:2018-12-14
python自動化語言基礎
介面測試知識基礎
一、框架結構:
工程目錄
二、Case檔案設計
三、基礎包 base
3.1 封裝get/post請求(runmethon.py)
1 import requests 2 import json 3 class RunMethod: 4 def post_main(self,url,data,header=None): 5 res = None 6 if header !=None: 7 res = requests.post(url=url,data=data,headers=header) 8 else: 9 res = requests.post(url=url,data=data) 10 return res.json() 11 12 def get_main(self,url,data=None,header=None): 13 res = None 14 if header !=None: 15 res = requests.get(url=url,data=data,headers=header,verify=False) 16 else: 17 res = requests.get(url=url,data=data,verify=False) 18 return res.json() 19 20 def run_main(self,method,url,data=None,header=None): 21 res = None 22 if method == 'Post': 23 res = self.post_main(url,data,header) 24 else: 25 res = self.get_main(url,data,header) 26 return json.dumps(res,ensure_ascii=False,sort_keys=True,indent=2)
3.2 封裝mock(mock.py)
1 from mock import mock
2 #模擬mock 封裝
3 def mock_test(mock_method,request_data,url,method,response_data):
4 mock_method = mock.Mock(return_value=response_data)
5 res = mock_method(url,method,request_data)
6 return res
四、資料操作包 operation_data
4.1 獲取excel單元格中的內容(get_data.py)
1 #coding:utf-8 2 from tool.operation_excel import OperationExcel 3 import data_config 4 from tool.operation_json import OperetionJson 5 from tool.connect_db import OperationMysql 6 class GetData: 7 def __init__(self): 8 self.opera_excel = OperationExcel() 9 10 #去獲取excel行數,就是case的個數 11 def get_case_lines(self): 12 return self.opera_excel.get_lines() 13 14 #獲取是否執行 15 def get_is_run(self,row): 16 flag = None 17 col = int(data_config.get_run()) 18 run_model = self.opera_excel.get_cell_value(row,col) 19 if run_model == 'yes': 20 flag = True 21 else: 22 flag = False 23 return flag 24 25 #是否攜帶header 26 def is_header(self,row): 27 col = int(data_config.get_header()) 28 header = self.opera_excel.get_cell_value(row,col) 29 if header != '': 30 return header 31 else: 32 return None 33 34 #獲取請求方式 35 def get_request_method(self,row): 36 col = int(data_config.get_run_way()) 37 request_method = self.opera_excel.get_cell_value(row,col) 38 return request_method 39 40 #獲取url 41 def get_request_url(self,row): 42 col = int(data_config.get_url()) 43 url = self.opera_excel.get_cell_value(row,col) 44 return url 45 46 #獲取請求資料 47 def get_request_data(self,row): 48 col = int(data_config.get_data()) 49 data = self.opera_excel.get_cell_value(row,col) 50 if data == '': 51 return None 52 return data 53 54 #通過獲取關鍵字拿到data資料 55 def get_data_for_json(self,row): 56 opera_json = OperetionJson() 57 request_data = opera_json.get_data(self.get_request_data(row)) 58 return request_data 59 60 #獲取預期結果 61 def get_expcet_data(self,row): 62 col = int(data_config.get_expect()) 63 expect = self.opera_excel.get_cell_value(row,col) 64 if expect == '': 65 return None 66 return expect 67 68 #通過sql獲取預期結果 69 def get_expcet_data_for_mysql(self,row): 70 op_mysql = OperationMysql() 71 sql = self.get_expcet_data(row) 72 res = op_mysql.search_one(sql) 73 return res.decode('unicode-escape') 74 75 def write_result(self,row,value): 76 col = int(data_config.get_result()) 77 self.opera_excel.write_value(row,col,value) 78 79 #獲取依賴資料的key 80 def get_depend_key(self,row): 81 col = int(data_config.get_data_depend()) 82 depent_key = self.opera_excel.get_cell_value(row,col) 83 if depent_key == "": 84 return None 85 else: 86 return depent_key 87 88 #判斷是否有case依賴 89 def is_depend(self,row): 90 col = int(data_config.get_case_depend()) 91 depend_case_id = self.opera_excel.get_cell_value(row,col) 92 if depend_case_id == "": 93 return None 94 else: 95 return depend_case_id 96 97 #獲取資料依賴欄位 98 def get_depend_field(self,row): 99 col = int(data_config.get_field_depend()) 100 data = self.opera_excel.get_cell_value(row,col) 101 if data == "": 102 return None 103 else: 104 return data
4.2 獲取excel中每個列(data_config.py)
1 #coding:utf-8
2 class global_var:
3 #case_id
4 Id = '0'
5 request_name = '1'
6 url = '2'
7 run = '3'
8 request_way = '4'
9 header = '5'
10 case_depend = '6'
11 data_depend = '7'
12 field_depend = '8'
13 data = '9'
14 expect = '10'
15 result = '11'
16 #獲取caseid
17 def get_id():
18 return global_var.Id
19
20 #獲取url
21 def get_url():
22 return global_var.url
23
24 def get_run():
25 return global_var.run
26
27 def get_run_way():
28 return global_var.request_way
29
30 def get_header():
31 return global_var.header
32
33 def get_case_depend():
34 return global_var.case_depend
35
36 def get_data_depend():
37 return global_var.data_depend
38
39 def get_field_depend():
40 return global_var.field_depend
41
42 def get_data():
43 return global_var.data
44
45 def get_expect():
46 return global_var.expect
47
48 def get_result():
49 return global_var.result
50
51 def get_header_value():
52 return global_var.header
4.3 解決資料依賴(dependent.py )
1 #coding:utf-8
2 import sys
3 import json
4 sys.path.append('C:/Users/lxz/Desktop/InterFace_JIA')
5 from tool.operation_excel import OperationExcel
6 from base.runmethod import RunMethod
7 from operation_data.get_data import GetData
8 from jsonpath_rw import jsonpath,parse
9 class DependdentData:
10 def __init__(self,case_id):
11 self.case_id = case_id
12 self.opera_excel = OperationExcel()
13 self.data = GetData()
14
15 #通過case_id去獲取該case_id的整行資料
16 def get_case_line_data(self):
17 rows_data = self.opera_excel.get_rows_data(self.case_id)
18 return rows_data
19
20 #執行依賴測試,獲取結果
21 def run_dependent(self):
22 run_method = RunMethod()
23 row_num = self.opera_excel.get_row_num(self.case_id)
24 request_data = self.data.get_data_for_json(row_num)
25 #header = self.data.is_header(row_num)
26 method = self.data.get_request_method(row_num)
27 url = self.data.get_request_url(row_num)
28 res = run_method.run_main(method,url,request_data)
29 return json.loads(res)
30
31 #根據依賴的key去獲取執行依賴測試case的響應,然後返回
32 def get_data_for_key(self,row):
33 depend_data = self.data.get_depend_key(row)
34 response_data = self.run_dependent()
35 json_exe = parse(depend_data)
36 madle = json_exe.find(response_data)
37 return [math.value for math in madle][0]
38
39 if __name__ == '__main__':
40 order = {
41 "data": {
42 "_input_charset": "utf-8",
43 "body": "京東訂單-1710141907182334",
44 "it_b_pay": "1d",
45 "notify_url": "http://order.imooc.com/pay/notifyalipay",
46 "out_trade_no": "1710141907182334",
47 "partner": "2088002966755334",
48 "payment_type": "1",
49 "seller_id": "[email protected]",
50 "service": "mobile.securitypay.pay",
51 "sign": "kZBV53KuiUf5HIrVLBCcBpWDg%2FnzO%2BtyEnBqgVYwwBtDU66Xk8VQUTbVOqDjrNymCupkVhlI%2BkFZq1jOr8C554KsZ7Gk7orC9dDbQl
pr%2BaMmdjO30JBgjqjj4mmM%2Flphy9Xwr0Xrv46uSkDKdlQqLDdGAOP7YwOM2dSLyUQX%2Bo4%3D",
52 "sign_type": "RSA",
53 "string": "_input_charset=utf-8&body=京東訂單-1710141907182334&it_b_pay=1d¬ify_url=http://order.imooc.com/pay/
notifyalipay&out_trade_no=1710141907182334&partner=2088002966755334&payment_type=1&[email protected]
tcl.com&service=mobile.securitypay.pay&subject=京東訂單-1710141907182334&total_fee=299&sign=kZBV53KuiUf5H
IrVLBCcBpWDg%2FnzO%2BtyEnBqgVYwwBtDU66Xk8VQUTbVOqDjrNymCupkVhlI%2BkFZq1jOr8C554KsZ7Gk7orC9dDbQlpr%2BaMmdjO30
JBgjqjj4mmM%2Flphy9Xwr0Xrv46uSkDKdlQqLDdGAOP7YwOM2dSLyUQX%2Bo4%3D&sign_type=RSA",
54 "subject": "京東訂單-1710141907182334",
55 "total_fee": 299
56 },
57 "errorCode": 1000,
58 "errorDesc": "成功",
59 "status": 1,
60 "timestamp": 1507979239100
61 }
62 res = "data.out_trade_no"
63 json_exe = parse(res)
64 madle = json_exe.find(order)
65 print [math.value for math in madle][0]
五、工具類包 tool
5.1 操作excel (operation_excel.py)
1 #coding:utf-8
2 import xlrd
3 from xlutils.copy import copy
4 class OperationExcel:
5 def __init__(self,file_name=None,sheet_id=None):
6 if file_name:
7 self.file_name = file_name
8 self.sheet_id = sheet_id
9 else:
10 self.file_name = '../dataconfig/case1.xls'
11 self.sheet_id = 0
12 self.data = self.get_data()
13
14 #獲取sheets的內容
15 def get_data(self):
16 data = xlrd.open_workbook(self.file_name)
17 tables = data.sheets()[self.sheet_id]
18 return tables
19
20 #獲取單元格的行數
21 def get_lines(self):
22 tables = self.data
23 return tables.nrows
24
25 #獲取某一個單元格的內容
26 def get_cell_value(self,row,col):
27 return self.data.cell_value(row,col)
28
29 #寫入資料
30 def write_value(self,row,col,value):
31 '''
32 寫入excel資料
33 row,col,value
34 '''
35 read_data = xlrd.open_workbook(self.file_name)
36 write_data = copy(read_data)
37 sheet_data = write_data.get_sheet(0)
38 sheet_data.write(row,col,value)
39 write_data.save(self.file_name)
40
41 #根據對應的caseid 找到對應行的內容
42 def get_rows_data(self,case_id):
43 row_num = self.get_row_num(case_id)
44 rows_data = self.get_row_values(row_num)
45 return rows_data
46
47 #根據對應的caseid找到對應的行號
48 def get_row_num(self,case_id):
49 num = 0
50 clols_data = self.get_cols_data()
51 for col_data in clols_data:
52 if case_id in col_data:
53 return num
54 num = num+1
55
56
57 #根據行號,找到該行的內容
58 def get_row_values(self,row):
59 tables = self.data
60 row_data = tables.row_values(row)
61 return row_data
62
63 #獲取某一列的內容
64 def get_cols_data(self,col_id=None):
65 if col_id != None:
66 cols = self.data.col_values(col_id)
67 else:
68 cols = self.data.col_values(0)
69 return cols
70
71
72 if __name__ == '__main__':
73 opers = OperationExcel()
74 print opers.get_cell_value(1,2)
5.2判斷字串包含,判斷字典是否相等(common_util.py)
1 #coding:utf-8
2 import json
3 class CommonUtil:
4 def is_contain(self,str_one,str_two):
5 '''
6 判斷一個字串是否再另外一個字串中
7 str_one:查詢的字串
8 str_two:被查詢的字串
9 '''
10 flag = None
11 if isinstance(str_one,unicode):
12 str_one = str_one.encode('unicode-escape').decode('string_escape')
13 return cmp(str_one,str_two)
14 if str_one in str_two:
15 flag = True
16 else:
17 flag = False
18 return flag
19
20
21 def is_equal_dict(self,dict_one,dict_two):
22 '''
23 判斷兩個字典是否相等
24 '''
25 if isinstance(dict_one,str):
26 dict_one = json.loads(dict_one)
27 if isinstance(dict_two,str):
28 dict_two = json.loads(dict_two)
29 return cmp(dict_one,dict_two)
5.3 操作header(operation_herder.py)
1 #coding:utf-8
2 import requests
3 import json
4 from operation_json import OperetionJson
5
6
7 class OperationHeader:
8
9 def __init__(self,response):
10 self.response = json.loads(response)
11
12 def get_response_url(self):
13 '''
14 獲取登入返回的token的url
15 '''
16 url = self.response['data']['url'][0]
17 return url
18
19 def get_cookie(self):
20 '''
21 獲取cookie的jar檔案
22 '''
23 url = self.get_response_url()+"&callback=jQuery21008240514814031887_1508666806688&_=1508666806689"
24 cookie = requests.get(url).cookies
25 return cookie
26
27 def write_cookie(self):
28 cookie = requests.utils.dict_from_cookiejar(self.get_cookie())
29 op_json = OperetionJson()
30 op_json.write_data(cookie)
31
32 if __name__ == '__main__':
33
34 url = "http://www.jd.com/passport/user/login"
35 data = {
36 "username":"18513199586",
37 "password":"111111",
38 "verify":"",
39 "referer":"https://www.jd.com"
40 }
41 res = json.dumps(requests.post(url,data).json())
42 op_header = OperationHeader(res)
43 op_header.write_cookie()
5.4 操作json檔案(operation_json.py)
1 #coding:utf-8
2 import json
3 class OperetionJson:
4
5 def __init__(self,file_path=None):
6 if file_path == None:
7 self.file_path = '../dataconfig/user.json'
8 else:
9 self.file_path = file_path
10 self.data = self.read_data()
11
12 #讀取json檔案
13 def read_data(self):
14 with open(self.file_path) as fp:
15 data = json.load(fp)
16 return data
17
18 #根據關鍵字獲取資料
19 def get_data(self,id):
20 print type(self.data)
21 return self.data[id]
22
23 #寫json
24 def write_data(self,data):
25 with open('../dataconfig/cookie.json','w') as fp:
26 fp.write(json.dumps(data))
27
28
29
30 if __name__ == '__main__':
31 opjson = OperetionJson()
32 print opjson.get_data('shop')
5.5 操作資料庫(connect_db.py)
1 #coding:utf-8
2 import MySQLdb.cursors
3 import json
4 class OperationMysql:
5 def __init__(self):
6 self.conn = MySQLdb.connect(
7 host='localhost',
8 port=3306,
9 user='root',
10 passwd='123456',
11 db='le_study',
12 charset='utf8',
13 cursorclass=MySQLdb.cursors.DictCursor
14 )
15 self.cur = self.conn.cursor()
16
17 #查詢一條資料
18 def search_one(self,sql):
19 self.cur.execute(sql)
20 result = self.cur.fetchone()
21 result = json.dumps(result)
22 return result
23
24 if __name__ == '__main__':
25 op_mysql = OperationMysql()
26 res = op_mysql.search_one("select * from web_user where Name='ailiailan'")
27 print res
5.6 傳送報告郵件(send_email.py)
1 #coding:utf-8
2 import smtplib
3 from email.mime.text import MIMEText
4 class SendEmail:
5 global send_user
6 global email_host
7 global password
8 email_host = "smtp.163.com"
9 send_user = "[email protected]"
10 password = "jia_668"
11 def send_mail(self,user_list,sub,content):
12 user = "jiaxiaonan"+"<"+send_user+">"
13 message = MIMEText(content,_subtype='plain',_charset='utf-8')
14 message['Subject'] = sub
15 message['From'] = user
16 message['To'] = ";".join(user_list)
17 server = smtplib.SMTP()
18 server.connect(email_host)
19 server.login(send_user,password)
20 server.sendmail(user,user_list,message.as_string())
21 server.close()
22
23 def send_main(self,pass_list,fail_list):
24 pass_num = float(len(pass_list))
25 fail_num = float(len(fail_list))
26 count_num = pass_num+fail_num
27 #90%
28 pass_result = "%.2f%%" %(pass_num/count_num*100)
29 fail_result = "%.2f%%" %(fail_num/count_num*100)
30
31
32 user_list = ['[email protected]']
33 sub = "介面自動化測試報告"
34 content = "此次一共執行介面個數為%s個,通過個數為%s個,失敗個數為%s,通過率為%s,失敗率為%s" %(count_num,pass_num,fail_num,pass_result,fail_result )
35 self.send_mail(user_list,sub,content)
36
37 if __name__ == '__main__':
38 sen = SendEmail()
39 sen.send_main([1,2,3,4],[2,3,4,5,6,7])
六、主函式
run_test.py
1 #coding:utf-8
2 import sys
3 sys.path.append("C:/Users/lxz/Desktop/InterFace_JIA")
4 from base.runmethod import RunMethod
5 from operation_data.get_data import GetData
6 from tool.common_util import CommonUtil
7 from operation_data.dependent_data import DependdentData
8 from tool.send_email import SendEmail
9 from tool.operation_header import OperationHeader
10 from tool.operation_json import OperetionJson
11 class RunTest:
12 def __init__(self):
13 self.run_method = RunMethod()
14 self.data = GetData()
15 self.com_util = CommonUtil()
16 self.send_mai = SendEmail()
17
18 #程式執行的
19 def go_on_run(self):
20 res = None
21 pass_count = []
22 fail_count = []
23 #10 0,1,2,3
24 rows_count = self.data.get_case_lines()
25 for i in range(1,rows_count):
26 is_run = self.data.get_is_run(i)
27 if is_run:
28 url = self.data.get_request_url(i)
29 method = self.data.get_request_method(i)
30 request_data = self.data.get_data_for_json(i)
31 expect = self.data.get_expcet_data_for_mysql(i)
32 header = self.data.is_header(i)
33 depend_case = self.data.is_depend(i)
34 if depend_case != None:
35 self.depend_data = DependdentData(depend_case)
36 #獲取的依賴響應資料
37 depend_response_data = self.depend_data.get_data_for_key(i)
38 #獲取依賴的key
39 depend_key = self.data.get_depend_field(i)
40 request_data[depend_key] = depend_response_data
41 if header == 'write':
42 res = self.run_method.run_main(method,url,request_data)
43 op_header = OperationHeader(res)
44 op_header.write_cookie()
45
46 elif header == 'yes':
47 op_json = OperetionJson('../dataconfig/cookie.json')
48 cookie = op_json.get_data('apsid')
49 cookies = {
50 'apsid':cookie
51 }
52 res = self.run_method.run_main(method,url,request_data,cookies)
53 else:
54 res = self.run_method.run_main(method,url,request_data)
55
56 if self.com_util.is_equal_dict(expect,res) == 0:
57 self.data.write_result(i,'pass')
58 pass_count.append(i)
59 else:
60 self.data.write_result(i,res)
61 fail_count.append(i)
62 self.send_mai.send_main(pass_count,fail_count)
63
64 #將執行判斷封裝
65 #def get_cookie_run(self,header):
66
67
68 if __name__ == '__main__':
69 run = RunTest()
70 run.go_on_run()