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 相关文章推荐
Python的Flask框架中Flask-Admin库的简单入门指引
Apr 07 Python
python分析作业提交情况
Nov 22 Python
在pandas中一次性删除dataframe的多个列方法
Apr 10 Python
python去掉 unicode 字符串前面的u方法
Oct 21 Python
树莓派用python中的OpenCV输出USB摄像头画面
Jun 22 Python
用Python爬取QQ音乐评论并制成词云图的实例
Aug 24 Python
Python综合应用名片管理系统案例详解
Jan 03 Python
python通过移动端访问查看电脑界面
Jan 06 Python
Django ORM filter() 的运用详解
May 14 Python
python 实现学生信息管理系统的示例
Nov 28 Python
python实现excel公式格式化的示例代码
Dec 23 Python
python实现KNN近邻算法
Dec 30 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
php下使用无限生命期Session的方法
2007/03/16 PHP
PHP SOCKET编程详解
2015/05/22 PHP
WordPress的文章自动添加关键词及关键词的SEO优化
2016/03/01 PHP
各浏览器对click方法的支持差异小结
2011/07/31 Javascript
js整数字符串转换为金额类型数据(示例代码)
2013/12/26 Javascript
JQuery处理json与ajax返回JSON实例代码
2014/01/03 Javascript
JavaScript中按位“异或”运算符使用介绍
2014/03/14 Javascript
jQuery动态星级评分效果实现方法
2015/08/06 Javascript
jQuery控制DIV层实现由大到小,由远及近动画变化效果
2015/10/09 Javascript
AngularJS实现Model缓存的方式
2016/02/03 Javascript
jQuery数据检索中根据关键字快速定位GridView指定行的实现方法
2016/06/08 Javascript
轻松5句话解决JavaScript的作用域
2016/07/15 Javascript
jquery实现下拉菜单的手风琴效果
2017/07/23 jQuery
基于jQuery实现Ajax验证用户名是否可用实例
2018/03/25 jQuery
angularjs1.X 重构controller 的方法小结
2019/08/15 Javascript
JavaScript中的this原理及6种常见使用场景详解
2020/02/14 Javascript
js数组相减简单示例【删除a数组所有与b数组相同元素】
2020/03/04 Javascript
javascript实现文字跑马灯效果
2020/06/18 Javascript
JavaScript实现网页留言板功能
2020/11/23 Javascript
[46:23]完美世界DOTA2联赛PWL S2 FTD vs Magma 第一场 11.20
2020/11/23 DOTA
python使用Flask框架获取用户IP地址的方法
2015/03/21 Python
django模型层(model)进行建表、查询与删除的基础教程
2017/11/21 Python
Python (Win)readline和tab补全的安装方法
2019/08/27 Python
python批量检查两个对应的txt文件的行数是否一致的实例代码
2020/10/31 Python
Django中ORM的基本使用教程
2020/12/22 Python
python 基于opencv操作摄像头
2020/12/24 Python
python画图时设置分辨率和画布大小的实现(plt.figure())
2021/01/08 Python
python连接手机自动搜集蚂蚁森林能量的实现代码
2021/02/24 Python
加拿大女鞋品牌:ALDO
2016/11/13 全球购物
毕业生自我鉴定范文
2013/11/08 职场文书
表彰大会新闻稿
2015/07/17 职场文书
毕业设计工作总结
2015/08/14 职场文书
Golang 正则匹配效率详解
2021/04/25 Golang
HTML中的表单Form实现居中效果
2021/05/25 HTML / CSS
详解NodeJS模块化
2021/06/15 NodeJs
MySQL Shell import_table数据导入的实现
2021/08/07 MySQL