PHP 實現base64編碼檔案上傳出現問題詳解
阿新 • • 發佈:2020-09-02
1.為什麼要學Excel
存測試資料
有時候有大批量的資料,存到TXT檔案裡面顯然不是最佳的方式,我們可以存到Excel裡面去,第一方便我們存資料和做資料,另一方面方便我們讀取資料,比較明朗。測試的時候就從資料庫中讀取出來,這點是非常重要的。
存測試結果
可以批量把結果存入到Excel中,也是比較好整理資料點,比我們的TXT要好。
2.安裝openpyxl
python中與excel操作相關的模組:
- xlrd庫:從excel中讀取資料,支援xls、xlsx
- xlwt庫:對excel進行修改操作,不支援對xlsx格式的修改
- xlutils庫:在xlw和xlrd中,對一個已存在的檔案進行修改。
- openpyxl:主要針對xlsx格式的excel進行讀取和編輯。
官方說法:網址:http://www.python-exceel.org/
安裝方式:pip install openxl
3.Excel中的三大物件
- WorkBook:工作簿物件
- Sheet:表單物件
- 建立一個工作薄:wb = openpyxl.Workbook()
- 新增一個sheet表單:wb.create_sheet('test_case')
- 儲存case.xlsx檔案:wb.save('cases.xlsx')
- 開啟工作簿:wb = openpyxl.load_workbook('cases.xlsx')
- 選取表單:sh = wb['Sheet1'
- 讀取第一行、第一列的資料:ce = sh.cell(row = 1,column = 1)
- 按行讀取資料:row_data = list(sh.rows)
- 關閉工作薄:wb.close()
- 按列讀取資料:columns_data = list(sh.columns)
- 寫入資料之前,該檔案一定要處於關閉狀態
- 寫入第一行、第四列的資料 value = 'result':sh.cell(row = 1,column = 4,value = 'result')
- 獲取最大行總數、最大列總數:sh.max_row、sh.max_column
- del 刪除表單的用法:del wb['sheet_name']
- remove 刪除表單的用法:sh = wb['sheet_name'] wb.remove(sh)
-
import openpyxl # 建立一個工作簿 wb = openpyxl.Workbook() # 建立一個test_case的sheet表單 wb.create_sheet('test_case') # 儲存為一個xlsx格式的檔案 wb.save('cases.xlsx') # 讀取excel中的資料 # 第一步:開啟工作簿 wb = openpyxl.load_workbook('cases.xlsx') # 第二步:選取表單 sh = wb['Sheet1'] # 第三步:讀取資料 # 引數 row:行 column:列 ce = sh.cell(row = 1,column = 1) # 讀取第一行,第一列的資料 print(ce.value) # 按行讀取資料 list(sh.rows) print(list(sh.rows)[1:]) # 按行讀取資料,去掉第一行的表頭資訊資料 for cases in list(sh.rows)[1:]: case_id = cases[0].value case_excepted = cases[1].value case_data = cases[2].value print(case_excepted,case_data) # 關閉工作薄 wb.close()
三.封裝一個讀取用例的excel類:用來實現讀取資料和寫入資料的功能
cases.xlsx的測試資料:
1.按行讀取資料,儲存在列表中
import openpyxl class Case: #這個類用來儲存用例的 __slots__ = [] #特殊的類屬性,可以用來限制這個類建立的例項屬性新增 可寫可不寫 pass class ReadExcel(object): #讀取excel資料的類 def __init__(self,file_name,sheet_name): """ 這個是用來初始化讀取物件的 :param file_name: 檔名 ---> str型別 :param sheet_name: 表單名 ———> str型別 """ # 開啟檔案 self.wb = openpyxl.load_workbook(file_name) # 選擇表單 self.sh = self.wb[sheet_name] def read_data_line(self): #按行讀取資料轉化為列表 rows_data = list(self.sh.rows) # print(rows_data) # 獲取表單的表頭資訊 titles = [] for title in rows_data[0]: titles.append(title.value) # print(titles) #定義一個空列表用來儲存測試用例 cases = [] for case in rows_data[1:]: # print(case) data = [] for cell in case: #獲取一條測試用例資料 # print(cell.value) data.append(cell.value) # print(data) #判斷該單元格是否為字串,如果是字串型別則需要使用eval();如果不是字串型別則不需要使用eval() if isinstance(cell.value,str): data.append(eval(cell.value)) else: data.append(cell.value) #將該條資料存放至cases中 # print(dict(list(zip(titles,data)))) case_data = dict(list(zip(titles,data))) cases.append(case_data) return cases if __name__ == '__main__': r = ReadExcel('cases.xlsx','Sheet1') data1 = r.read_data_line() print(data1)
2.按行讀取資料,儲存在物件中
import openpyxl class Case: pass class ReadExcel(object): def __init__(self,filename,sheetname): self.wb = openpyxl.load_workbook(filename) self.sh = self.wb[sheetname] def read_data_obj(self): """ 按行讀取資料 每條用例儲存在一個物件中 :return: """ rows_data = list(self.sh.rows) # print(rows_data) # 獲取表單的表頭資訊 titles = [] for title in rows_data[0]: titles.append(title.value) # print(titles) # 定義一個空列表用來儲存測試用例 cases = [] for case in rows_data[1:]: # print(case) #建立一個Case類的物件,用來儲存用例資料 case_obj = Case() data = [] for cell in case: # 獲取一條測試用例資料 # print(cell.value) # data.append(cell.value) # print(data) if isinstance(cell.value,str): # 判斷該單元格是否為字串,如果是字串型別則需要使用eval();如果不是字串型別則不需要使用eval() data.append(eval(cell.value)) else: data.append(cell.value) # 將該條資料存放至cases中 # print(dict(list(zip(titles,data)))) case_data = list(zip(titles, data)) # print(case_data) for i in case_data: setattr(case_obj,i[0],i[1]) # print(case_obj) # print(case_obj.case_id,case_obj.data,case_obj.excepted) cases.append(case_obj) return cases if __name__ == '__main__': r = ReadExcel('cases.xlsx','Sheet1') res = r.read_data_obj() for i in res: print(i.caseid, i.excepted, i.data)
3.將測試用例封裝到列表中,讀取指定列的資料
import openpyxl class Case: pass class ReadExcelZy(object): def __init__(self,filename,sheetname): self.wb = openpyxl.load_workbook(filename) self.sheet = self.wb[sheetname] # list1 引數為一個列表,傳入的是指定讀取資料的列,比如[1,2,3] # 每一行[1,3,5]列的資料,讀取出來就作為一條測試用例,放在字典中 # 所有的用例放在列表中並且進行返回 def read_data(self,list1): """ :param list1: list--->要讀取列 list型別 :return: 返回一個列表,每一個元素為一個用例(用例為dict型別) """ # 獲取最大的行數 max_r = self.sheet.max_row cases = [] #定義一個空列表,用來存放所有的用例資料 titles = [] #定義一個空列表,用來存放表頭 # 遍歷所有的行資料 for row in range(1,max_r+1): if row != 1: #判斷是否是第一行 case_data = [] #定義一個空列表,用來存放該行的用例資料 for column in list1: info = self.sheet.cell(row,column).value # print(info) case_data.append(info) # print(list(zip(titles,case_data))) case = dict(zip(titles,case_data)) #將該條資料和表頭進行打包組合,作用相當於dict(list(zip(titles,case_data))) # print(case) cases.append(case) # print(cases) else: #獲取表頭資料 for column in list1: title = self.sheet.cell(row,column).value titles.append(title) # print(titles) return cases if __name__ == '__main__': r = ReadExcelZy("cases.xlsx","Sheet1") res = r.read_data([1,2,3]) for o in res: print(o['caseid'],o['data'],o['excepted'])
4.將測試用例封裝到物件中,讀取指定列的資料
import openpyxl class Case: pass class ReadExcelZy(object): def __init__(self,filename,sheetname): self.wb = openpyxl.load_workbook(filename) self.sheet = self.wb[sheetname] # list1 引數為一個列表,傳入的是指定讀取資料的列,比如[1,2,3] # 每一行[1,3,5]列的資料,讀取出來就作為一條測試用例,放在字典中 # 所有的用例放在物件中並且進行返回 def read_data_obj(self,list2): max_r1 = self.sheet.max_row #獲取最大行數 cases = [] titles = [] #用來存放表頭資料 for row in range(1,max_r1+1): if row != 1: case_data = [] for column in list2: info = self.sheet.cell(row,column).value # print(info) case_data.append(info) cases_data = list(zip(titles,case_data)) #將一條用例存到一個物件中(每一列對應物件的一個屬性) case_obj = Case() for i in cases_data: # print(i) setattr(case_obj,i[0],i[1]) # print(case_obj.caseid,case_obj.excepted,case_obj.data) cases.append(case_obj) else: for column in list2: title = self.sheet.cell(row,column).value titles.append(title) return cases if __name__ == '__main__': r = ReadExcelZy("cases.xlsx","Sheet1") res = r.read_data_obj([1,2,3]) for i in res: print(i.caseid,i.data,i.excepted)
5.優化第4部分程式碼,將設定物件屬性寫在初始化方法中(封裝Excel類讀取資料最常用的方法)
import openpyxl class Case: # 這個類用來儲存用例的 def __init__(self, attrs): """ 初始化用例 :param attrs:zip型別——>[{key,value},(key1,value1)......] """ for i in attrs: setattr(self, i[0], i[1]) class ReadExcel(object): def __init__(self, filename, sheetname): """ 定義需要開啟的檔案及表名 :param filename: 檔名 :param sheetname: 表名 """ self.wb = openpyxl.load_workbook(filename) self.sheet = self.wb[sheetname] def read_data_obj_new(self, list2): # 獲取最大行數 max_r1 = self.sheet.max_row cases = [] # 用來存放表頭資料 titles = [] for row in range(1, max_r1 + 1): if row != 1: case_data = [] for column in list2: info = self.sheet.cell(row, column).value # print(info) case_data.append(info) case = list(zip(titles, case_data)) # 新建物件時,將物件傳給Case類 case_obj = Case(case) # print(case_obj.caseid,case_obj.excepted,case_obj.data) cases.append(case_obj) else: # 獲取表頭 for column in list2: title = self.sheet.cell(row, column).value titles.append(title) if None in titles: raise ValueError("傳入的表頭的資料有顯示為空") return cases if __name__ == '__main__': r = ReadExcel('cases.xlsx', 'Sheet1') res1 = r.read_data_obj_new([1, 2, 3]) for i in res1: print(i.caseid, i.data, i.excepted)
三.完整流程的程式碼
一、將測試資料引數化
import unittest from python.register_new.register import register from python.register_new.register_testcase_new import RegisterTestCase from HTMLTestRunnerNew import HTMLTestRunner class RegisterTestCase(unittest.TestCase): # 初始化測試用例 def __init__(self,modethod_name,excepted,data): # modethod_name 測試用例方法名 super().__init__(modethod_name) # excepted 測試用例的預期結果 self.excepted = excepted # data 測試用例引數值 self.data = data def setUp(self): print("準備測試環境,執行測試用例之前會執行此操作") def tearDown(self): print("還原測試環境,執行完測試用例之後會執行此操作") def test_register(self): res = register(*self.data) try: self.assertEquals(self.excepted,res) except AssertionError as e: print("該條測試用例執行未通通過") raise e else: print("該條測試用例執行通過") # 建立測試套件 suite = unittest.TestSuite() # 將測試用例新增至測試套件中 case = [{'excepted':'{"code": 1, "msg": "註冊成功"}','data':'('python1', '123456','123456')'}, {'excepted':'{"code": 0, "msg": "兩次密碼不一致"}','data':'('python1', '1234567','123456')'}] for case in cases: suite.addTest(RegisterTestCase('test_register',case['excepted'],case['data'])) # 執行測試套件,生成測試報告 with open("report.html",'wb') as f: runner = HTMLTestRunner( stream = f, verbosity = 2, title = 'python_test_report', description = '這是一份測試報告', tester = 'WL' ) runner.run(suite)
二.將呼叫封裝好的Excel類的完整程式碼流程
import unittest from python.register_new.register import register from python.register_new.register_testcase_new import RegisterTestCase from HTMLTestRunnerNew import HTMLTestRunner from python.readexcel import ReadExcel class RegisterTestCase(unittest.TestCase): # 初始化測試用例 def __init__(self, modethod_name, excepted, data): # modethod_name 測試用例方法名 super().__init__(modethod_name) # excepted 測試用例的預期結果 self.excepted = excepted # data 測試用例引數值 self.data = data def setUp(self): print("準備測試環境,執行測試用例之前會執行此操作") def tearDown(self): print("還原測試環境,執行完測試用例之後會執行此操作") def test_register(self): res = register(*self.data) try: self.assertEquals(self.excepted, res) except AssertionError as e: print("該條測試用例執行未通通過") raise e else: print("該條測試用例執行通過") # 建立測試套件 suite = unittest.TestSuite() # 呼叫封裝好的讀取資料的Excel類,獲取測試資料 r1 = ReadExcel('cases.xlsx', 'Sheet1') cases = r1.read_data_obj_new([2, 3]) # 將測試用例新增至測試套件中 for case in cases: # 需要使用eva()函式對except和data進行自動識別 suite.addTest(RegisterTestCase('test_register', eval(case.excepted), eval(case.data))) # 執行測試套件,生成測試報告 with open("report.html", 'wb') as f: runner = HTMLTestRunner( stream=f, verbosity=2, title='python_test_report', description='這是一份測試報告', tester='WL') runner.run(suite)