闲话休扯,上需求:自动读取、执行excel里面的接口测试用例,测试完成后,返回错误结果并发送邮件通知。

分析:

1、设计excel表格
2、读取excel表格
3、拼接url,发送请求
4、汇总错误结果、发送邮件

开始实现:

1、设计excel接口用例表格,大概长这样:

依次为:用例编号、接口名称、接口主host、接口路由、请求方式、请求参数类型、请求参数、断言

这次案例中用到的接口,其实就是如何优雅的进行接口测试使用的快递查询接口,一时半会儿没找到好用的,之前写的也找不到了,只好作罢。

2、读取excel表格,获取每个用例的数据

import xlrd
import sys def test_cases_in_excel(test_case_file):
test_case_file = os.path.join(os.getcwd(), test_case_file)
# 获取测试用例全路径 如:E:\Python\httprunner\interface_excel\testcases.xlsx
print(test_case_file)
if not os.path.exists(test_case_file):
print("测试用例excel文件存在或路径有误!")
# 找不到指定测试文件,就退出程序 os.system("exit")是用来退出cmd的
sys.exit()
# 读取excel文件
test_case = xlrd.open_workbook(test_case_file)
# 获取第一个sheet,下标从0开始
table = test_case.sheet_by_index(0)
# 记录错误用例
error_cases = []
# 一张表格读取下来,其实就像个二维数组,无非是读取第一行的第几列的值,由于下标是从0开始,第一行是标题,所以从第二行开始读取数据
for i in range(1, table.nrows):
num = str(int(table.cell(i, 0).value)).replace("\n", "").replace("\r", "")
api_name = table.cell(i, 1).value.replace("\n", "").replace("\r", "")
api_host = table.cell(i, 2).value.replace("\n", "").replace("\r", "")
request_url = table.cell(i, 3).value.replace("\n", "").replace("\r", "")
method = table.cell(i, 4).value.replace("\n", "").replace("\r", "")
request_data_type = table.cell(i, 5).value.replace("\n", "").replace("\r", "")
request_data = table.cell(i, 6).value.replace("\n", "").replace("\r", "")
check_point = table.cell(i, 7).value.replace("\n", "").replace("\r", "")
print(num, api_name, api_host, request_url, method, request_data_type, request_data, check_point)
try:
# 调用接口请求方法,后面会讲到
status, resp = interface_test(num, api_name, api_host, request_url, method,
request_data_type, request_data, check_point)
if status != 200 or check_point not in resp:
# append只接收一个参数,所以要讲四个参数括在一起,当一个参数来传递
# 请求失败,则向error_cases中增加一条记录
error_cases.append((num + " " + api_name, str(status), api_host + request_url))
except Exception as e:
print(e)
print("第{}个接口请求失败,请检查接口是否异常。".format(num))
# 访问异常,也向error_cases中增加一条记录
error_cases.append((num + " " + api_name, "请求失败", api_host + request_url))
return error_cases

3、拼接url,判断请求方式(get/post),发送请求

传入读取用例的各种参数,先判断请求方式,再拼接参数通过requests库来发送请求

import requests

def interface_test(num, api_name, api_host, request_url, method,
request_data_type, request_data, check_point):
# 构造请求headers
headers = {'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8',
'X-Requested-With' : 'XMLHttpRequest',
'Connection' : 'keep-alive',
'Referer' : 'http://' + api_host,
'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36'
}
# 判断请求方式,如果是GET,则调用get请求,POST调post请求,都不是,则抛出异常
if method == "GET":
r = requests.get(url=api_host+request_url, params=json.loads(request_data), headers=headers)
# 获取请求状态码
status = r.status_code
# 获取返回值
resp = r.text
if status == 200:
# 断言,判断设置的断言值,是否在返回值里面
if check_point in str(r.text):
print("第{}条用例'{}'执行成功,状态码为{},结果返回值为{}.".format(num, api_name, status, r.text))
return status, resp
else:
print("第{}条用例'{}'执行失败!!!状态码为{},结果返回值为{}.".format(num, api_name, status, r.text))
return status, resp
else:
print("第{}条用例'{}'执行失败!!!状态码为{},结果返回值为{}.".format(num, api_name, status, r.text))
return status, resp
elif method == "POST":
# 跟GET里面差不多,就不一一注释了
r = requests.post(url=api_host+request_url, params=json.loads(request_data), headers=headers)
status = r.status_code
resp = r.text
if status == 200:
if check_point in str(r.text):
print("第{}条用例'{}'执行成功,状态码为{},结果返回值为{}.".format(num, api_name, status, r.text))
return status, resp
else:
print("第{}条用例'{}'执行失败!!!状态码为{},结果返回值为{}.".format(num, api_name, status, r.text))
return status, resp
else:
print("第{}条用例'{}'执行失败!!!状态码为{},结果返回值为{}.".format(num, api_name, status, r.text))
return status, resp
else:
print("第{}条用例'{}'请求方式有误!!!请确认字段【Method】值是否正确,正确值为大写的GET或POST。".format(num, api_name))
return 400, "请求方式有误"

4、汇总错误结果、发送邮件

4.1、汇总错误结果,保存为简易html报告,并通过邮件发送到指定接收人

def main():
# 执行所以测试用例,获取错误的用例
error_cases = test_cases_in_excel("testcases.xlsx")
# 如果有错误接口,则开始构造html报告
if len(error_cases) > 0:
html = '<html><body>接口自动化扫描,共有 ' + str(len(error_cases)) + ' 个异常接口,列表如下:' + '</p><table><tr><th style="width:100px;text-align:left">接口</th><th style="width:50px;text-align:left">状态</th><th style="width:200px;text-align:left">接口地址</th></tr>'
for test in error_cases:
html = html + '<tr><td style="text-align:left">' + test[0] + '</td><td style="text-align:left">' + test[1] + '</td><td style="text-align:left">' + test[2] + '</td></tr>'
send_email(html)
print(html)
with open ("report.html", "w") as f:
f.write(html)
else:
print("本次测试,所有用例全部通过")
send_email("本次测试,所有用例全部通过")

4.2、构造邮件函数

先读取配置文件,新建config.yml配置文件,内容如下:

sender为发送邮件的邮箱,receiver为接收者着的邮箱,支持多个,smtpserver邮箱服务,username发送者邮箱少去后缀,password密码

import yaml

def get_conf():
with open ("config.yml", "r", encoding='utf-8') as f:
cfg = f.read()
dic = yaml.load(cfg)
sender = dic['email']['sender']
receiver = dic['email']['receiver']
smtpserver = dic['email']['smtpserver']
username = dic['email']['username']
password = dic['email']['password']
print(sender, receiver, smtpserver, username, password)
return sender, receiver, smtpserver, username, password

然后构造发送邮件的函数


import smtplib
import time
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.header import Header

def send_email(text):
today = time.strftime('%Y.%m.%d',time.localtime(time.time()))
sender, receiver, smtpserver, username, password = get_conf()
# subject为邮件主题 text为邮件正文
subject = "[api_test]接口自动化测试结果通知 {}".format(today)
msg = MIMEText(text, 'html', 'utf-8')
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = "".join(receiver)
smtp = smtplib.SMTP()
smtp.connect(smtpserver)
smtp.login(username, password)
smtp.sendmail(sender, receiver, msg.as_string())
smtp.quit()

以上内容就将需求实现了,由于现在很晚了(懒),上面所以函数就对在一个py文件里面了,来运行下吧

邮件一会儿就收到了

所有代码如下:

#!/usr/bin/env python
#-*- coding:utf-8 -*- '''
需求:自动读取、执行excel里面的接口测试用例,测试完成后,返回错误结果并发送邮件通知。
一步一步捋清需求:
1、设计excel表格
2、读取excel表格
3、拼接url,发送请求
4、汇总错误结果、发送邮件
'''
import xlrd
import os
import requests
import json
import yaml
import smtplib
import time
import sys
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.header import Header def test_cases_in_excel(test_case_file):
test_case_file = os.path.join(os.getcwd(), test_case_file)
# 获取测试用例全路径 如:E:\Python\httprunner\interface_excel\testcases.xlsx
print(test_case_file)
if not os.path.exists(test_case_file):
print("测试用例excel文件存在或路径有误!")
# 找不到指定测试文件,就退出程序 os.system("exit")是用来退出cmd的
sys.exit()
# 读取excel文件
test_case = xlrd.open_workbook(test_case_file)
# 获取第一个sheet,下标从0开始
table = test_case.sheet_by_index(0)
# 记录错误用例
error_cases = []
# 一张表格读取下来,其实就像个二维数组,无非是读取第一行的第几列的值,由于下标是从0开始,第一行是标题,所以从第二行开始读取数据
for i in range(1, table.nrows):
num = str(int(table.cell(i, 0).value)).replace("\n", "").replace("\r", "")
api_name = table.cell(i, 1).value.replace("\n", "").replace("\r", "")
api_host = table.cell(i, 2).value.replace("\n", "").replace("\r", "")
request_url = table.cell(i, 3).value.replace("\n", "").replace("\r", "")
method = table.cell(i, 4).value.replace("\n", "").replace("\r", "")
request_data_type = table.cell(i, 5).value.replace("\n", "").replace("\r", "")
request_data = table.cell(i, 6).value.replace("\n", "").replace("\r", "")
check_point = table.cell(i, 7).value.replace("\n", "").replace("\r", "")
print(num, api_name, api_host, request_url, method, request_data_type, request_data, check_point)
try:
# 调用接口请求方法,后面会讲到
status, resp = interface_test(num, api_name, api_host, request_url, method,
request_data_type, request_data, check_point)
if status != 200 or check_point not in resp:
# append只接收一个参数,所以要讲四个参数括在一起,当一个参数来传递
# 请求失败,则向error_cases中增加一条记录
error_cases.append((num + " " + api_name, str(status), api_host + request_url))
except Exception as e:
print(e)
print("第{}个接口请求失败,请检查接口是否异常。".format(num))
# 访问异常,也向error_cases中增加一条记录
error_cases.append((num + " " + api_name, "请求失败", api_host + request_url))
return error_cases def interface_test(num, api_name, api_host, request_url, method,
request_data_type, request_data, check_point):
# 构造请求headers
headers = {'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8',
'X-Requested-With' : 'XMLHttpRequest',
'Connection' : 'keep-alive',
'Referer' : 'http://' + api_host,
'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36'
}
# 判断请求方式,如果是GET,则调用get请求,POST调post请求,都不是,则抛出异常
if method == "GET":
r = requests.get(url=api_host+request_url, params=json.loads(request_data), headers=headers)
# 获取请求状态码
status = r.status_code
# 获取返回值
resp = r.text
if status == 200:
# 断言,判断设置的断言值,是否在返回值里面
if check_point in str(r.text):
print("第{}条用例'{}'执行成功,状态码为{},结果返回值为{}.".format(num, api_name, status, r.text))
return status, resp
else:
print("第{}条用例'{}'执行失败!!!状态码为{},结果返回值为{}.".format(num, api_name, status, r.text))
return status, resp
else:
print("第{}条用例'{}'执行失败!!!状态码为{},结果返回值为{}.".format(num, api_name, status, r.text))
return status, resp
elif method == "POST":
# 跟GET里面差不多,就不一一注释了
r = requests.post(url=api_host+request_url, params=json.loads(request_data), headers=headers)
status = r.status_code
resp = r.text
if status == 200:
if check_point in str(r.text):
print("第{}条用例'{}'执行成功,状态码为{},结果返回值为{}.".format(num, api_name, status, r.text))
return status, resp
else:
print("第{}条用例'{}'执行失败!!!状态码为{},结果返回值为{}.".format(num, api_name, status, r.text))
return status, resp
else:
print("第{}条用例'{}'执行失败!!!状态码为{},结果返回值为{}.".format(num, api_name, status, r.text))
return status, resp
else:
print("第{}条用例'{}'请求方式有误!!!请确认字段【Method】值是否正确,正确值为大写的GET或POST。".format(num, api_name))
return 400, "请求方式有误" def main():
# 执行所以测试用例,获取错误的用例
error_cases = test_cases_in_excel("testcases.xlsx")
# 如果有错误接口,则开始构造html报告
if len(error_cases) > 0:
# html = '<html><body>接口自动化扫描,共有 ' + str(len(error_cases)) + ' 个异常接口,列表如下:' + '</p><table><tr><th style="width:100px;text-align:left">接口</th><th style="width:50px;text-align:left">状态</th><th style="width:200px;text-align:left">接口地址</th><th style="text-align:left">接口返回值</th></tr>'
html = '<html><body>接口自动化扫描,共有 ' + str(len(error_cases)) + ' 个异常接口,列表如下:' + '</p><table><tr><th style="width:100px;text-align:left">接口</th><th style="width:50px;text-align:left">状态</th><th style="width:200px;text-align:left">接口地址</th></tr>'
for test in error_cases:
# html = html + '<tr><td style="text-align:left">' + test[0] + '</td><td style="text-align:left">' + test[1] + '</td><td style="text-align:left">' + test[2] + '</td><td style="text-align:left">' + test[3] + '</td></tr>'
html = html + '<tr><td style="text-align:left">' + test[0] + '</td><td style="text-align:left">' + test[1] + '</td><td style="text-align:left">' + test[2] + '</td></tr>'
send_email(html)
print(html)
with open ("report.html", "w") as f:
f.write(html)
else:
print("本次测试,所有用例全部通过")
send_email("本次测试,所有用例全部通过") def get_conf():
with open ("config.yml", "r", encoding='utf-8') as f:
cfg = f.read()
dic = yaml.load(cfg)
# print(type(dic))
# print(dic)
sender = dic['email']['sender']
receiver = dic['email']['receiver']
smtpserver = dic['email']['smtpserver']
username = dic['email']['username']
password = dic['email']['password']
print(sender, receiver, smtpserver, username, password)
return sender, receiver, smtpserver, username, password def send_email(text):
today = time.strftime('%Y.%m.%d',time.localtime(time.time()))
sender, receiver, smtpserver, username, password = get_conf()
# subject为邮件主题 text为邮件正文
subject = "[api_test]接口自动化测试结果通知 {}".format(today)
msg = MIMEText(text, 'html', 'utf-8')
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = "".join(receiver)
smtp = smtplib.SMTP()
smtp.connect(smtpserver)
smtp.login(username, password)
smtp.sendmail(sender, receiver, msg.as_string())
smtp.quit() if __name__ == "__main__":
# send_email("test")
main()

思考:

需要改进的地方有很多:

1、增加日志:导入logging模块,代码里面的print一通copy即可,自己尝试哈

2、回写excel表格:xlrd既然可以读取excel文档,肯定可以写入的。可以新增一列,每次执行完用例,将结果写进去,自己去尝试哈

3、request data type没有做判断,这里偷懒了,因为只用了一个接口,而且大晚上在赶工,就没有做判断。可以参照判断请求方式(get/post)来写。

4、报告渣:1、可以尝试使用htmlreport库;2、也可以自己尝试使用一些前端框架生成,如bootstrap

5、未做持续集成:什么是持续集成?听起来高大上,说白了就是找个数据库或者其他玩意儿,将用例、执行结果等等,都存储起来。python有很多库,可以连接各种数据库(mysql、mongoDB),读取excel或者其他接口脚本文档,存入数据库;然后请求接口后,再从库里面读取出来。balabala......

6、无界面:没有界面,其实要不要都无所谓,毕竟只要维护一份excel表格即可。如果一定要的话,可以考虑使用django或者flask框架,构造web页面,将用例的导入导出、新增、编辑、发送请求,生成报告等等一系列操作,全部移交到前端。这就需要懂一点前端代码,如果有兴趣,你也可以尝试。

最后,这篇文章其实是借鉴(抄袭)别人的,原文地址为:https://testerhome.com/topics/4948

本文章在博客留有备份,不对,微信公众号的才是备份,你不知道编辑公众号的文章是多么痛苦的一件事,但既然说了,要做,再难也要搞下去不是。

我的公众号:Python万事屋

请以excel管理你的接口测试用例的更多相关文章

  1. TestNG使用教程详解(接口测试用例编写与断言)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/sinat_34766121/artic ...

  2. postman系列之批量执行接口测试用例

    postman如何批量执行接口测试用例~其实很简单,但是会给我们的工作带来很多方便~ 比如我们写了几十个测试用例,请求都是同一个服务器IP,一旦服务器IP地址从测试环境搬到线上环境,需要修改所有的服务 ...

  3. python接口自动化(五)--接口测试用例和接口测试报告模板(详解)

    简介 当今社会在测试领域,接口测试已经越来越多的被提及,被重视,而且现在好多招聘信息要对接口测试提出要求.区别于传统意义上的系统级别测试,很多测试人员在接触到接口测试的时候,也许对测试执行还可以比较顺 ...

  4. python接口自动化(三)--如何设计接口测试用例(详解)

    简介 上篇我们已经介绍了什么是接口测试和接口测试的意义.在开始接口测试之前,我们来想一下,如何进行接口测试的准备工作.或者说,接口测试的流程是什么?有些人就很好奇,接口测试要流程干嘛?不就是拿着接口文 ...

  5. Vue之状态管理(vuex)与接口调用

    Vue之状态管理(vuex)与接口调用 一,介绍与需求 1.1,介绍 1,状态管理(vuex) Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态 ...

  6. (转)【腾讯 TMQ】 接口测试用例设计

    导语 这是我在其他的开源社区看到的一篇分享帖子.这篇文章的目的只是为大家提供一个思路,但是实现成本太高了,因为一个接口设计的接口测试用例很多,一般公司的接口数量几百到上千不等,每一个接口都设计这么多测 ...

  7. [腾讯 TMQ] 接口测试用例设计

    接口测试 [腾讯 TMQ] 接口测试用例设计 腾讯移动品质中心 · 2018年01月17日 · 最后由 于静 回复于 20 天前 · 21794 次阅读 本帖已被设为精华帖! 目录 作者:刘燕 团队: ...

  8. Tomcat学习笔记 - 错误日志 - NetBeans配置tomcat出错情况总结 -- 尚未授予访问 Tomcat 服务器的权限。请在服务器管理器的 Tomcat 定制器中设置 "manager-script" 角色的正确用户名和口令。 有关详细信息, 请查看服务器日志。

    错误描述: 发布时控制台出现: 部署错误: 尚未授予访问 Tomcat 服务器的权限.请在服务器管理器的 Tomcat 定制器中设置 "manager-script" 角色的正确用 ...

  9. 基于Groovy+HttpRestful的超轻量级的接口测试用例配置的设计方案及DEMO实现

    目标 设计一个轻量级测试用例框架,接口测试编写者只需要编写测试用例相关的内容(入参及结果校验),不需要理会系统的实现,不需要写跟测试校验无关的内容. 思路 测试用例分析 一个用例由以下部分组成: (1 ...

随机推荐

  1. Jquery delegate的理解

    $(".step4TagList .albumShow", "#divStep4").delegate(" .abmFct .icoRt", ...

  2. Android系列一: 环境搭建

      相关软件 JAVA  JDKAndroid StudioHAXM JDK的安装和Java环境变量的设置 1.JDK下载地址: http://www.oracle.com/technetwork/j ...

  3. SSH的三个组件ssh、sftp、scp介绍

    SSH  包含3个组件 (1) ssh 远程登录节点 : ssh 用户名@IP地址 ① 不允许空密码或错误密码认证登录 ② 不允许root用户登录 ③ 有两个版本 ssh,ssh2安全性更高 (2)  ...

  4. 关于MultiDataTrigger和MultiTrigger的一些注意事项

    他俩有着相同的语法. 都是在conditions中编写触发条件. 因为都是同一个触发类. 在conditions中有Property和Binding这两个属性.那么这两个可以同时使用吗?当然是不可以的 ...

  5. 3人从小公寓创业,到世界最大引擎公司,Unity创始人谈14年...

    Unity创始人David Helgason出席了5月11 - 13日在上海举办的Unite 2017 Shanghai,并在大会期间接受了游戏陀螺的专访,动情地讲述了这14年来从3人在公寓创业,到成 ...

  6. javascript点击变绿色再点击变红色

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. docker容器管理及网络管理

    防火墙规则—— INPUT 主要用于主机防火墙,设置规则屏蔽处理进入本机的数据包示例:禁止10.180.100.141这个机器访问我本机的web服务iptables -t filter -A INPU ...

  8. 引用面试官文章 :如何准备Java初级和高级的技术面试

    本人最近几年一直在做java后端方面的技术面试官,而在最近两周,又密集了面试了一些java初级和高级开发的候选人,在面试过程中,我自认为比较慎重,遇到问题回答不好的候选人,我总会再三从不同方面提问,只 ...

  9. 题解 P2350 【[HAOI2012]外星人】

    题目链接 还是本宝宝写题解的一贯习惯 $ :$ 先吐槽吐槽这道题$……$ 相信不少同学第一眼一定没有看懂题.(因为我也没看懂) ~~初中~~数学知识: 对于函数 $ f(x)$ 有 $f^{-1}(x ...

  10. Ping命令简单报错介绍

    了解ABC类IP地址:网络.主机.子网.广播. ---------------------------- 学会ping: ping www.baidu.com 网络检测:ping某一主机可以正常启动! ...