工做原理: 測試用例在excel上編輯,使用第三方庫xlrd,讀取表格sheet和內容,sheetName對應模塊名,Jenkins集成服務發現服務moduleName查找對應表單,運用第三方庫requests請求接口,根據結果和指望值進行斷言,根據輸出報告判斷接口測試是否經過。
寫一個簡單登陸的接口自動化測試python
代碼實現以下:mysql
# !/usr/bin/python # -*- coding: UTF-8 -*- # author: 赫本z # 基礎包: excel的封裝 import xlrd workbook = None def open_excel(path): """ 打開excel :param path: 打開excel文件的位置 """ global workbook if (workbook == None): workbook = xlrd.open_workbook(path, on_demand=True) def get_sheet(sheetName): """ 獲取頁名 :param sheetName: 頁名 :return: workbook """ global workbook return workbook.sheet_by_name(sheetName) def get_rows(sheet): """ 獲取行號 :param sheet: sheet :return: 行數 """ return sheet.nrows def get_content(sheet, row, col): """ 獲取表格中內容 :param sheet: sheet :param row: 行 :param col: 列 :return: """ return sheet.cell(row, col).value def release(path): """釋放excel減小內存""" global workbook workbook.release_resources() del workbook # todo:沒有驗證是否可用
代碼封裝後當成模塊引用,這仍是最開始呢。sql
準備工做:
須要一個日誌的捕獲,包括框架和源碼拋出的expection。
代碼以下:數據庫
#!/usr/bin/python # -*- coding: UTF-8 -*- # author: 赫本z # 基礎包: 日誌服務 import logging def get_logger(): global logPath try: logPath except NameError: logPath = "" FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' logging.basicConfig(level=logging.INFO, format=FORMAT) return logging
準備工做:
須要的請求類型和執行測試的方法。絕大多數公司使用Post和Get請求,一部分公司還在使用Restful API設計方案,能夠因材施教。
代碼以下:json
#!/usr/bin/python #-*- coding: UTF-8 -*- # 基礎包:接口測試的封裝 import requests import core.log as log import json logging = log.get_logger() def change_type(value): """ 對dict類型進行中文識別 :param value: 傳的數據值 :return: 轉碼後的值 """ try: if isinstance(eval(value), str): return value if isinstance(eval(value), dict): result = eval(json.dumps(value)) return result except Exception, e: logging.error("類型問題 %s", e) def api(method, url, data ,headers): """ 自定義一個接口測試的方法 :param method: 請求類型 :param url: 地址 :param data: 數據 :param headers: 請求頭 :return: code碼 """ global results try: if method == ("post" or "POST"): results = requests.post(url, data, headers=headers) if method == ("get" or "GET"): results = requests.get(url, data, headers=headers) # if method == "put": # results = requests.put(url, data, headers=headers) # if method == "delete": # results = requests.delete(url, headers=headers) # if method == "patch": # results == requests.patch(url, data, headers=headers) # if method == "options": # results == requests.options(url, headers=headers) response = results.json() code = response.get("code") return code except Exception, e: logging.error("service is error", e) def content(method, url, data, headers): """ 請求response本身能夠自定義檢查結果 :param method: 請求類型 :param url: 請求地址 :param data: 請求參數 :param headers: 請求headers :return: message信息 """ global results try: if method == ("post" or "POST"): results = requests.post(url, data, headers=headers) if method == ("get" or "GET"): results = requests.get(url, data, headers=headers) if method == ("put" or "PUT"): results = requests.put(url, data, headers=headers) if method == ("patch" or "PATCH"): results = requests.patch(url, data, headers=headers) response = results.json() message = response.get("message") result = response.get("result") content = {"message": message, "result": result} return content except Exception, e: logging.error("請求失敗 %s" % e)
主要調用二次封裝的代碼,結合業務作一個通用代碼。以下:api
#!/usr/bin/python # -*- coding: UTF-8 -*- # 業務包:通用函數 import core.mysql as mysql import core.log as log import core.request as request import core.excel as excel import constants as cs from prettytable import PrettyTable logging = log.get_logger() class ApiTest: """接口測試業務類""" filename = cs.FILE_NAME def __init__(self): pass def prepare_data(self, host, user, password, db, sql): """數據準備,添加測試數據""" mysql.connect(host, user, password, db) res = mysql.execute(sql) mysql.close() logging.info("Run sql: the row number affected is %s", res) return res def get_excel_sheet(self, path, module): """依據模塊名獲取sheet""" excel.open_excel(path) return excel.get_sheet(module) def get_prepare_sql(self, sheet): """獲取預執行SQL""" return excel.get_content(sheet, cs.SQL_ROW, cs.SQL_COL) def run_test(self, sheet, url): """再執行測試用例""" rows = excel.get_rows(sheet) fail = 0 for i in range(2, rows): testNumber = str(int(excel.get_content(sheet, i, cs.CASE_NUMBER))) testData = excel.get_content(sheet, i, cs.CASE_DATA) testName = excel.get_content(sheet, i, cs.CASE_NAME) testUrl = excel.get_content(sheet, i, cs.CASE_URL) testUrl = url + testUrl testMethod = excel.get_content(sheet, i, cs.CASE_METHOD) testHeaders = eval(excel.get_content(sheet, i, cs.CASE_HEADERS)) testCode = excel.get_content(sheet, i, cs.CASE_CODE) actualCode = request.api(testMethod, testUrl, testData, testHeaders) expectCode = str(int(testCode)) failResults = PrettyTable(["Number", "Method", "Url", "Data", "ActualCode", "ExpectCode"]) failResults.align["Number"] = "l" failResults.padding_width = 1 failResults.add_row([testNumber, testMethod, testUrl, testData, actualCode, expectCode]) if actualCode != expectCode: logging.info("FailCase %s", testName) print "FailureInfo" print failResults fail += 1 else: logging.info("Number %s", testNumber) logging.info("TrueCase %s", testName) if fail > 0: return False return True
準備工做:
全部的參數和常量咱們會整理到這個文件中,由於設計業務和服務密碼、數據庫密碼這裏展現一部分。
代碼以下:框架
#!/usr/bin/python # -*- coding: UTF-8 -*- # 通用包:常量 CASE_NUMBER = 0 # 用例編號 CASE_NAME = 1 # 用例名稱 CASE_DATA = 2 # 用例參數 CASE_URL = 3 # 用例接口地址 CASE_METHOD = 4 # 用例請求類型 CASE_CODE = 5 # 用例code CASE_HEADERS = 6 # 用例headers SQL_ROW = 0 # 預執行SQL的行號 SQL_COL = 1 # 預執行SQL的列號 FILE_NAME = 'test.xlsx'
代碼以下:運維
#!/usr/bin/python # -*- coding: UTF-8 -*- # 驗證包:接口測試腳本 import core.log as log from function.func import ApiTest func = ApiTest() logging = log.get_logger() """1.外部輸入參數""" module = 'user' url = 'http://127.0.0.1:8080' """2.根據module獲取Sheet""" logging.info("-------------- Execute TestCases ---------------") sheet = func.get_excel_sheet(func.filename, module) # """3.數據準備""" # logging.info("-------------- Prepare data through MysqlDB --------------") # sql = func.get_prepare_sql(sheet) # func.prepare_data(host=host, user=user, password=password, db=db, sql=sql) """4.執行測試用例""" res = func.run_test(sheet, url) logging.info("-------------- Get the result ------------ %s", res)