Python3+Requests+Excel完整接口自动化测试框架的实现


Posted in Python onOctober 11, 2019

框架整体使用Python3+Requests+Excel:包含对实时token的获取

1、------base

-------runmethond.py

runmethond:对不同的请求方式进行封装

import json
import requests

requests.packages.urllib3.disable_warnings()

class RunMethod:
  def post_main(self, url, data, header=None):
    res = None
    if header != None:
      res = requests.post(url=url, data=data, headers=header,verify=False)
    else:
      res = requests.post(url=url, data=data,verify=False)
    return res.json()

  def get_main(self, url, data=None, header=None):
    res = None
    if header != None:
      res = requests.get(url=url, params=data, headers=header, verify=False)
    else:
      res = requests.get(url=url, params=data, verify=False)
    return res.json()

  def run_main(self, method, url, data=None, header=None):
    res = None
    if method == 'Post':
      res = self.post_main(url, data, header)
    else:
      res = self.get_main(url, data, header)
    return json.dumps(res, indent=2, sort_keys=True, ensure_ascii=False)


if __name__ == '__main__':
  url = 'http://httpbin.org/post'
  data = {
    'cart': '11'
  }
  run = RunMethod()
  run_test = run.run_main(method="Post", url=url, data=data)
  print(run_test)

2、------data

------data_config.py

data_config:获取excel模块中数据

class global_val:
  Id = '0'
  request_name = '1'
  url = '2'
  run = '3'
  request_way = '4'
  header = '5'
  case_depend = '6'
  data_depend = '7'
  field_depend = '8'
  data = '9'
  expect = '10'
  result = '11'


def get_id():
  """获取case_id"""
  return global_val.Id


def get_request_name():
  """获取请求模块名称"""
  return global_val.request_name


def get_url():
  """获取请求url"""
  return global_val.url


def get_run():
  """获取是否运行"""
  return global_val.run


def get_run_way():
  """获取请求方式"""
  return global_val.request_way


def get_header():
  """获取是否携带header"""
  return global_val.header


def get_case_depend():
  """case依赖"""
  return global_val.case_depend


def get_data_depend():
  """依赖的返回数据"""
  return global_val.data_depend


def get_field_depend():
  """数据依赖字段"""
  return global_val.field_depend


def get_data():
  """获取请求数据"""
  return global_val.data


def get_expect():
  """获取预期结果"""
  return global_val.expect


def get_result():
  """获取返回结果"""
  return global_val.result

3、-----data

-----dependent_data.py

dependent_data:解决数据依赖问题

from util.operation_excel import OperationExcel
from base.runmethod import RunMethod
from data.get_data import GetData
from jsonpath_rw import jsonpath, parse
import json


class DependentData:
  """解决数据依赖问题"""

  def __init__(self, case_id):
    self.case_id = case_id
    self.opera_excel = OperationExcel()
    self.data = GetData()

  def get_case_line_data(self):
    """
    通过case_id去获取该case_id的整行数据
    :param case_id: 用例ID
    :return:
    """
    rows_data = self.opera_excel.get_row_data(self.case_id)
    return rows_data

  def run_dependent(self):
    """
    执行依赖测试,获取结果
    :return:
    """
    run_method = RunMethod()
    row_num = self.opera_excel.get_row_num(self.case_id)
    request_data = self.data.get_data_for_json(row_num)
    # header = self.data.is_header(row_num)
    method = self.data.get_request_method(row_num)
    url = self.data.get_request_url(row_num)
    res = run_method.run_main(method, url, request_data)
    return json.loads(res)

  def get_data_for_key(self, row):
    """
    根据依赖的key去获取执行依赖case的响应然后返回
    :return:
    """
    depend_data = self.data.get_depend_key(row)
    response_data = self.run_dependent()
    return [match.value for match in parse(depend_data).find(response_data)][0]

4、-----data

-----get_data.py

get_data:获取excel数据

from util.operation_excel import OperationExcel
from data import data_config
from util.operation_json import OperationJson


class GetData:
  """获取excel数据"""

  def __init__(self):
    self.opera_excel = OperationExcel()

  def get_case_lines(self):
    """获取excel行数,即case的个数"""
    return self.opera_excel.get_lines()

  def get_is_run(self, row):
    """获取是否执行"""
    flag = None
    col = int(data_config.get_run())
    run_model = self.opera_excel.get_cell_value(row, col)
    if run_model == 'yes':
      flag = True
    else:
      flag = False
    return flag

  def is_header(self, row):
    """
    是否携带header
    :param row: 行号
    :return:
    """
    col = int(data_config.get_header())
    header = self.opera_excel.get_cell_value(row, col)
    if header != '':
      return header
    else:
      return None

  def get_request_method(self, row):
    """
    获取请求方式
    :param row: 行号
    :return:
    """
    # col 列
    col = int(data_config.get_run_way())
    request_method = self.opera_excel.get_cell_value(row, col)
    return request_method

  def get_request_url(self, row):
    """
    获取url
    :param row: 行号
    :return:
    """
    col = int(data_config.get_url())
    url = self.opera_excel.get_cell_value(row, col)
    return url

  def get_request_data(self, row):
    """
    获取请求数据
    :param row:行号
    :return:
    """
    col = int(data_config.get_data())
    data = self.opera_excel.get_cell_value(row, col)
    if data == '':
      return None
    return data

  def get_data_for_json(self, row):
    """
    通过关键字拿到data数据
    :param row:
    :return:
    """
    opera_json = OperationJson()
    request_data = opera_json.get_data(self.get_request_data(row))
    return request_data

  def get_expcet_data(self, row):
    """
    获取预期结果
    :param row:
    :return:
    """
    col = int(data_config.get_expect())
    expect = self.opera_excel.get_cell_value(row, col)
    if expect == "":
      return None
    else:
      return expect

  def write_result(self, row, value):
    """
    写入结果数据
    :param row:
    :param col:
    :return:
    """
    col = int(data_config.get_result())
    self.opera_excel.write_value(row, col, value)

  def get_depend_key(self, row):
    """
    获取依赖数据的key
    :param row:行号
    :return:
    """
    col = int(data_config.get_data_depend())
    depend_key = self.opera_excel.get_cell_value(row, col)
    if depend_key == "":
      return None
    else:
      return depend_key

  def is_depend(self, row):
    """
    判断是否有case依赖
    :param row:行号
    :return:
    """
    col = int(data_config.get_case_depend()) # 获取是否存在数据依赖列
    depend_case_id = self.opera_excel.get_cell_value(row, col)
    if depend_case_id == "":
      return None
    else:
      return depend_case_id

  def get_depend_field(self, row):
    """
    获取依赖字段
    :param row:
    :return:
    """
    col = int(data_config.get_field_depend())
    data = self.opera_excel.get_cell_value(row, col)
    if data == "":
      return None
    else:
      return data

5、-----dataconfig

-----case.xls

case.xls:用例数据

Python3+Requests+Excel完整接口自动化测试框架的实现

6、-----dataconfig

-----data.json

data.json:请求数据,根据自己实际业务,且与case层的请求数据列是关联的

{
 "user": {
  "username": "1111111",
  "password": "123456"
 },
 "filtrate": {
  "type_id": "2",
  "brand_id": "1",
  "model_id": "111"
 },
 "search": {
  "page": "1",
  "keyword": "oppo",
  "type": "12"
 },
 "token": {
  "token": ""
 }

7、-----dataconfig

-----token.json

token.json:实时自动将获取的token写入到该文件

{"data": {"token": "db6f0abee4e5040f5337f5c47a82879"}}

8、-----main

-----run_test.py

run_test:主运行程序

from base.runmethod import RunMethod
from data.get_data import GetData
from util.common_util import CommonUtil
from data.dependent_data import DependentData
# from util.send_email import SendEmail
from util.operation_header import OperationHeader
from util.operation_json import OperationJson


class RunTest:

  def __init__(self):
    self.run_method = RunMethod()
    self.data = GetData()
    self.com_util = CommonUtil()
    # self.send_email = SendEmail()

  def go_on_run(self):
    """程序执行"""
    pass_count = []
    fail_count = []
    res = None
    # 获取用例数
    rows_count = self.data.get_case_lines()
    # 第一行索引为0
    for i in range(1, rows_count):
      is_run = self.data.get_is_run(i)
      if is_run:
        url = self.data.get_request_url(i)
        method = self.data.get_request_method(i)
        request_data = self.data.get_data_for_json(i)
        expect = self.data.get_expcet_data(i)
        header = self.data.is_header(i)
        depend_case = self.data.is_depend(i)

        if depend_case != None:
          self.depend_data = DependentData(depend_case)
          # 获取依赖的响应数据
          depend_response_data = self.depend_data.get_data_for_key(i)
          # 获取依赖的key
          depend_key = self.data.get_depend_field(i)
          # 更新请求字段
          request_data[depend_key] = depend_response_data
        # 如果header字段值为write则将该接口的返回的token写入到token.json文件,如果为yes则读取token.json文件
        if header == "write":
          res = self.run_method.run_main(method, url, request_data)
          op_header = OperationHeader(res)
          op_header.write_token()
        elif header == 'yes':
          op_json = OperationJson("../dataconfig/token.json")
          token = op_json.get_data('data')
          request_data = dict(request_data, **token) # 把请求数据与登录token合并,并作为请求数据

          res = self.run_method.run_main(method, url, request_data)
        else:
          res = self.run_method.run_main(method, url, request_data)

        if expect != None:
          if self.com_util.is_contain(expect, res):
            self.data.write_result(i, "Pass")
            pass_count.append(i)
          else:
            self.data.write_result(i, res)
            fail_count.append(i)
        else:
          print(f"用例ID:case-{i},预期结果不能为空")

    # 发送邮件
    # self.send_email.send_main(pass_count, fail_count)

    print(f"通过用例数:{len(pass_count)}")
    print(f"失败用例数:{len(fail_count)}")


if __name__ == '__main__':
  run = RunTest()
  run.go_on_run()

9、-----util

-----common_util.py

common_util:用于断言

class CommonUtil:
  def is_contain(self, str_one, str_two):
    """
    判断一个字符串是否在另一个字符串中
    :param str_one:
    :param str_two:
    :return:
    """
    flag = None
    if str_one in str_two:
      flag = True
    else:
      flag = False
    return flag

10、-----util

-----operation_excel.py

operation_excel:操作excel

import xlrd
from xlutils.copy import copy


class OperationExcel:
  """操作excel"""

  def __init__(self, file_name=None, sheet_id=None):
    if file_name:
      self.file_name = file_name
      self.sheet_id = sheet_id
    else:
      self.file_name ='../dataconfig/case1.xls'
      self.sheet_id = 0
    self.data = self.get_data()

  def get_data(self):
    """
    获取sheets的内容
    :return:
    """
    data = xlrd.open_workbook(self.file_name)
    tables = data.sheets()[self.sheet_id]
    return tables

  def get_lines(self):
    """
    获取单元格行数
    :return:
    """
    tables = self.data
    return tables.nrows

  def get_cell_value(self, row, col):
    """
    获取单元格数据
    :param row: 行
    :param col: 列
    :return:
    """
    tables = self.data
    cell = tables.cell_value(row, col)
    return cell

  def write_value(self, row, col, value):
    """
    回写数据到excel
    :param row:行
    :param col:列
    :param value:值
    :return:
    """
    read_data = xlrd.open_workbook(self.file_name)
    write_data = copy(read_data)
    sheet_data = write_data.get_sheet(0)
    sheet_data.write(row, col, value)
    write_data.save(self.file_name)

  def get_row_data(self, case_id):
    """
    根据对应的case_id获取对应行的内容
    :param case_id: 用例id
    :return:
    """
    row_num = self.get_row_num(case_id)
    row_data = self.get_row_value(row_num)
    return row_data

  def get_row_num(self, case_id):
    """
    根据case_id获取对应行号
    :param case_id:
    :return:
    """
    num = 0
    cols_data = self.get_cols_data()
    for col_data in cols_data:
      if case_id in col_data:
        return num
      num = num + 1

  def get_row_value(self, row):
    """
     根据行号,找到该行的内容
    :param row:行号
    :return:

    """
    tables = self.data
    row_data = tables.row_values(row)
    return row_data

  def get_cols_data(self, col_id=None):
    """
    获取某一列的内容
    :param col_id:列号
    :return:
    """
    if col_id != None:
      cols = self.data.col_values(col_id)
    else:
      cols = self.data.col_values(0)
    return cols


if __name__ == '__main__':
  opera = OperationExcel()
  opera.get_data()
  print(opera.get_data().nrows)
  print(opera.get_lines())
  print(opera.get_cell_value(1, 2))

11、-----util

-----operation_header.py

operation_header:实时获取登录token及将token写入到token.json文件

import json
from util.operation_json import OperationJson
from base.runmethod import RunMethod
class OperationHeader:

  def __init__(self, response):
    self.response = json.loads(response)

  def get_response_token(self):
    '''
    获取登录返回的token
    '''
    token = {"data":{"token":self.response['data']['token']}}
    return token

  def write_token(self):
    op_json = OperationJson()
    op_json.write_data(self.get_response_token())

 

if __name__ == '__main__':

  url = "http://xxxxx"

  data = {
    "username": "1111",
    "password": "123456"
  }
  run_method=RunMethod()
  # res = json.dumps(requests.post(url, data).json())
  res=run_method.run_main('Post', url, data)
  op = OperationHeader(res)
  op.write_token()

12、-----util

-----operation_json.py

operation_json:操作json文件

import json


class OperationJson:
  """操作json文件"""

  def __init__(self,file_path=None):
    if file_path==None:
      self.file_path="../dataconfig/data.json"
    else:
      self.file_path=file_path
    self.data = self.read_data()

  def read_data(self):
    """
    读取json文件
    :param file_name:文件路径
    :return:
    """
    with open(self.file_path) as fp:
      data = json.load(fp)
      return data

  def get_data(self, id):
    """根据关键字获取对应数据"""
    return self.data[id]

  # 写入json
  def write_data(self, data):
    with open("../dataconfig/token.json", 'w') as fp:
      fp.write(json.dumps(data))


if __name__ == '__main__':
  # file_path = "../dataconfig/data.json"
  opejson = OperationJson()
  print(opejson.read_data())
  print(opejson.get_data('filtrate'))

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
可用于监控 mysql Master Slave 状态的python代码
Feb 10 Python
python使用三角迭代计算圆周率PI的方法
Mar 20 Python
Python爬虫抓取代理IP并检验可用性的实例
May 07 Python
Python unittest模块用法实例分析
May 25 Python
python消除序列的重复值并保持顺序不变的实例
Nov 08 Python
用Python实现BP神经网络(附代码)
Jul 10 Python
Python 求数组局部最大值的实例
Nov 26 Python
关于Python3 lambda函数的深入浅出
Nov 27 Python
对Python中 \r, \n, \r\n的彻底理解
Mar 06 Python
Python3如何判断三角形的类型
Apr 12 Python
TensorFlow tf.nn.softmax_cross_entropy_with_logits的用法
Apr 19 Python
python实现文件+参数发送request的实例代码
Jan 05 Python
python二进制读写及特殊码同步实现详解
Oct 11 #Python
Python+Tensorflow+CNN实现车牌识别的示例代码
Oct 11 #Python
命令行运行Python脚本时传入参数的三种方式详解
Oct 11 #Python
python中对_init_的理解及实例解析
Oct 11 #Python
pandas数据处理进阶详解
Oct 11 #Python
结合OpenCV与TensorFlow进行人脸识别的实现
Oct 10 #Python
树莓派安装OpenCV3完整过程的实现
Oct 10 #Python
You might like
用Flash图形化数据(一)
2006/10/09 PHP
PHP.ini安全配置检测工具pcc简单介绍
2015/07/02 PHP
2017年最新PHP经典面试题目汇总(上篇)
2017/03/17 PHP
phpStorm+XDebug+chrome 配置详解
2019/04/01 PHP
ExtJS PropertyGrid中使用Combobox选择值问题
2010/06/13 Javascript
根据json字符串生成Html的一种方式
2013/01/09 Javascript
jQuery 如何先创建、再修改、后添加DOM元素
2014/05/20 Javascript
jQuery实现Tab菜单滚动切换的方法
2015/09/21 Javascript
JS实现简单的抽奖转盘效果示例
2019/02/16 Javascript
只有 20 行的 JavaScript 模板引擎实例详解
2020/05/11 Javascript
[08:08]2014DOTA2国际邀请赛中国区预选赛精彩TOPPLAY
2014/06/25 DOTA
Python 字符串定义
2009/09/25 Python
python3使用tkinter实现ui界面简单实例
2014/01/10 Python
Python中lambda的用法及其与def的区别解析
2014/07/28 Python
基于DataFrame筛选数据与loc的用法详解
2018/05/18 Python
Python 字符串转换为整形和浮点类型的方法
2018/07/17 Python
Linux 修改Python命令的方法示例
2018/12/03 Python
numpy下的flatten()函数用法详解
2019/05/27 Python
python 基于TCP协议的套接字编程详解
2019/06/29 Python
Series和DataFrame使用简单入门
2019/11/13 Python
Python计算指定日期是今年的第几天(三种方法)
2020/03/26 Python
python如何写个俄罗斯方块
2020/11/06 Python
python操作toml文件的示例代码
2020/11/27 Python
人力资源管理专业毕业生自我评价
2013/09/21 职场文书
车间操作工岗位职责
2013/12/19 职场文书
心理健康教育制度
2014/01/27 职场文书
入党积极分子自我鉴定范文
2014/03/25 职场文书
2014年五四青年节活动方案
2014/03/29 职场文书
学生会竞聘书范文
2014/03/31 职场文书
制冷与空调专业毕业生推荐信
2014/07/07 职场文书
党员演讲稿
2014/09/04 职场文书
党员民主生活会对照检查材料思想汇报
2014/09/28 职场文书
2016领导干部廉洁从政心得体会
2016/01/19 职场文书
纪检干部学习心得体会
2016/01/23 职场文书
公司财务制度:成本管理控制制度模板
2019/11/19 职场文书
sentinel支持的redis高可用集群配置详解
2022/04/01 Redis