1. 程式人生 > >介面測試 我的 python 介面測試框架

介面測試 我的 python 介面測試框架

簡單介紹

  • Win7 64,python 3,Pycharm. unittest
  • 讀取配置檔案--讀取測試用例--執行測試用例--記錄測試結果--生成html結果檔案
  • 支援指定介面用例id的測試
  • 考慮到登陸後返回的token,useId給其他介面聯合使用的情況
  • 使用html線上生成器生成xml,基於xml管理資料,只要改xml檔案,不用改其他程式碼。
  • 檢查點的定義
    • 檢查第一層的全欄位
    • 如果有巢狀層,檢查第一層的全欄位後,檢查巢狀層的model的type型別

模組類的設計說明

  • Httpbase.py 讀取http的域名和埠
  • Config.py http方法的封裝,可以支援多協議擴充套件,get,post
  • Runner_m.py 核心程式碼。run_case是程式的入口
  • Htmlreport.py 結果生成html檔案

xml模型

<root>
    <title>導購碼介面測試</title>
    <host>dgm.XXXX</host>
    <port>80</port>
    <No>[]</No> # 指定需要執行哪些介面
    <InterfaceList> # 第一個層固定預留,只用於登陸介面
        <id>1001</id>
        <name>登陸</name>
        <method>POST</method>
        <url>/Login</url>
        <hope>{"appStatus":{"errorCode":0,"message":"操作成功"},"content":[{"user_sex":0,"fk_user_city":440300,"user_id":30,"nickname":"18576759587","user_phone":"18576759587","head_picture":"http:\/\/dgm.boweixin.com\/","has_finance":1,"user_state":1}]}</hope>
        <params>{"account":"18576759587","password":"1112111","type":"0"}</params>
        <login>user_id</login> # 登陸後返回的userid,token等
        <isList>0</isList> # 是否有巢狀
        <!--Version=3.0&UserName=18576759587&IMEI=868157020567821&Password=222222&City=%E6%B7%B1%E5%9C%B3%E5%B8%82&Province=%E5%B9%BF%E4%B8%9C%E7%9C%81&Plat=android&PhoneModel=H60-L02-->
    </InterfaceList>
    <InterfaceList>
        <id>1002</id>
        <name>廠家主頁</name>
        <method>GET</method>
        <url>/GetFactoryHome?homeId=2</url>
        <hope>{"appStatus":{"errorCode":0,"message":"操作成功"},"content":[{"business_name":"坤達點子","notice_img":"\/product\/20160718184134_321.jpg","user_type":1,"user_id":2,"goods":[{"good_price":45211.0,"good_id":12,"good_name":"艾歐","banner_picture1":"\/product\/20160719165135_8977.png"},{"good_price":199.0,"good_id":14,"good_name":"麒麟瓜1","banner_picture1":"\/product\/20160720102028_5352.jpg"},{"good_price":452.0,"good_id":6,"good_name":"實力產品","banner_picture1":"\/product\/20160718165448_2602.png"},{"good_price":99898.0,"good_id":11,"good_name":"越南芒果","banner_picture1":"\/product\/20160720100057_5877.jpg"}],"shop_img":"\/product\/20160718120144_3196.jpg","head_picture":"http:\/\/dgm.boweixin.com\/\/product\/20160718134528_4744.jpg","notice_id":1}]}</hope>
        <params>{}</params>
         <login>1</login> # 0不需要登陸後的引數,1表示需要登陸後的引數
        <isList>1</isList> # 是否有巢狀層
    </InterfaceList>

入口程式碼

gm = con_api_xml.ret_xml() # 讀取xml
hb = con_api_xml.ret_http_base(gm) #讀取http引數


#初始化報告
html_report1 = htmlreport.HtmlReport(gm)

# 測試用例(組)類
class TestInterfaceCase(unittest.TestCase):
    def __init__(self, testName, hope, index):
        super(TestInterfaceCase, self).__init__(testName)
        self.hope = hope
        self.index = index
    def setUp(self):
        self.config_http = config.ConfigHttp(hb.host, hb.port)
    def function(self):
        response = ""
        if self.index == 1: # 登陸的介面測試
             if gm[self.index]["method"] == "POST":
                response = self.config_http.post(go.URL, go.PARAMS)
                go.REALLY_RESULT = eval(response)
                print(go.REALLY_RESULT)
                hope = eval(self.hope)
                # temp = testJson.compareJson(hope, go.REALLY_RESULT, gm[self.index]["isList"])
                temp = check.compare(hope,go.REALLY_RESULT)
                if temp:
                    go.LOGIN_KY = gm[1]["login"]
                    go.LOGIN_VALUE = go.REALLY_RESULT["content"][0][go.LOGIN_KY]
                    go.RESULT = 'Pass'
                    html_report1.success_num = html_report1.success_num + 1
                else:
                    go.RESULT = 'Fail'
                    html_report1.error_num = html_report1.error_num + 1
        else:
            if gm[self.index]["login"] != "0":
                    go.PARAMS[go.LOGIN_KEY] = go.LOGIN_VALUE
            if gm[self.index]["method"] == "POST":
                response = self.config_http.post(go.URL, go.PARAMS)
            if gm[self.index]["method"] == "GET":
                response = self.config_http.get(go.URL, go.PARAMS)
            print(type(response))
            go.REALLY_RESULT = eval(str(response))
            hope = eval(self.hope)
            # temp = testJson.compareJson(hope, go.REALLY_RESULT, gm[self.index]["isList"])
            temp = check.compare(hope,go.REALLY_RESULT,  gm[self.index]["isList"])
            print(temp)
            if temp:
                go.RESULT = 'Pass'
                html_report1.success_num = html_report1.success_num + 1
            # except AssertionError:
            else:
                go.RESULT = 'Fail'
                html_report1.fail_num = html_report1.fail_num + 1
# 獲取測試套件
def get_test_suite(index):
    test_suite = unittest.TestSuite()
    hope = gm[index]["hope"] # 預期值
    # print(hope)
    test_suite.addTest(TestInterfaceCase("function", hope,index))
    return test_suite

# 執行測試用例函式
def run_case(runner):
    html_report1.case_total = 0
    case_list = hb.No
    case_list = eval(case_list)  # 把字串型別的list轉換為list
    html_report1.case_list = case_list
    temp_case = ""
    if len(case_list) == False: #判斷是否執行指定的用例ID
        temp_case = gm
        for index in range(1, len(temp_case)):
            go.URL = gm[index]['url']
            go.PARAMS = gm[index]["params"]
            test_suite = get_test_suite(index)
            runner.run(test_suite)
            # 記錄執行結果
            gm[index]["result"] = go.RESULT
            gm[index]["really_result"] = go.REALLY_RESULT
    else:
        for i in case_list:
            for j in range(1, len(gm)):
                if str(i) == gm[j]['id']:
                    go.URL = gm[j]['url']
                    go.PARAMS = gm[j]["params"]
                    test_suite = get_test_suite(j)
                    runner.run(test_suite)
                    gm[j]["result"] = go.RESULT
                    gm[j]["really_result"] = go.REALLY_RESULT
# 執行測試套件
if __name__ == '__main__':
    start_time = time.time()
    runner = unittest.TextTestRunner()
    run_case(runner)
    end_time = time.time()
    html_report1.time_caculate(end_time - start_time)  # 計算測試消耗時間
    html_report1.generate_html( r'D:\\app\\auto_http34_test\\report\report.html')     # 生成測試報告

檢查點的程式碼

def compare(exJson,factJson,isList=0):
    isFlag = True
    if exJson.get("appStatus") == factJson.get("appStatus"):
        if isList== False: # 如果沒有巢狀層
            return isFlag
        data2 = exJson.get("content")
        data3 = factJson.get("content")
        for item2 in data2:
            for item3 in data3:
                keys2 = item2.keys()
                keys3 = item3.keys()
                if keys2 == keys3: # 如果巢狀層的key完全相等
                     for key in keys2:
                        value2 = item2.get(key)
                        value3 = item3.get(key)
                        if type(value3)==type(value2):
                           pass
                        else:
                            isFlag = False
                            break
                else:
                    isFlag = False
                    break
    else:
        isFlag = False
    print(isFlag)
    return isFlag

執行結果用的是pyh拼接的html頁面

  • 頁面比較醜沒有去美化

後續優化

  • 介面加密
  • 美化UI
  • 期望值從其他介面查詢
  • 其他優化

github原始碼

後續