python+requests+excel接口自动化数据驱动

一、前言

1.环境准备:

- python3.6

- requests

- xlrd

- openpyxl

- HTMLTestRunner_api

2.目前实现的功能:

- 封装requests请求方法

- 在excel填写接口请求参数

- 运行完后,重新生成一个excel报告,结果写入excel

- 用unittest+ddt数据驱动模式执行

- HTMLTestRunner生成可视化的html报告

- 对于没有关联的单个接口请求是可以批量执行的,需要登录的话写到setUpclass里的session里保持cookies

- token关联的不能实现

- logging日志文件暂时未加入

3.目前已知的缺陷:

- 无法实现参数关联(无解):上个请求的结果是下个请求的参数,如token

(流程类的接口,需要自己封装,自己组织流程)

- 接口请求参数名有重复的,目前未处理,如key1=value1&key1=value2,两个key都一样,这种需要用元组存储,目前暂时未判断

- 生成的excel样式未处理,后期慢慢优化样式

- python新手可能遇到模块导入报错问题

二、项目结构

三、excel测试数据

四、xlrd读excel数据

1.先从excel里面读取测试数据,返回字典格式

```

# coding:utf-8

# 作者:上海-悠悠

# QQ群:226296743

import xlrd

class ExcelUtil():

def __init__(self, excelPath, sheetName="Sheet1"):

self.data = xlrd.open_workbook(excelPath)

self.table = self.data.sheet_by_name(sheetName)

# 获取第一行作为key值

self.keys = self.table.row_values(0)

# 获取总行数

self.rowNum = self.table.nrows

# 获取总列数

self.colNum = self.table.ncols

def dict_data(self):

if self.rowNum <= 1:

print("总行数小于1")

else:

r = []

j = 1

for i in list(range(self.rowNum-1)):

s = {}

# 从第二行取对应values值

s['rowNum'] = i+2

values = self.table.row_values(j)

for x in list(range(self.colNum)):

s[self.keys[x]] = values[x]

r.append(s)

j += 1

return r

if __name__ == "__main__":

filepath = "debug_api.xlsx"

sheetName = "Sheet1"

data = ExcelUtil(filepath, sheetName)

print(data.dict_data())

```

五、 openpyxl写入数据

1.为了避免修改到原测试用例里面的数据,先复制一个新的excel,放到report文件夹下

2.再封装一个写入excel数据的方法

```

# coding:utf-8

from openpyxl import load_workbook

import openpyxl

# 作者:上海-悠悠

# QQ群:226296743

def copy_excel(excelpath1, excelpath2):

'''复制excek,把excelpath1数据复制到excelpath2'''

wb2 = openpyxl.Workbook()

wb2.save(excelpath2)

# 读取数据

wb1 = openpyxl.load_workbook(excelpath1)

wb2 = openpyxl.load_workbook(excelpath2)

sheets1 = wb1.sheetnames

sheets2 = wb2.sheetnames

sheet1 = wb1[sheets1[0]]

sheet2 = wb2[sheets2[0]]

max_row = sheet1.max_row         # 最大行数

max_column = sheet1.max_column   # 最大列数

for m in list(range(1,max_row+1)):

for n in list(range(97,97+max_column)):   # chr(97)='a'

n = chr(n)                            # ASCII字符

i ='%s%d'% (n, m)                     # 单元格编号

cell1 = sheet1[i].value               # 获取data单元格数据

sheet2[i].value = cell1               # 赋值到test单元格

wb2.save(excelpath2)                 # 保存数据

wb1.close()                          # 关闭excel

wb2.close()

class Write_excel(object):

'''修改excel数据'''

def __init__(self, filename):

self.filename = filename

self.wb = load_workbook(self.filename)

self.ws = self.wb.active  # 激活sheet

def write(self, row_n, col_n, value):

'''写入数据,如(2,3,"hello"),第二行第三列写入数据"hello"'''

self.ws.cell(row_n, col_n).value = value

self.wb.save(self.filename)

if __name__ == "__main__":

copy_excel("debug_api.xlsx", "testreport.xlsx")

wt = Write_excel("testreport.xlsx")

wt.write(4, 5, "HELLEOP")

wt.write(4, 6, "HELLEOP")

```

六、封装request请求方法

1.把从excel读处理的数据作为请求参数,封装requests请求方法,传入请求参数,并返回结果

2.为了不污染测试的数据,出报告的时候先将测试的excel复制都应该新的excel

3.把测试返回的结果,在新的excel里面写入数据

```

# coding:utf-8

import json

import requests

from excelddtdriver.common.readexcel import ExcelUtil

from excelddtdriver.common.writeexcel import copy_excel, Write_excel

# 作者:上海-悠悠

# QQ群:226296743

def send_requests(s, testdata):

'''封装requests请求'''

method = testdata["method"]

url = testdata["url"]

# url后面的params参数

try:

params = eval(testdata["params"])

except:

params = None

# 请求头部headers

try:

headers = eval(testdata["headers"])

print("请求头部:%s" % headers)

except:

headers = None

# post请求body类型

type = testdata["type"]

test_nub = testdata['id']

print("*******正在执行用例:-----  %s  ----**********" % test_nub)

print("请求方式:%s, 请求url:%s" % (method, url))

print("请求params:%s" % params)

# post请求body内容

try:

bodydata = eval(testdata["body"])

except:

bodydata = {}

# 判断传data数据还是json

if type == "data":

body = bodydata

elif type == "json":

body = json.dumps(bodydata)

else:

body = bodydata

if method == "post": print("post请求body类型为:%s ,body内容为:%s" % (type, body))

verify = False

res = {}   # 接受返回数据

try:

r = s.request(method=method,

url=url,

params=params,

headers=headers,

data=body,

verify=verify

)

print("页面返回信息:%s" % r.content.decode("utf-8"))

res['id'] = testdata['id']

res['rowNum'] = testdata['rowNum']

res["statuscode"] = str(r.status_code)  # 状态码转成str

res["text"] = r.content.decode("utf-8")

res["times"] = str(r.elapsed.total_seconds())   # 接口请求时间转str

if res["statuscode"] != "200":

res["error"] = res["text"]

else:

res["error"] = ""

res["msg"] = ""

if testdata["checkpoint"] in res["text"]:

res["result"] = "pass"

print("用例测试结果:   %s---->%s" % (test_nub, res["result"]))

else:

res["result"] = "fail"

return res

except Exception as msg:

res["msg"] = str(msg)

return res

def wirte_result(result, filename="result.xlsx"):

# 返回结果的行数row_nub

row_nub = result['rowNum']

# 写入statuscode

wt = Write_excel(filename)

wt.write(row_nub, 8, result['statuscode'])       # 写入返回状态码statuscode,第8列

wt.write(row_nub, 9, result['times'])            # 耗时

wt.write(row_nub, 10, result['error'])            # 状态码非200时的返回信息

wt.write(row_nub, 12, result['result'])           # 测试结果 pass 还是fail

wt.write(row_nub, 13, result['msg'])           # 抛异常

if __name__ == "__main__":

data = ExcelUtil("debug_api.xlsx").dict_data()

print(data[0])

s = requests.session()

res = send_requests(s, data[0])

copy_excel("debug_api.xlsx", "result.xlsx")

wirte_result(res, filename="result.xlsx")

```

七、测试用例unittest+ddt

1.测试用例用unittest框架组建,并用ddt数据驱动模式,批量执行用例

```

# coding:utf-8

import unittest

import ddt

import os

import requests

from excelddtdriver.common import base_api

from excelddtdriver.common import readexcel

from excelddtdriver.common import writeexcel

# 作者:上海-悠悠

# QQ群:226296743

# 获取demo_api.xlsx路径

curpath = os.path.dirname(os.path.realpath(__file__))

testxlsx = os.path.join(curpath, "demo_api.xlsx")

# 复制demo_api.xlsx文件到report下

report_path = os.path.join(os.path.dirname(curpath), "report")

reportxlsx = os.path.join(report_path, "result.xlsx")

testdata = readexcel.ExcelUtil(testxlsx).dict_data()

@ddt.ddt

class Test_api(unittest.TestCase):

@classmethod

def setUpClass(cls):

cls.s = requests.session()

# 如果有登录的话,就在这里先登录了

writeexcel.copy_excel(testxlsx, reportxlsx) # 复制xlsx

@ddt.data(*testdata)

def test_api(self, data):

# 先复制excel数据到report

res = base_api.send_requests(self.s, data)

base_api.wirte_result(res, filename=reportxlsx)

# 检查点 checkpoint

check = data["checkpoint"]

print("检查点->:%s"%check)

# 返回结果

res_text = res["text"]

print("返回实际结果->:%s"%res_text)

# 断言

self.assertTrue(check in res_text)

if __name__ == "__main__":

unittest.main()

```

八、生成报告

1.用HTMLTestRunner生成html报告,我这里改了下名称,改成了HTMLTestRunner_api.py

此文件跟selenium的报告是通用的,github可下载[https://github.com/yoyoketang/selenium_report/tree/master/selenium_report](https://github.com/yoyoketang/selenium_report/tree/master/selenium_report)

```

# coding=utf-8

import unittest

import time

from excelddtdriver.common import HTMLTestRunner_api

import os

# 作者:上海-悠悠

# QQ群:226296743

curpath = os.path.dirname(os.path.realpath(__file__))

report_path = os.path.join(curpath, "report")

if not os.path.exists(report_path): os.mkdir(report_path)

case_path = os.path.join(curpath, "case")

def add_case(casepath=case_path, rule="test*.py"):

'''加载所有的测试用例'''

# 定义discover方法的参数

discover = unittest.defaultTestLoader.discover(casepath,

pattern=rule,)

return discover

def run_case(all_case, reportpath=report_path):

'''执行所有的用例, 并把结果写入测试报告'''

htmlreport = reportpath+r"\result.html"

print("测试报告生成地址:%s"% htmlreport)

fp = open(htmlreport, "wb")

runner = HTMLTestRunner_api.HTMLTestRunner(stream=fp,

verbosity=2,

title="测试报告",

description="用例执行情况")

# 调用add_case函数返回值

runner.run(all_case)

fp.close()

if __name__ == "__main__":

cases = add_case()

run_case(cases)

```

2.生成的excel报告

3.生成的html报告

《python3.6自动化UI+接口》第9期班3月31号开学

(0)

相关推荐

  • Python/对excel进行数据分析 (mark)

    Python对excel进行分析 目前有一个excel表,其中里面有一个工作薄的名称为:btc,在这个工作薄中有2013年–2018年的所有交易数据,本文主要实现,将不同的年份的数据保存至新的工作薄并 ...

  • 三种Python操作Excel的方法,自动化学习Get!

    来源:凹凸数据    作者:Ryoko One old watch, like brief python 大家好,我是老表- 今天和大家分享的内容是Python操作Excel的三个模块,不同方法实现自 ...

  • 史上最全Python 操作 Excel库总结!

    为了带大家了解各个库的异同,从而在不同场景下可以灵活使用,本文将横向比较7个可以操作 Excel 文件的常用模块,在比较各模块常用操作的同时进行巩固学习! 首先让我们来整体把握下不同库的特点 &quo ...

  • 超全整理|Python 操作 Excel 库 xlwings 常用操作详解!

    人人都可以简单入门Python.爬虫.数据分析  简说Python推荐  文 | 陈熹.刘早起 来源:早起Python 在之前的文章中我们曾详细的讲解了如何使用openpyxl 操作Excel,其实在 ...

  • 批量转化xlsx文件为csv格式

    写在前面 python对于文件流工作做的比R包,这是我目前的感受,今天给大家贡献一个小函数,这是赵向阳师弟编写的,我们在处理xlsx文件过程中需要将xlsx文件转化为csv文件,毕竟大部分人不是做代码 ...

  • python+openpyxl创建excel

    创建一个excel,在excel中添加4个sheet wb = openpyxl.Workbook() for i in range(4):     sheet = wb .create_sheet( ...

  • python word excel ppt自动化办公教程

    模块导入 import openpyxl 读取Excel文件 打开Excel文件 workbook = openpyxl.load_workbook('test.xlsx') 输出表单名字 # 输出工 ...

  • Python 操作 Excel 报表自动化指南!

    大家好,我是明哥! 0. Python Excel库对比 我们先来看一下python中能操作Excel的库对比(一共九个库): 1. Python xlrd 读取 操作Excel 1.1 xlrd模块 ...

  • python+requests接口自动化项目完整框架设计

    前言 有很多小伙伴吵着要完整的项目源码,完整的项目属于公司内部的代码,这个是没法分享的,违法职业道德了,就算别人分享了,也只适用于本公司内部的业务. 所以用例的代码还是得自己去一个个写,我只能分享项目 ...

  • python接口自动化22-下载文件(excel)

    前言 Content-Type类型为octets/stream,这种一般是文件类型了,比如有时候需要导出excel数据,下载excel这种场景如何用python来实现呢? 抓下载接口 1.下载的场景如 ...

  • python接口自动化40-盘点requests那些不常用(面试经常问)的高级技能

    前言 如果面试问你如何用 python 发 get/post 请求? 这种问题只要是个小白花10分钟随便看下博客都能学得会. 面试官如果知道你是资深的,还是初级的呢?面试其实最喜欢考那些你不常用的功能 ...

  • Python 接口自动化测试之数据驱动(DDT)

    在接口测试中,一个接口往往需要有多组数据进行测试,以验证接口的正确性.这样就涉及到一个问题,是不是需要编写多个测试用例来实现呢?比如一个登陆接口,登陆成功的一组数据.登陆密码错误的一组数据.登陆账号错 ...

  • Python Requests Pytest YAML Allure实现接口自动化

    作者:wintest 链接:https://www.cnblogs.com/wintest/p/13423231.html 本项目实现接口自动化的技术选型:Python+Requests+Pytest ...

  • python接口自动化1-发送get请求

    前言 requests模块,也就是老污龟,为啥叫它老污龟呢,因为这个官网上的logo就是这只污龟,接下来后面的自动化都离不开它. 一.环境安装 1.用pip安装requests模块 >>p ...

  • python接口自动化2-发送post请求

    前言 发送post的请求参考例子很简单,实际遇到的情况却是很复杂的,首先第一个post请求肯定是登录了,但登录是最难处理的.登录问题解决了,后面都简单了. 一.查看官方文档 1.学习一个新的模块,其实 ...