在學接口自動化測試時, 需要從excel中讀取測試用例的數據, 假如我的數據是這樣的:
最好是每行數據對應着一條測試用例, 為方便取值, 我選擇使用pandas庫, 先安裝 pip install pandas.
然后導入:
1 import pandas as pd 2 df=pd.read_excel('../test_data/test_data.xlsx',sheet_name='hehe')
默認第一行數據是表頭,先來簡單了解一下pandas的用法:
輸入:
1 print(df.head()) # 矩陣式輸出,無法利用數據,忽略 2 print(df.ix[0]) # 索引從第二行開始,0表示表中的第二行,表頭與行數據成映射關系
輸出:
學號 姓名 年齡 攻擊力
0 1 李連傑 27 96
1 2 甄子丹 27 93
2 3 成龍 36 90
3 4 洪金寶 38 89
4 5 吳京 16 91
學號 1
姓名 李連傑
年齡 27
攻擊力 96
輸入:
1 print(df.ix[0,1]) # 第二行第二個數據,B2 2 print(df.ix[1].values) # 第3行數據 3 print(df.ix[[1,2]].values) # 第3,4行數據,注意輸出多行里面應該要嵌套列表
輸出:
李連傑
[2 '甄子丹' 27 93]
[ [2 '甄子丹' 27 93]
[3 '成龍' 36 90] ]
輸入:
print(df.ix[[1,2],['年齡']].values) #3,4行里輸出表頭為'年齡'的列的數據,嵌套列表 print(df.ix[:,['攻擊力']].values) # 輸出所有行的表頭為'攻擊力'的列的數據,即D2-D9,嵌套列表 print(df.ix[:].values) # 輸出所有行 print(df.values) # 輸出所有行,結果與上一樣
輸出:
[[27]
[36]]
[[ 96]
[ 93]
[ 90]
[ 89]
[ 91]
[100]
[ 92]
[ 1]]
[[1 '李連傑' 27 96]
[2 '甄子丹' 27 93]
[3 '成龍' 36 90]
[4 '洪金寶' 38 89]
[5 '吳京' 16 91]
[6 '李小龍' 50 100]
[7 '趙文卓' 18 92]
[8 '劉亦菲' 3 1]]
輸入:
1 print(df.index.values) # 輸出行號 2 print(df.columns.values) # 輸出所有列標題 3 print(df['年齡'].values) #輸出指定標題列的數據 4 print(df.sample(3).values) #隨機輸出三行數據
輸出:
[0 1 2 3 4 5 6 7]
['學號' '姓名' '年齡' '攻擊力']
[27 27 36 38 16 50 18 3]
[[3 '成龍' 36 90]
[6 '李小龍' 50 100]
[7 '趙文卓' 18 92]]
輸入:
1 print(df.ix[1,['學號','年齡']].to_dict()) # 字典的形式輸出第三行特定列
輸出:
{'學號': 2, '年齡': 27}
有表頭的情況下, 輸出的數據若有多個元素,都是<class 'numpy.ndarray'>的類型的,即[[] [] [] []],大列表嵌套多個小列表,小列表之間沒有逗號隔開, 輸出的數據若只有一個元素,那就是str或者int.
然而, 在自動化測試中我們需要的可能是這樣的數據:
[{'學號': 1, '姓名': '李連傑', '年齡': 27, '攻擊力': 96}, {'學號': 2, '姓名': '甄子丹', '年齡': 27, '攻擊力': 93}]
即大列表嵌套多字典, 每條字典就是一個測試用例的數據, 那么怎么取出這種類型的呢?
1 df=pd.read_excel('../test_data/test_data.xlsx') #默認第一個sheet 2 test_data=[] 3 for i in df.index.values:#獲取行號的索引,並對其進行遍歷: 4 #根據i來獲取每一行指定的數據 並利用to_dict轉成字典 5 row_data=df.ix[i,['學號','姓名','年齡','攻擊力']].to_dict() 6 test_data.append(row_data) 7 print("最終獲取到的數據是:{0}".format(test_data))
輸出:
最終獲取到的數據是:[{'學號': 1, '姓名': '李連傑', '年齡': 27, '攻擊力': 96},
{'學號': 2, '姓名': '甄子丹', '年齡': 27, '攻擊力': 93},
{'學號': 3, '姓名': '成龍', '年齡': 36, '攻擊力': 90},
{'學號': 4, '姓名': '洪金寶', '年齡': 38, '攻擊力': 89},
{'學號': 5, '姓名': '吳京', '年齡': 16, '攻擊力': 91},
{'學號': 6, '姓名': '李小龍', '年齡': 50, '攻擊力': 100},
{'學號': 7, '姓名': '趙文卓', '年齡': 18, '攻擊力': 92},
{'學號': 8, '姓名': '劉亦菲', '年齡': 3, '攻擊力': 1}]
怎么樣,大功告成了吧, 然而你會說, 好麻煩呀,有簡單點的方法嗎?哈哈,有!
我們來看to_dict方法:
作用是把數據格式轉換成字典型的,兩個參數,into不管它,前面orient有很多值,我先輸出幾個看看:
1 import pandas as pd 2 p=pd.read_excel('../test_data/test_data.xlsx') 3 4 print("orient='list'-->",p.to_dict(orient='list')) # <class 'dict'>將表頭作為key,將每列的值放在列表中,將列表作為value 5 print("orient='index'-->:",p.to_dict(orient='index')) # 將行的索引值作為key,將存放數據的字典作為value 6 print("orient='records'-->",p.to_dict(orient='records')) # 大列表嵌套多字典,適合測試用例 7 print(p.to_dict(orient='dict')) 8 print(p.to_dict(orient='split'))
結果:
1 orient='list'--> {'學號': [1, 2, 3, 4, 5, 6, 7, 8], '姓名': ['李連傑', '甄子丹', '成龍', '洪金寶', '吳京', '李小龍', '趙文卓', '劉亦菲'], '年齡': [27, 27, 36, 38, 16, 50, 18, 3], '攻擊力': [96, 93, 90, 89, 91, 100, 92, 1]} 2 orient='index'-->: {0: {'學號': 1, '姓名': '李連傑', '年齡': 27, '攻擊力': 96}, 1: {'學號': 2, '姓名': '甄子丹', '年齡': 27, '攻擊力': 93}, 2: {'學號': 3, '姓名': '成龍', '年齡': 36, '攻擊力': 90}, 3: {'學號': 4, '姓名': '洪金寶', '年齡': 38, '攻擊力': 89}, 4: {'學號': 5, '姓名': '吳京', '年齡': 16, '攻擊力': 91}, 5: {'學號': 6, '姓名': '李小龍', '年齡': 50, '攻擊力': 100}, 6: {'學號': 7, '姓名': '趙文卓', '年齡': 18, '攻擊力': 92}, 7: {'學號': 8, '姓名': '劉亦菲', '年齡': 3, '攻擊力': 1}} 3 orient='records'--> [{'學號': 1, '姓名': '李連傑', '年齡': 27, '攻擊力': 96}, {'學號': 2, '姓名': '甄子丹', '年齡': 27, '攻擊力': 93}, {'學號': 3, '姓名': '成龍', '年齡': 36, '攻擊力': 90}, {'學號': 4, '姓名': '洪金寶', '年齡': 38, '攻擊力': 89}, {'學號': 5, '姓名': '吳京', '年齡': 16, '攻擊力': 91}, {'學號': 6, '姓名': '李小龍', '年齡': 50, '攻擊力': 100}, {'學號': 7, '姓名': '趙文卓', '年齡': 18, '攻擊力': 92}, {'學號': 8, '姓名': '劉亦菲', '年齡': 3, '攻擊力': 1}] 4 {'學號': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8}, '姓名': {0: '李連傑', 1: '甄子丹', 2: '成龍', 3: '洪金寶', 4: '吳京', 5: '李小龍', 6: '趙文卓', 7: '劉亦菲'}, '年齡': {0: 27, 1: 27, 2: 36, 3: 38, 4: 16, 5: 50, 6: 18, 7: 3}, '攻擊力': {0: 96, 1: 93, 2: 90, 3: 89, 4: 91, 5: 100, 6: 92, 7: 1}} 5 {'index': [0, 1, 2, 3, 4, 5, 6, 7], 'columns': ['學號', '姓名', '年齡', '攻擊力'], 'data': [[1, '李連傑', 27, 96], [2, '甄子丹', 27, 93], [3, '成龍', 36, 90], [4, '洪金寶', 38, 89], [5, '吳京', 16, 91], [6, '李小龍', 50, 100], [7, '趙文卓', 18, 92], [8, '劉亦菲', 3, 1]]}
發現我們測試需要的數據格式也在其中, 那就是orient='records', 所以兩行代碼解決了從excel中取出測試數據的事情, 好開心!
1 p=pd.read_excel('../test_data/test_data.xlsx') 2 print(p.to_dict(orient='records'))
取出數據測試完畢后想寫回測試結果該怎么辦呢,這就要談談另一個模塊了:openpyxl
這里我把讀取數據寫成一個類, 利用openpyxl也可以拿出大列表嵌套多字典的數據類型, 但稍微麻煩了點, 不過它還可以寫回數據. 如下:
1 from openpyxl import load_workbook 2 from tools.read_config import ReadConfig 3 4 class ReadExcel: 5 button = ReadConfig().read_config('case.config','MOD','button') 6 def read_excel_openpyxl(self,file_name,sheet_name): 7 '''從excel讀取數據並以大列表嵌套多字典的形式輸出''' 8 wb=load_workbook(file_name) 9 sheet=wb[sheet_name] 10 tit = [] 11 test_data = [] 12 row = sheet.max_row + 1 13 column = sheet.max_column + 1 14 for i in range(1, row): 15 ele = {} 16 for j in range(1, column): 17 if i == 1: 18 res = sheet.cell(i, j).value 19 tit.append(res) 20 else: 21 ele[tit[j - 1]] = sheet.cell(i, j).value 22 test_data.append(ele) # 此時的test_data里面第一個是空列表 23 24 test_data_new = [] 25 for item in test_data: 26 if item != {}: # 去除空列表 27 test_data_new.append(item) 28 return self.get_which_row(test_data_new) 29 30 def write_back_unittest(self,file_name,sheet_name,value,row,cloumn): 31 '''unittest框架用這個''' 32 wb=load_workbook(file_name) 33 sheet=wb[sheet_name] 34 sheet.cell(row,cloumn).value=value 35 wb.save(file_name) 36 37 def get_which_row(self,test_data_new): 38 '''根據button值決定取出哪些行的數據作為測試用例''' 39 test_data_final=[] 40 if self.button == 'all': 41 return test_data_new 42 else: 43 for i in eval(self.button): # 配置文件里button的值是字符串類型,切記!!! 44 test_data_final.append(test_data_new[i-1]) 45 return test_data_final
END