Python接口自動化

公司內部的一個接口自動化使用框架(非使用工具)

  工作原理: 測試用例在excel上編輯,使用第三方庫xlrd,讀取表格sheet和內容,sheetName對應模塊名,Jenkins集成服務發現服務moduleName查找對應表單,運用第三方庫requests請求接口,根據結果和期望值進行斷言,根據輸出報告判斷接口測試是否通過。

  1. 數據準備

  數據插入(容易實現的測試場景下所需外部數據)

  準備sql (接口需要重複使用,參數一定得是變量)

  2.集成部署(運維相關了解即可)

  平滑升級驗證腳本加入自動化

  3.自動化框架實現

  ●調用mysql

  ●excel遍歷測試用例

  ●requests實現接口調用

  ●根據接口返回的code值和Excel對比

  ●報告反饋

  ●暴露服務

  寫一個簡單登錄的接口自動化測試

  代碼的分層如下圖:

  coding.png

  一、寫一個封裝的獲取excel表格的模塊

  excel.png

  代碼實現如下:

  # !/usr/bin/python

  # -*- coding: UTF-8 -*-

  # 基礎包:excel的封裝

  import xlrd

  workbook = None

  def open_excel(path):    

       """打開excel"""    

        global workbook    

        if (workbook == None):        

            workbook = xlrd.open_workbook(path, on_demand=True)

  def get_sheet(sheetName):    

       """獲取頁名"""    

        global workbook    

        return workbook.sheet_by_name(sheetName)

  def get_rows(sheet):    

      """獲取行號"""    

        return sheet.nrows

  def get_content(sheet, row, col):    

      """獲取表格中內容"""    

         return sheet.cell(row, col).value

  def release(path):    

      """釋放excel減少內存"""    

        global workbook    

        workbook.release_resources()    

        del workbook

  代碼封裝後當成模塊引用,這還是最開始呢。

  二、引用log模塊獲取日誌

  準備工作:

  需要一個日誌的捕獲,包括框架和源碼拋出的expection。

  代碼如下:

  #!/usr/bin/python

  # -*- coding: UTF-8 -*-

  # 基礎包:日誌服務

  import logging

  import time

  def getLogger():

  global tezLogPath

  try:

      tezLogPath

  except NameError:

      tezLogPath = "/data/log/apiTest/"

  FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'

  # file = tezLogPath + time.strftime("%Y-%m-%d", time.localtime()) + ".log"

  # logging.basicConfig(filename=file, level=logging.INFO, format=FORMAT)

  # 開發階段爲了方便調試,可不輸出到文件

  logging.basicConfig(level=logging.INFO, format=FORMAT)

  return logging

  三、引用requests模塊接口測試

  準備工作:

  需要的請求類型和執行測試的方法。

  代碼如下:

  #!/usr/bin/python#

  #-*- coding: UTF-8 -*-

  # 基礎包:接口測試的封裝

  import requests

  import tezLog as log

  logging = log.getLogger()

  def api_test(method, url, data ,headers):    

      """

      定義一個請求接口的方法和需要的參數 

      :Args:

      method  - 企業名稱 str

      url - 用戶暱稱 str

      data - 參數 str

      headers - 請求頭信息 dict

      非RESTful API請求另外的請求類型實際用不到。也不安全。

      """  

        try:

            if method == "post":

               results = requests.post(url, data, headers=headers)

            if method == "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)

  四、關於common模塊

  主要調用二次封裝的代碼,結合業務做一個通用代碼。如下:

  #!/usr/bin/python

  # -*- coding: UTF-8 -*-

  # 業務包:通用函數

  import core.tezMysql as mysql

  import core.tezLog as log

  import gl

  import core.tezExcel as excel

  import core.tezRequest as request

  from prettytable import PrettyTable

  filename = gl.FILE_NAME

  logging = log.get_logger()

  def prepare_data(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(path, module):

      """依據模塊名獲取sheet"""

      excel.open_excel(path)

      return excel.get_sheet(module)

  def replace_holder(value):

      """遍歷字典替換佔位符"""

      for holder in gl.PLACE_HOLDER:

          value = value.replace(holder, gl.PLACE_HOLDER[holder])

      return value

  def get_prepare_sql(sheet):

      """獲取預執行SQL"""

      return replace_holder(excel.get_content(sheet, gl.SQL_ROW,     gl.SQL_COL))

  def run_test(sheet, url):

      """再執行測試用例"""

      rows = excel.get_rows(sheet)

      fail = 0

      for i in range(2, rows):

          testNumber = str(int(excel.get_content(sheet, i, gl.CASE_NUMBER)))

          testData = excel.get_content(sheet, i, gl.CASE_DATA)

          testName = excel.get_content(sheet, i, gl.CASE_NAME)

          testUrl = excel.get_content(sheet, i, gl.CASE_URL)

          testUrl = url + testUrl

          testMethod = excel.get_content(sheet, i, gl.CASE_METHOD)

          testHeaders = str(excel.get_content(sheet, i, gl.CASE_HEADERS))

          testHeaders = eval(replace_holder(testHeaders))

          testCode = excel.get_content(sheet, i, gl.CASE_CODE)

          actualCode = request.api_test(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

  五、關於參數中gl模塊

  準備工作:

  所有的參數和常量我們會整理到這個文件中,因爲設計業務和服務密碼、數據庫密碼這裏展示一部分。

  代碼如下:

  #!/usr/bin/python

  # -*- coding: UTF-8 -*-

  # 腳本功能:全部變量

  import time

  import uuid

  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的列號

  六、寫一個run文件:只是用來執行的,業務和代碼剝離。

  代碼如下:

  #!/usr/bin/python

  # -*- coding: UTF-8 -*-

  # 驗證包:接口測試腳本

  import sys

  import core.tezLog as log

  import function.common as common

  logging = log.getLogger()

  """1.外部輸入參數"""

  path = sys.path[0]      # 當前路徑

  module = sys.argv[1]    # 服務模塊名

  url = sys.argv[2]       # 服務地址

  host = sys.argv[3]      # 數據庫地址

  user = sys.argv[4]      # 數據庫用戶名

  password = sys.argv[5]  # 數據庫密碼

  db = sys.argv[6]        # 數據庫名稱

  """2.根據module獲取Sheet"""

  logging.info("-------------- Execute TestCases ---------------")

  sheet = common.get_excel_sheet(path + "/" + common.filename,  module)

  """3.數據準備"""

  logging.info("-------------- Prepare data through MysqlDB --------------")

  sql = common.get_prepare_sql(sheet)

  common.prepare_data(host=host, user=user, password=password, db=db, sql=sql)

  """4.執行測試用例"""

  res = common.run(sheet, url)

  logging.info("-------------- Get the result ------------ %s", res)

   """這裏的res是我們平滑升級的時候需要返回結果爲TRUE纔會繼續下面走。"""

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章