🎉 🎂 🍰 TesterHome 创立 6 周年纪念日 🍰 🎂 🎉

接口测试 接口自动化测试,完整入门篇

lovesoo · 2017年12月01日 · 最后由 lovesoo 回复于 2018年08月07日 · 6658 次阅读
本帖已被设为精华帖!

1. 什么是接口测试

顾名思义,接口测试是对系统或组件之间的接口进行测试,主要是校验数据的交换,传递和控制管理过程,以及相互逻辑依赖关系。其中接口协议分为HTTP,WebService,Dubbo,Thrift,Socket等类型,测试类型又主要分为功能测试,性能测试,稳定性测试,安全性测试等。
在分层测试的“金字塔”模型中,接口测试属于第二层服务集成测试范畴。相比UI层(主要是WEB或APP)自动化测试而言,接口自动化测试收益更大,且容易实现,维护成本低,有着更高的投入产出比,是每个公司开展自动化测试的首选。

下面我们以一个HTTP接口为例,完整的介绍接口自动化测试流程:从需求分析到用例设计,从脚本编写、测试执行到结果分析,并提供完整的用例设计及测试脚本。

2. 基本流程

基本的接口功能自动化测试流程如下:
需求分析 -> 用例设计 -> 脚本开发 -> 测试执行 -> 结果分析

2.1 示例接口

接口名称:豆瓣电影搜索
接口文档地址:https://developers.douban.com/wiki/?title=movie_v2#search
接口调用示例:
1) 按演职人员搜索:https://api.douban.com/v2/movie/search?q=张艺谋
2) 按片名搜索:https://api.douban.com/v2/movie/search?q=大话西游
3) 按类型搜索:https://api.douban.com/v2/movie/search?tag=喜剧

3. 需求分析

需求分析是参考需求、设计等文档,在了解需求的基础上还需清楚内部的实现逻辑,并且可以在这一阶段提出需求、设计存在的不合理或遗漏之处。
如:豆瓣电影搜索接口,我理解的需求即是支持对片名,演职人员及标签的搜索,并分页返回搜索结果。

4. 用例设计

用例设计是在理解接口测试需求的基础上,使用MindManager或XMind等思维导图软件编写测试用例设计,主要内容包括参数校验,功能校验、业务场景校验、安全性及性能校验等,常用的用例设计方法有等价类划分法,边界值分析法,场景分析法,因果图,正交表等。
针对豆瓣电影搜索接口功能测试部分,我们主要从参数校验,功能校验,业务场景校验三方面,设计测试用例如下:

5. 脚本开发

依据上面编写的测试用例设计,我们使用python+nosetests框架编写了相关自动化测试脚本。可以完整实现接口自动化测试、自动执行及邮件发送测试报告功能。

5.1 相关lib安装

必要的lib库如下,使用pip命令安装即可:

pip install nose
pip install nose-htmloutput
pip install requests

5.2 接口调用

使用requests库,我们可以很方便的编写上述接口调用方法(如搜索q=刘德华,示例代码如下):

#coding=utf-8
import requests
import json

url = 'https://api.douban.com/v2/movie/search'
params=dict(q=u'刘德华')
r = requests.get(url, params=params)
print 'Search Params:\n', json.dumps(params, ensure_ascii=False)
print 'Search Response:\n', json.dumps(r.json(), ensure_ascii=False, indent=4)

在实际编写自动化测试脚本时,我们需要进行一些封装。如下代码中我们对豆瓣电影搜索接口进行了封装,test_q方法只需使用nosetests提供的yield方法即可很方便的循环执行列表qs中每一个测试集:

class test_doubanSearch(object):

@staticmethod
def search(params, expectNum=None):
url = 'https://api.douban.com/v2/movie/search'
r = requests.get(url, params=params)
print 'Search Params:\n', json.dumps(params, ensure_ascii=False)
print 'Search Response:\n', json.dumps(r.json(), ensure_ascii=False, indent=4)

def test_q(self):
# 校验搜索条件 q
qs = [u'白夜追凶', u'大话西游', u'周星驰', u'张艺谋', u'周星驰,吴孟达', u'张艺谋,巩俐', u'周星驰,大话西游', u'白夜追凶,潘粤明']
for q in qs:
params = dict(q=q)
f = partial(test_doubanSearch.search, params)
f.description = json.dumps(params, ensure_ascii=False).encode('utf-8')
yield (f,)

我们按照测试用例设计,依次编写每个功能的自动化测试脚本即可。

5.3 结果校验

在手工测试接口的时候,我们需要通过接口返回的结果判断本次测试是否通过,自动化测试也是如此。
对于本次的接口,我们搜索“q=刘德华”,我们需要判断返回的结果中是否含有“演职人员刘德华或片名刘德华”,搜索“tag=喜剧”时,需要判断返回的结果中电影类型是否为“喜剧”,结果分页时需要校验返回的结果数是否正确等。完整结果校验代码如下:

class check_response():
@staticmethod
def check_result(response, params, expectNum=None):
# 由于搜索结果存在模糊匹配的情况,这里简单处理只校验第一个返回结果的正确性
if expectNum is not None:
# 期望结果数目不为None时,只判断返回结果数目
eq_(expectNum, len(response['subjects']), '{0}!={1}'.format(expectNum, len(response['subjects'])))
else:
if not response['subjects']:
# 结果为空,直接返回失败
assert False
else:
# 结果不为空,校验第一个结果
subject = response['subjects'][0]
# 先校验搜索条件tag
if params.get('tag'):
for word in params['tag'].split(','):
genres = subject['genres']
ok_(word in genres, 'Check {0} failed!'.format(word.encode('utf-8')))

# 再校验搜索条件q
elif params.get('q'):
# 依次判断片名,导演或演员中是否含有搜索词,任意一个含有则返回成功
for word in params['q'].split(','):
title = [subject['title']]
casts = [i['name'] for i in subject['casts']]
directors = [i['name'] for i in subject['directors']]
total = title + casts + directors
ok_(any(word.lower() in i.lower() for i in total),
'Check {0} failed!'.format(word.encode('utf-8')))

@staticmethod
def check_pageSize(response):
# 判断分页结果数目是否正确
count = response.get('count')
start = response.get('start')
total = response.get('total')
diff = total - start

if diff >= count:
expectPageSize = count
elif count > diff > 0:
expectPageSize = diff
else:
expectPageSize = 0

eq_(expectPageSize, len(response['subjects']), '{0}!={1}'.format(expectPageSize, len(response['subjects'])))

5.4 执行测试

对于上述测试脚本,我们使用nosetests命令可以方便的运行自动化测试,并使用插件生成html格式测试报告。
运行命令如下:
nosetests -v test_doubanSearch.py:test_doubanSearch --with-html --html-file=TestReport.html

5.5 发送邮件报告

测试完成之后,我们可以使用smtplib模块提供的方法发送html格式测试报告。基本流程是读取测试报告 -> 添加邮件内容及附件 -> 连接邮件服务器 -> 发送邮件 -> 退出,示例代码如下:

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

def send_mail():
# 读取测试报告内容
with open(report_file, 'r') as f:
content = f.read().decode('utf-8')

msg = MIMEMultipart('mixed')
# 添加邮件内容
msg_html = MIMEText(content, 'html', 'utf-8')
msg.attach(msg_html)

# 添加附件
msg_attachment = MIMEText(content, 'html', 'utf-8')
msg_attachment["Content-Disposition"] = 'attachment; filename="{0}"'.format(report_file)
msg.attach(msg_attachment)

msg['Subject'] = mail_subjet
msg['From'] = mail_user
msg['To'] = ';'.join(mail_to)
try:
# 连接邮件服务器
s = smtplib.SMTP(mail_host, 25)
# 登陆
s.login(mail_user, mail_pwd)
# 发送邮件
s.sendmail(mail_user, mail_to, msg.as_string())
# 退出
s.quit()
except Exception as e:
print "Exceptioin ", e

6. 结果分析

打开nosetests运行完成后生成的测试报告,可以看出本次测试共执行了51条测试用例,50条成功,1条失败。

失败的用例可以看到传入的参数是:{"count": -10, "tag": "喜剧"},此时返回的结果数与我们的期望结果不一致(count为负数时,期望结果是接口报错或使用默认值20,但实际返回的结果数目是189。赶紧去给豆瓣提bug啦- -)

7. 完整脚本

豆瓣电影搜索接口的完整自动化测试脚本,我已上传到的GitHub。下载地址:https://github.com/lovesoo/test_demo/tree/master/test_douban

下载完成之后,在当前脚本目录下,使用如下命令即可进行完整的接口自动化测试并使用邮件发送最终测试报告(执行命令之前,别忘了修改脚本中邮件发件人及收件人信息为你自己的实际信息):
python test_doubanSearch.py

最终发送测试报告邮件,截图如下:

8. 参考资料

1) requests: http://cn.python-requests.org/zh_CN/latest/
2) nosetests: http://nose.readthedocs.io/en/latest/testing.html
3) nose-html-reporting: https://pypi.python.org/pypi/nose-html-reporting

9. Python 3版本

本文是基于Python 2.7编写,因为有的小伙伴使用的Python 3。特地修改了一个Python3的版本:https://github.com/lovesoo/test_demo/blob/master/test_douban/test_doubanSearch_py3.py

获取更多信息,欢迎加入测试开发交流群:25452556

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
最佳回复
Donly 回复

修改了一个Python3的版本,代码上传到了GitHub:https://github.com/lovesoo/test_demo/blob/master/test_douban/test_doubanSearch_py3.py

由于原有插件nose-html-reporting不兼容Python3,使用了新的插件nose-htmloutput (https://pypi.python.org/pypi/nose-htmloutput),可以使用如下命令安装:
pip install nose-htmloutput

直接在脚本目录下,使用如下命令运行即可(当然执行测试之前,别忘了修改脚本中邮件发件人及收件人信息为你自己的实际信息):
python test_doubanSearch_py3.py

最终执行结果如下:

有问题的话,欢迎再提问~

共收到 65 条回复 时间 点赞

这样写用例,如果后续接口变动会不会维护很麻烦

学习了!

9688e 回复

不会啊,其实可以借鉴WEB自动化测试中page-object模式,我们设计接口自动化测试的时候可以对接口的调用做封装,如果接口变动了,比如增加了一些参数,只需维护封装好的调用方法就行了。

seveniruby 将本帖设为了精华贴 12月01日 23:51

不错的入门文章,连夜进行加精。

学习了!!

学习了!!

seveniruby 回复

感谢版主😀

thanksdanny 回复

一起学习~😀

caolanmiao 回复

💪

不错的实践

学习了!!,写的蛮详细

执行的时候提示没有--with-html这个选项?为嘛呢?
直接运行脚本的话,也没有任何报告输出,似乎都没有执行测试。。。
这边环境是python3的

Donly 回复

pip install nose
pip install nose-html-reporting
pip install requests
这些lib安装了吗,代码必须要通过nosetests来运行的~

看了下nosetests -help,真的没有--with-html和--html-report这两个选项。。。。。

lovesoo 回复

肯定是都有安装的啦
刚刚试过把--with-html和--html-report改成了--with-xunit --xunit-file,可以运行了,但是一堆报错啊。。。难道说,nosetests不支持py3吗??
基本都是这样的错

nosetests -h的部分选项


这是安装后的包

Donly 回复

我安装下Python 3看看 ,这个demo用的是Python 2.7~

lovesoo 回复

我把所有的encode('utf-8')都注释掉了,然后就可以运行了。只是有报错。可能还是哪里编码不对吧。
对了,代码开头的reload和设置utf-8的两句,我也注释掉了。。

Donly 回复

修改了一个Python3的版本,代码上传到了GitHub:https://github.com/lovesoo/test_demo/blob/master/test_douban/test_doubanSearch_py3.py

由于原有插件nose-html-reporting不兼容Python3,使用了新的插件nose-htmloutput (https://pypi.python.org/pypi/nose-htmloutput),可以使用如下命令安装:
pip install nose-htmloutput

直接在脚本目录下,使用如下命令运行即可(当然执行测试之前,别忘了修改脚本中邮件发件人及收件人信息为你自己的实际信息):
python test_doubanSearch_py3.py

最终执行结果如下:

有问题的话,欢迎再提问~

发件人邮箱登陆密码要设置为邮箱的授权码才行,楼主!

xiaoqiangzq 回复

我直接用账号密码就可以的 网易163邮箱

lovesoo 回复

速度👍
有一点小问题,nose_html_reporting的init中,引入了StringIO,在py3中,没有这个模块了。应该引入io,使用io.StringIO就可以了。
另外,我看邮件中中文是正常显示的。但是如果直接打开html文件的话,中文却是乱码的哦,这个怎么破呢?

另外,关于授权码,163邮箱可以打开或关闭授权码,开了就得使用授权码,没开就使用密码。QQ的话,好像就必须使用授权码了。

Donly 回复

是的,之前插件的问题就是StringIO,改插件源码相对比较麻烦,所以直接换了另外的插件了。
直接打开Html文件乱码,我这边使用Chrome浏览器看了是正常的。不知道你是用的什么浏览器,猜测应该是需要修改下页面的编码? (右键修改编码为UTF-8)

授权码的问题,应该就是你说的那样~👍

mark,学习了

lovesoo 回复

我也是chrome,firefox也打开看了,都是乱码。。。
右键看编码已经是utf-8了

另外,刚刚运行第一遍的时候基本都是正确的,后面改了io,好多失败的。。只看test_q这一个,发现检查(大话西游)的时候失败了。但是我看返回的响应里面都是 大话西游之xxx 之类的。不知道是不是那个检查的语句问题,还是我这边的其他问题。

报错应该是导出html报告插件的Python 3兼容性问题,麻烦看下上面的置顶帖(又...换了个插件)。

搜索“周星驰,大话西游”报错,是因为返回的第一个结果是“西游降魔篇”,结果校验时这里我目前只校验了第一个结果与搜索词是否匹配,“西游降魔篇”与“大话西游”不匹配,所以报错了。

装了新插件啦。并且也执行了pip uninstall nose-html-reporting。。

Donly 回复

还有问题嘛~现在😂

lovesoo 回复

除了报告乱码,暂时没有其他问题。
剩下的就是好好来消化你这些代码了。才开始学习接口自动化,nosetest这个框架也不熟悉,json也不熟悉,所以要学习的很多呢!!多谢你给指了一个方向!

Donly 回复

额,报告乱码的问题我已经解决了啊,看我最新上传的代码和置顶的回复贴~😄

lovesoo 回复

那就没有问题了。。。是我没有重新下载py代码导致。。

Donly 回复

OK~👌


这同一个test的view点击后都是展开第一个的div,尤其那种失败的没法看详情啊

fmhying 回复

我这边看了下是OK的~也有可能是nose-html-reporting插件的bug~

还是换nose-htmloutput这个插件吧😂

lovesoo C/S 架构系统自动化测试入门 中提及了此贴 12月06日 14:54
37楼 已删除

好了,万分感谢~~~

楼主,能说下yield的作用么?我没理解到!

xiaoqiangzq 回复

可以参考我之前写的博客文章:http://www.cnblogs.com/lovesoo/p/7735380.html
官方文档:http://nose.readthedocs.io/en/latest/writing_tests.html

简单来说就是Nose支持测试方法或函数是生成器(使用yield关键字定义),Nose每次执行测试时会迭代函数生成器,为每一个yiled的tuple创建一个测试用例。

lovesoo 回复

我的天啊,我是刚学python,我一直再看python的yield,看的一脸懵逼,我还想呢返回个元组干啥。。。。
nose有啥好的中文资料吗?
还有个问题,我看网上说pytest好像更好一些,这个一般怎么选择呢,谢谢

Pastel 回复

框架的选择具体可以参考如下文章:
https://blog.zengrong.net/post/2170.html
https://wiki.python.org/moin/PythonTestingToolsTaxonomy
就我自己而言,nose是最简单的,而且与pycharm配合特别好用~😳

python 2.7.12 运行后cmd中的中文乱码,生成报告也乱码?有人遇到没?

看起来很不错,Python的接口测试

#20楼 @lovesoo 楼主,真厉害👍👍👍

—— 来自TesterHome官方 安卓客户端

sunny_2016 回复

这个应该是cmd的中文编码不是utf-8编码导致的吧~建议用pycharm运行看看呢😅

huocao 回复

💪 💪 💪 相互学习,共同进步!

{
"msg": "rate_limit_exceeded2: 183.12.27.100",
"code": 112,
"request": "GET /v2/movie/search"
}

112 rate_limit_exceeded2 IP访问速度限制
尴尬,访问这个豆瓣接口次数多,IP会被封禁?

kilalonger 回复

嗯,我也遇到过,应该是豆瓣做的安全处理,这里只是举例用的。
可以换成你们自己项目的接口哈~


楼主你好 我导入结果校验的code 怎么提示“eq_”没有定义 这个是内置函数吗

Python环境 2.7.10 Windows系统
已经安装
pip install nose
pip install nose-html-reporting
pip install requests

没有from nose.tools import *

lovesoo 回复

还是打算咨询下,为啥这个nose-htmloutput插件,运行pass的,详情看不了。
只有fail的才看的到详情。

kilalonger 回复

现在用的这个插件就是不会显示pass用例的详细日志的,如果你是Python2.7的话,可以用之前我推荐的nose-html-reporting。
另外如果你使用Pycharm的话,也可以使用Pycharm自带的测试报告导出功能,非常好用的~

lovesoo 回复

谢谢 导入之后就好了

requests.exceptions.SSLError: HTTPSConnectionPool(host='api.douban.com', port=443): Max retries exceeded with url: /v2/movie/search?q=big (Caused by SSLError(SSLError(1, u'[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)'),))

昨天成功过,今天为啥又一直报这个错了
Python -m requests.help ( "using_pyopenssl": false )
https://github.com/requests/requests/issues/4246
看了这篇文章 人家说重新装了 OpenSSL就好了 我重新装了 还是没有好 按照这篇文章装的http://www.cnblogs.com/aveenzhou/p/3912539.html

而且我网页是可以拿到接口收据的 也不至于说豆瓣把我限制了

lovesoo 回复

明白了


楼主你好 我改成 奇艺的搜索,单个测试就可以

使用nose命令行测试就又报 豆瓣SSL 验证错误 ,实际我url都改为 奇艺了
@staticmethod
def search(params, expectNum=None):
url = 'http://suggest.video.iqiyi.com'
r = requests.get(url, params=params)
print 'Search Params:\n', json.dumps(params, ensure_ascii=False)
print 'Search Response:\n', json.dumps(r.json(), ensure_ascii=False, indent=4)

def test_q(self):
# 校验搜索条件 q
qs = [u'白夜追凶.', u'大话西游', u'周星驰', u'张艺谋', u'周星驰,吴孟达', u'张艺谋,巩俐', u'周星驰,大话西游', u'白夜追凶,潘粤明']
for q in qs:
params = dict(key=q)
f = partial(test_doubanSearch.search, params)
f.description = json.dumps(params, ensure_ascii=False).encode('utf-8')
yield (f,)

moonshan 回复

要看下完整的代码才可以帮你查问题,不知道你是如何执行用例的呢

lovesoo 回复

好的 代码我怎么给你 代码全部都是粘贴的你这个页面的 我就改了个url
我感觉可能是不是我的环境的问题 只要是https的就报SSL验证错误 但是前几天我调试的时候 是好的

lovesoo 回复

我就是在Eclipse的工作空间 当前项目下执行的这个命令 nosetests -v test_doubanSearch.py:test_doubanSearch --with-html --html-file=TestReport.html
文件名 test_doubanSearch.py 类名 test_doubanSearch 是这样的跑的吗 之前是写java的 Python不怎么会 也不会调试😂

r = requests.get(url, params = params, verify=True ); 刚把verify=True 添加上 https的也可以了 单个调试的时候 ,现在就是不知道怎么跑你那个自动化的脚本😭

moonshan 回复

nosetests -v test_doubanSearch.py:test_doubanSearch --with-html --html-file=TestReport.html

前面的nosetests -v test_doubanSearch.py:test_doubanSearch的意思是执行 test_doubanSearch.py文件下的 test_doubanSearch测试类

你调试时,可以改成
nosetests -s test_doubanSearch.py:test_doubanSearch.test_q

其中 -s是打印所有输出,执行 test_doubanSearch.py文件下的 test_doubanSearch测试类下的 test_q测试方法

详见文档:http://nose.readthedocs.io/en/latest/usage.html

另外,如果写python脚本的话,还是建议用PyCharm

PyCharm运行Nosetests并导出测试报告方法: http://lovesoo.org/pycharm-run-nosetests-and-exports-test-report.html

lovesoo 回复

好的 谢谢了 我再看看

仅楼主可见
speng 回复

自己直接改下代码中的report_file参数就行了

MARK 学习下

仅楼主可见
lovesoo · #68 · 2018年08月07日 作者
仅楼主可见
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册