接口自動化測試:apiAutoTest使用re 處理數據依賴

廢話

目前在工作中寫腳本的時候發現了一些之前開源的apiAutoTest的可優化項,後面應該也是會慢慢的繼續優化了

2020/11/19

截止到寫這篇文章的時間是,2020/11/19 00:53 現在也是把該項優化了,那優化了什麼尼?

參數依賴

我理解的參數依賴/接口依賴就是接口進行關聯操作,比如有些查詢接口需要登錄之後才可以操作,那麼我們就需要拿到token之類的東西,這一部分東西是放到header中的,apiAutoTest圍繞的只有路徑參數依賴,請求數據依賴

  • 路徑參數依賴

    譬如說現在的restful,一個users接口,路由一般這樣的users他的請求方式是get,這個路由我們把他認為是查所有用戶,如果查某一個用戶可能是這樣的users/:id也是個get請求,這裡這個id想表達的意思是這裡有個需要個用戶id的參數,比如1-500裏面的任意1個,也就是說這個id是可變的,可以從登錄接口的返迴響應取一個叫userId的值

  • 請求參數依賴

    這個應該好理解些,就是說支付接口需要的訂單id,是從上一步提交訂單接口返回的響應訂單id

更新後的效果

由於在改動時發現了之前的代碼挺繞的,而且都沒什麼幫助所以就不說了,如果對之前的感興趣可以看這裡://testerhome.com/topics/25003 , 下面上新版用例截圖

  • 關於文件改動,新增了data_process.py文件裏面封裝了請求保存實際結果響應,path參數處理,請求數據處理

    #!/usr/bin/env/python3
    # -*- coding:utf-8 -*-
    """
    @project: apiAutoTest
    @author: zy7y
    @file: data_process.py
    @ide: PyCharm
    @time: 2020/11/18
    """
    import json
    import re
    from tools import *
    
    
    class DataProcess:
        response_dict = {}
        header = {}
        null_header = {}
    
        @classmethod
        def save_response(cls, key: str, value: object) -> None:
            """
            保存實際響應
            :param key: 保存字典中的key,一般使用用例編號
            :param value: 保存字典中的value,使用json響應
            """
            cls.response_dict[key] = value
            logger.info(f'添加key: {key}, 對應value: {value}')
    
        @classmethod
        def handle_path(cls, path_str: str = '') -> str:
            """路徑參數處理
            :param path_str: 帶提取表達式的字符串 /&$.case_005.data.id&/state/&$.case_005.data.create_time&
            上述內容表示,從響應字典中提取到case_005字典里data字典里id的值,假設是500,後面&$.case_005.data.create_time& 類似,最終提取結果
            return  /511/state/1605711095
            """
            # /&$.case.data.id&/state/&$.case_005.data.create_time&
            path_str.split('/')
            for i in re.findall('&(.*?)&', path_str):
                path_str = path_str.replace(f'&{i}&', str(extractor(cls.response_dict, i)))
            logger.info(f'提取出的路徑地址: {path_str}')
            return path_str
    
        @classmethod
        def handle_header(cls, is_token: str, response: dict, reg) -> dict:
            """處理header"""
            if is_token == '寫':
                cls.header['Authorization'] = extractor(response, reg)
                return cls.header
            elif is_token == '':
                return cls.null_header
            else:
                return cls.header
    
        @classmethod
        def handle_data(cls, variable: str) -> dict:
            """請求數據處理
            :param variable: 請求數據,傳入的是可轉換字典/json的字符串,其中可以包含變量表達式
            return 處理之後的json/dict類型的字典數據
            """
            if variable == '':
                return
            for i in re.findall('&(.*?)&', variable):
                variable = variable.replace(f'&{i}&', str(extractor(cls.response_dict, i)))
            if 'null' in variable:
                variable = variable.replace('null', 'None')
            if 'true' in variable:
                variable = variable.replace('true', 'True')
            if 'false' in variable:
                variable = variable.replace('false', 'False')
            logger.info(f'最終的請求數據如下: {variable}')
            return eval(variable)
    
    

    相比之前這種寫法應該更加清晰,然後之前的請求數據是採用字典合併的方式,在請求數據多層結構的時候會出現bug,現在改成了文本替換之後轉json/dict的方法

新版依賴數據如何使用

舉個例子

假設現在有個實際響應結果字典如下

{"case_002": {
        "data": {
            "id": 500,
            "username": "admin",
            "mobile": "12345678",
        }},
  "case_005": {
        "data": {
            "id": 511,
            "create_time": 1605711095
        },
    }
}
  • excel中接口路徑內容:users/&$.case_005.data.id&/state/&$.case_005.data.careate_time&

    代碼內部解析後如下:users/511/state/1605711095

    &$.case_005.data.id& 代表從響應字典中提取case_005字典中data字典中的id的值,提取出來的結果是511

  • excel中請求參數內容如下:

    {
     "pagenum": 1, 
     "pagesize": "12",
     "data": &$.case_005.data&, 
     "userId": &$.case_002.data.id&
    }
    

    代碼內部解析後如下:

    {
     "pagenum": 1, 
     "pagesize": "12",
     "meta": {
                "id": 511,
                "create_time": 1605711095
            }, 
     "userId": 500
    }
    

其實不難看出其中規則&jsonpath提取語法&,如果你需要的內容是字符串類型,只需要這樣"&jsonpath提取語法&"

源碼地址

github: //github.com/zy7y/apiAutoTest.git

gitee: //gitee.com/zy7y/apiAutoTest.git

道謝

謝謝各位的點評,在實際工作寫到之後發現之前的寫法的確不如意,希望多寫,然後進步~晚安