Python接口自動化實戰(第二階段)- 數據與代碼分離


前面我們已經實現了用unittest框架編寫測試用例,實現了請求接口的封裝,這樣雖然已經可以完成接口的自動化測試,但是其復用性並不高。

我們看到每個方法(測試用例)的代碼幾乎是一模一樣的,試想一下,在我們的測試場景中,一個注冊接口有可能會有十幾條到幾十條測試用例,如果每組數據都編寫一個方法,這樣將會有更多的重復項代碼,不僅執行效率不高,也不好維護。

接下來將會對框架進行優化,采用數據驅動方式,1)把測試數據用excel表格管理起來,代碼做封裝,2)用ddt來驅動測試,兩部分相互獨立。

1.數據與代碼分離:excel管理測試數據

在上一節的代碼中, test_register.py 模塊中,定義了三個方法(三個測試用例),每一個測試用例都需要提供一組測試數據:url,params,method,expect_res等,不利於修改和構建,現在我們新建 excel文件(TestData.xlsx )。如下:

自動化用例設計:

關於自動化測試用例的設計,是基於對接口業務流程的熟悉,只有熟悉業務流程,才能設計出較好的自動化測試數據。這邊要考慮的點很多,

  • id:用例編號,從1開始,唯一
  • module:接口模塊
  • case_name:用例名稱
  • method:請求類型
  • url:接口地址信息
  • params:請求參數

 

用例設計好了,這邊我遇到了三個問題:

第一:如何讀取測試數據?

第二:讀取的測試數據,應該存儲成什么格式?

第三:數據如何傳遞?

當然,用例的設計對於越復雜的場景,考慮的就會越多,其中有一點很重要,盡量保持用例的獨立性,用例之間的關聯性不要太強,避免一條用例的失敗,導致其他用例也無法執行。

xlrd 使用 

安裝xlrd第三方庫,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":"test01@gamil.com","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":"test01@gamil.com","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表格中,有 兩列的值是需要在執行完測試用例后寫回的:實際結果和測試結果。

    def write_back_result(self, filename, sheetname, row, actual_res, test_result):
        '''
        
        :param filename: 文件名
        :param sheetname: 要寫回數據的表格
        :param row: 要寫回的行數
        :param actual_res: 實際結果 :實際結果是第8列,測試結果是第9列 ,比如:(2,8)(2,9)
        :param test_result: 測試結果 :pass/failed
        :return: 
        '''
        wb = load_workbook(filename)
        sheet = wb[sheetname]
        sheet.cell(row,8).value = actual_res    
        sheet.cell(row,9).value = test_result 
        wb.save(filename)

在test_register.py文件中,每次執行完一組測試數據,調用 write_back_result()方法,將所需要的參數傳遞進去。

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM