Reprinted: https://www.cnblogs.com/testjiali/p/10421304.html
Interface Automation combat Python (second stage) - out of the code data
We have already achieved a written test unittest framework to achieve a package request interface, so that although the interface can be completed in automated testing, but it is not high reusability.
We see each method (test) code is almost exactly the same, Imagine, in our test scenario, a registration interface, there may be a dozen to dozens of test cases, if each set of data is written one way, so there will be more duplicates the code, not only the efficiency is not high, not good maintenance.
Next, will be optimized for the frame, using the data-driven approach, 1) together with the test data management excel table, code to do the package, 2) to drive test ddt, the two parts independent of each other.
1. The separation of data and code: excel Test Data Management
In a code, test_register.py module defines three methods (three test cases), each test case are required to provide a set of test data: url, params, method, expect_res the like, is not conducive to modify and build, and now our new excel file (TestData.xlsx). as follows:
Case Design Automation:
About automated test case design is based on familiar interfaces of business processes, only familiar with the business processes, to design a better automated test data. Many point to consider here,
- id: Example No. use, from the beginning, the only
- module: Interface Module
- case_name: Examples name
- method: request type
- url: interface address information
- params: Request parameter
Case design Well, here I encountered three problems:
First: how to read the test data?
Second: test data read, should be stored into what format?
3: How to transfer data?
Of course, with a design example for the more complex scenes, it will be more consideration, which it is important to try to maintain the independence of the use cases, with the correlation between cases of not too strong, to avoid the failure of a use case, lead to other use cases can not be executed.
xlrd use
Xlrd install third-party libraries, pip install xlrd.from xlrd import open_workbook
wb = open_workbook ( "TestData.xlsx") # open Excel SH = wb.sheet_by_name ( "Register") # worksheet positioning print (sh.row_values (0)) # line output of all values of a first (list format) Print ( dict (zip (sh.row_values (0) , sh.row_values (1)))) # header and data words composed
for I in Range (sh.nrows): Print (sh.row_values (I))
Read excel packaging operation - how to read the test data?
Codes are as follows:
Import open_workbook to xlrd from class Doexcel (): DEF excel_data_list (Self, filename, sheetname): DATA_LIST = [] WB = open_workbook (filename) # open Excel SH = wb.sheet_by_name (sheetname) # positioned worksheet header = sh.row_values ( 0) # row header data acquired for i in range (1, sh.nrows ): # skip the header row, the second row starts retrieving the data col_datas = dict (zip (sh.row_values ( 0), sh.row_values ( i))) # header and data of each line, is assembled into a dictionary data_list.append (col_datas) # add to the dictionary list, a list of nested dictionaries, a dictionary corresponding to each element is a list (i.e. line data) return DATA_LIST DEF get_test_data (Self, DATA_LIST, the case_id): '' ' : param DATA_LIST: all data rows worksheet : param case_id: cases with id, used to determine which of several case execution. If id = all, it performs all use cases; otherwise, execution cases specified in the parameter list : return: return to execute a final test '' ' IF the case_id ==' All ': final_data = DATA_LIST the else: final_data = [] for in Item DATA_LIST: IF Item [' ID '] in the case_id: final_data.append (Item ) return final_data
if __name__ == '__main__':
data_list=Doexcel().excel_data_list('F:\JialiProgramfile\serviceX_API_Test\Test_datas\TestData.xlsx','register')
final_data=Doexcel().get_test_data(data_list, [1,2,3])
print(final_data)
Results of the
[{'method': 'post', 'expect_res': 200.0, 'actual_res': '', 'id': 1.0, 'test_res': '', 'case_name': 'test_register_normal', 'url': 'http://27.154.55.14:8180/api/fcb2bcrm/webRegister', 'module': 'register', 'params': '{"LoginAccount":"[email protected]","Password":"123456","Type":"Pro"}'},
{'method': 'post', 'expect_res': 400.0, 'actual_res': '', 'id': 2.0, 'test_res': '', 'case_name': 'test_register_existing', 'url': 'http://27.154.55.14:8180/api/fcb2bcrm/webRegister', 'module': 'register', 'params': '{"LoginAccount":"[email protected]","Password":"123456","Type":"Pro"}'},
{'method': 'post', 'expect_res': 400.0, 'actual_res': '', 'id': 3.0, 'test_res': '', 'case_name': 'test_register_invalid_email', 'url': 'http://27.154.55.14:8180/api/fcb2bcrm/webRegister', 'module': 'register', 'params': '{"LoginAccount":"test01@gamil","Password":"123456","Type":"Pro"}'}]
2.ddt data-driven - if transfer data?
Data-driven, personal understanding is parametric test data
1) installation of third-party libraries: pip install ddt
2) introducing ddt module: from ddt import ddt, data
3) test_register.py code to ddt
# Import Import the unittest Import Requests from the HttpRequest Common.http_request Import from Import ddt ddt, ddt Data Module # introduced from Common.do_excel Import * TEST_DATA = Doexcel () excel_data_list (. 'F.: \ JialiProgramfile \ serviceX_API_Test \ Test_datas \ TestData.xlsx' , 'register') # read all the data worksheet register, and returns a list of nested dictionary format @ddt class TestRegister (unittest.TestCase): # class must start with Test, inheritance TestCase DEF the setUp (Self): Print ( "====== began to execute test cases ======") DEF tearDown (Self): Print ( "====== ====== test case is finished") # test @ the data (* TEST_DATA) DEF test_register (Self, data_itme): # data_item that each set of test data (in the form of a dictionary) # sending request . RES = the HttpRequest () Http_Request (data_itme [ 'URL'], the eval (data_itme [ 'the params']), data_itme [ 'Method']) # asserted: the try: self.assertEqual (int (data_itme [ 'expect_res']) , res.status_code) the except AssertionError with AS E: Print ( 'the Failed') The raise E # attention must be thrown
3. Test results are written back - extend doExcel class
In the excel spreadsheet, there are two values is the need to write-back after performing the test case: the actual results and the test results.
write_back_result DEF (Self, filename, sheetname, Row, actual_res, test_result): '' ' : param filename: File name : param sheetname: write back data tables : param row: number of rows to write back : param actual_res: actual results: The results are the actual 8, 9 are the test results, such as: (2,8) (2,9) : param test_result: test results: Pass / failed : return: '' ' WB = load_workbook (filename) WB = Sheet [sheetname] sheet.cell (Row,. 8) .Value = actual_res sheet.cell (Row,. 9) .Value = test_result wb.save (filename)
In test_register.py file, a set of test data from each completed execution, call write_back_result () method, passing in the required parameters.
We have already achieved a written test unittest framework to achieve a package request interface, so that although the interface can be completed in automated testing, but it is not high reusability.
We see each method (test) code is almost exactly the same, Imagine, in our test scenario, a registration interface, there may be a dozen to dozens of test cases, if each set of data is written one way, so there will be more duplicates the code, not only the efficiency is not high, not good maintenance.
Next, will be optimized for the frame, using the data-driven approach, 1) together with the test data management excel table, code to do the package, 2) to drive test ddt, the two parts independent of each other.
1. The separation of data and code: excel Test Data Management
In a code, test_register.py module defines three methods (three test cases), each test case are required to provide a set of test data: url, params, method, expect_res the like, is not conducive to modify and build, and now our new excel file (TestData.xlsx). as follows:
Case Design Automation:
About automated test case design is based on familiar interfaces of business processes, only familiar with the business processes, to design a better automated test data. Many point to consider here,
- id: Example No. use, from the beginning, the only
- module: Interface Module
- case_name: Examples name
- method: request type
- url: interface address information
- params: Request parameter
Case design Well, here I encountered three problems:
First: how to read the test data?
Second: test data read, should be stored into what format?
3: How to transfer data?
Of course, with a design example for the more complex scenes, it will be more consideration, which it is important to try to maintain the independence of the use cases, with the correlation between cases of not too strong, to avoid the failure of a use case, lead to other use cases can not be executed.
xlrd use
Xlrd install third-party libraries, pip install xlrd.from xlrd import open_workbook
wb = open_workbook("TestData.xlsx") # 打开excel sh = wb.sheet_by_name("register") # 定位工作表 print(sh.row_values(0)) # 输出第1行的所有值(列表格式) print(dict(zip(sh.row_values(0),sh.row_values(1)))) # 将数据和标题组成字
for i in range(sh.nrows): print(sh.row_values(i))
封装读取excel操作 -如何读取测试数据?
实现代码如下:
from xlrd import open_workbook class Doexcel(): def excel_data_list(self, filename, sheetname): data_list = [] wb = open_workbook(filename) # 打开excel sh = wb.sheet_by_name(sheetname) # 定位工作表 header = sh.row_values(0) # 获取标题行的数据 for i in range(1, sh.nrows): # 跳过标题行,从第二行开始获取数据 col_datas = dict(zip(sh.row_values(0), sh.row_values(i))) # 将标题和每一行的数据,组装成字典 data_list.append(col_datas) # 将字典添加到列表中 ,列表嵌套字典,相当于每个字典的元素都是一个列表(也就是一行数据) return data_list def get_test_data(self, data_list, case_id): ''' :param data_list: 工作表的所有行数据 :param case_id: 用例id,用来判断执行哪几条case。如果id=all ,那就执行所有用例;否则,执行列表参数中指定的用例 :return: 返回最终要执行的测试用例 ''' if case_id == 'all': final_data = data_list else: final_data = [] for item in data_list: if item['id'] in case_id: final_data.append(item) return final_data
if __name__ == '__main__':
data_list=Doexcel().excel_data_list('F:\JialiProgramfile\serviceX_API_Test\Test_datas\TestData.xlsx','register')
final_data=Doexcel().get_test_data(data_list, [1,2,3])
print(final_data)
执行结果
[{'method': 'post', 'expect_res': 200.0, 'actual_res': '', 'id': 1.0, 'test_res': '', 'case_name': 'test_register_normal', 'url': 'http://27.154.55.14:8180/api/fcb2bcrm/webRegister', 'module': 'register', 'params': '{"LoginAccount":"[email protected]","Password":"123456","Type":"Pro"}'},
{'method': 'post', 'expect_res': 400.0, 'actual_res': '', 'id': 2.0, 'test_res': '', 'case_name': 'test_register_existing', 'url': 'http://27.154.55.14:8180/api/fcb2bcrm/webRegister', 'module': 'register', 'params': '{"LoginAccount":"[email protected]","Password":"123456","Type":"Pro"}'},
{'method': 'post', 'expect_res': 400.0, 'actual_res': '', 'id': 3.0, 'test_res': '', 'case_name': 'test_register_invalid_email', 'url': 'http://27.154.55.14:8180/api/fcb2bcrm/webRegister', 'module': 'register', 'params': '{"LoginAccount":"test01@gamil","Password":"123456","Type":"Pro"}'}]
2.ddt 数据驱动- 如果传递数据?
数据驱动,个人理解就是测试数据的参数化
1)安装第三方库 : pip install ddt
2)引入ddt模块:from ddt import ddt,data
3)test_register.py 代码加入ddt
# 导入 import unittest import requests from Common.http_request import HttpRequest from ddt import ddt,data # 引入ddt模块 from Common.do_excel import * test_data = Doexcel().excel_data_list('F:\JialiProgramfile\serviceX_API_Test\Test_datas\TestData.xlsx','register') #读取工作表 register 的所有数据 ,返回的是个列表嵌套字典格式 @ddt class TestRegister (unittest.TestCase): # 类必须以Test开头,继承TestCase def setUp(self): print("======开始执行测试用例======") def tearDown(self): print("======测试用例执行完毕======") # 测试用例 @data(*test_data) def test_register(self, data_itme): # data_item 就是每一组测试数据(字典的形式) # 发送请求 res = HttpRequest().http_request(data_itme['url'],eval(data_itme['params']),data_itme['method']) # 断言: try: self.assertEqual(int(data_itme['expect_res']), res.status_code) except AssertionError as e: print('Failed') raise e # 注意一定要抛出异常
3.测试结果写回 - 扩展doExcel类
在excel表格中,有 两列的值是需要在执行完测试用例后写回的:实际结果和测试结果。
write_back_result DEF (Self, filename, sheetname, Row, actual_res, test_result): '' ' : param filename: File name : param sheetname: write back data tables : param row: number of rows to write back : param actual_res: actual results: The results are the actual 8, 9 are the test results, such as: (2,8) (2,9) : param test_result: test results: Pass / failed : return: '' ' WB = load_workbook (filename) WB = Sheet [sheetname] sheet.cell (Row,. 8) .Value = actual_res sheet.cell (Row,. 9) .Value = test_result wb.save (filename)
In test_register.py file, a set of test data from each completed execution, call write_back_result () method, passing in the required parameters.