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才会继续下面走。"""

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