你的第一个接口测试:Python 接口测试

 


前言:

    首先我们先明确一个概念,什么叫接口、什么叫接口测试?

接口的全称叫【Application Programming Interface 又叫API】,是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。

接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换,传递和控制管理过程,以及系统间的相互逻辑依赖关系等。

(本章不会讲POSTMan、Jmeter等工具,直接入直路,工具毕竟是有依赖性)

一. 前期准备

    1、准备工具:

本文版权归作者和博客园共有,原创作者:http://www.cnblogs.com/BenLam,未经作者同意必须在文章页面给出原文连接。

        1、Python3.7 + notepad (Windows自带的文本文档工具)|(Linux配合vi编辑也可以)

        2、Request库:下载地址 或通过Pip命令安装lib库:

pip install requests

  3、urllib、Unittest

  4、HTMLTestRunner获取方法【打开下面折叠代码,另存为HTMLTestRunner_Py3.Py文件】


HTMLTestRunner Code

 

    2、示例接口说明:

        演示接口:豆瓣电影搜索

        文档说明:https://developers.douban.com/wiki/?title=movie_v2#search

        api请求地址:https://api.douban.com/v2/movie/search?

        1、按片名搜索:api请求地址 + q=钢铁侠

        2、按类型搜索:api请求地址 + tag=喜剧

        说明:在实际工作中接口说明开发会提供交到我们手上的,不用担心。

    3、接口踩点:

        1、拿到 api 先别着急测试,通过手工点点能否正常使用

        2、编写对应的测试用例,例如上边测试按电影的片名和类型搜索:(演示)

testdemo1: https://api.douban.com/v2/movie/search?q=钢铁侠
testdemo2: https://api.douban.com/v2/movie/search?q=喜剧
testdemo3: https://api.douban.com/v2/movie/search?q=恐龙恐怖片
testdemo4: https://api.douban.com/v2/movie/search?q=

二. 接口调用(我会通过使用两个Python库来实现与接口通讯)

    1、urllib发起请求:

本文版权归作者和博客园共有,原创作者:http://www.cnblogs.com/BenLam,未经作者同意必须在文章页面给出原文连接。

复制代码
import urllib.request
params = "TomCruise" # 汤姆·克鲁斯的电影
url = "https://api.douban.com/v2/movie/search?"
html = urllib.request.urlopen(url + params) # 通过urllib发起请求
html = html.read().decode("utf-8")
print(html)
复制代码

    2、Requests发起请求:

import requests
params = "TomCruise" # 汤姆·克鲁斯的电影
url = "https://api.douban.com/v2/movie/search?"
req = requests.get(url) # 通过requests 发起请求
print(req)

打印结果:

复制代码
{
    "count": 20,
    "start": 0,
    "total": 40,
    "subjects": [{
        "rating": {
            "max": 10,
            "average": 7.7,
            "stars": "40",
            "min": 0
        },
        "genres": ["剧情", "悬疑", "惊悚"],
        "title": "大开眼戒",
        "casts": [{
            "alt": "https:\/\/movie.douban.com\/celebrity\/1054435\/",
            "avatars": {
                "small": "https://img1.doubanio.com\/view\/celebrity\/s_ratio_celebrity\/public\/p567.jpg",
                "large": "https://img1.doubanio.com\/view\/celebrity\/s_ratio_celebrity\/public\/p567.jpg",
                "medium": "https://img1.doubanio.com\/view\/celebrity\/s_ratio_celebrity\/public\/p567.jpg"
            },
            "name": "汤姆·克鲁斯",
            "id": "1054435"  
            .......... 省略很多东西 ...............
    "title": "搜索 \"TomCruise\" 的结果"
} json内容太长了,浓缩了重点 
复制代码

这样就完成了我们第一次请求api内容。

三. 结果校验

    1、Python自身特性断言:

本文版权归作者和博客园共有,原创作者:http://www.cnblogs.com/BenLam,未经作者同意必须在文章页面给出原文连接。

通过Requests请求,用Python IF 判断 HTTP 状态码(只有验证码是200就通过)

复制代码
import requests
actor_name = "q=TomCruise" # 汤姆·克鲁斯的电影
url = "https://api.douban.com/v2/movie/search?"
req = requests.get(url + actor_name) # 通过requests 发起请求
if req.status_code == 200:
    # req.status_code 就是HTTP的状态码
    print("测试通过,请求已成功,请求所希望的响应头或数据体将随此响应返回")
elif req.status_code == 301:
    # 有些重定向的301 可以用 elif 再判断
    print("重定向过,被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个 URI 之一")
elif req.status_code == 500:
    print("服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。")
elif req.status_code == 404:
    print("请求失败,请求所希望得到的资源未被在服务器上发现。")
else:
    print("请求出现意外,未找到合适的 HTTP Status_code!")
# 好处:通过Python自身的特性来判断返回的状态码是否正确 # 坏处:判断过于简单,无法精准检查接口
复制代码

 用Python IF 判断加强版

复制代码
import requests,json
actor_name = "q=TomCruise" # 演员名
url = "https://api.douban.com/v2/movie/search?"
try:
    req = requests.get(url + actor_name) # 通过requests 发起请求
    req = json.dumps(req.json(), ensure_ascii=False, indent=4)
except requests.RequestException as e:
    raise
name = "汤姆·克鲁斯"
if name in req: # 判断返回的数据是否包括我们搜索的条件,这里我们搜索是“汤姆克鲁斯”
    print("通过测试")
else:
    print("测试不通过")
复制代码

    2.2、Unittest断言:

 使用unittest进行判断测试结果是否包含我们想要的信息

复制代码
import requests,json
import unittest

class demo(unittest.TestCase):
    def setUp(self):
        # 初始化信息
        self.url = "https://api.douban.com/v2/movie/search?"
        self.actor_name = "q=TomCruise"
        self.style_tag = "tag=爱情"
        self.name = "汤姆·克鲁斯"
        self.action = "动作"

    def test_actor(self):
        # 执行测试
        req = requests.get(self.url + self.actor_name) # 通过requests 发起请求
        req = json.dumps(req.json(), ensure_ascii=False, indent=4)
        self.assertIn(self.name, req, msg=None) # 检查有没有 "汤姆·克鲁斯"这个演员

    def test_style_tag(self):
        # 执行测试
        req = requests.get(self.url + self.actor_name) # 通过requests 发起请求
        req = json.dumps(req.json(), ensure_ascii=False, indent=4)
        self.assertIn(self.action, req, msg=None) # 检查有没有 "动作片"

if __name__ == '__main__':
    unittest.main()
复制代码

这是通过测试的运行结果:

复制代码
..
----------------------------------------------------------------------
Ran 2 tests in 1.610s

OK
[Run in 1.9s]
复制代码

如果测试结果不通过显示F (如下):

复制代码
import unittest

class demo(unittest.TestCase):
    def test_Error(self):
        a = "1"
        b = "2"
        self.assertEqual(a,b) # 检查 a 和 b 是否相同

if __name__ == '__main__':
    unittest.main()

# ==============================
#       测试结果
# ==============================
F
======================================================================
FAIL: test_Error (__main__.demo)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\1\demo.py", line 45, in test_Error
    self.assertEqual(a,b) # 检查 a 和 b 是否相同
AssertionError: '1' != '2'
- 1
+ 2

----------------------------------------------------------------------
Ran 1 test in 0.000s

FAILED (failures=1)
[Run in 0.3s with exit code 1]
复制代码

四. 报告生成

本文版权归作者和博客园共有,原创作者:http://www.cnblogs.com/BenLam,未经作者同意必须在文章页面给出原文连接。

通过HTMLTestRunner快速生成:

复制代码
import unittest
import HTMLTestRunner
import time

class Test(unittest.TestCase):
    def test_case1(self):
        # 填写你的测试用例

if __name__ == '__main__':
    # 获取当前时间
    now = time.strftime("%Y-%m-%d-%H_%M_%S", time.localtime(time.time()))
    # html存放文件路径
    Report_path = (Report_path, "Report_"+now+".html")
    # 打开一个文件,将result写入此file中
    file = open(Report_path, "wb")
    runner = HTMLTestRunner.HTMLTestRunner(stream=file, title=u'接口测试报告:', description=u'用例执行情况:')
    # 这里填写你的测试用例名
    runner.run(all_case())
    file.close()
复制代码

五. 邮件推送测试报告

本文版权归作者和博客园共有,原创作者:http://www.cnblogs.com/BenLam,未经作者同意必须在文章页面给出原文连接。

通过邮件发送接口测试结果

复制代码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @file       : 邮件.py
# @Date    : 2018-06-02 14:14:46
# @Author  : Destroyers (https://github.com/lguobin)
# @Link    : https://github.com/lguobin
# @Version : $1.0$

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
 
class Myemail:
    def __init__(self,mail_list,mail_title):
        self.mail_list = mail_list
        self.mail_title = mail_title
        self.mail_host = "smtp.163.com"
        self.mail_user = "你自己邮箱@163.com"
        self.mail_pass = "你的密码"
        self.mail_postfix = "163.com"

    def SendMail(self):
        info = self.mail_user + "<" + self.mail_user + "@" + self.mail_postfix + ">"
        msg = MIMEMultipart()
        msg['Subject'] = '接口测试报告'
        msg['From'] = info
        msg['To'] = ";".join(self.mail_list)

        with open("/temp/Report.html", 'r') as f:
            Report_content = f.read().encode("utf-8")
        puretext = MIMEText(Report_content, 'html', 'utf-8')
        msg.attach(puretext)
    try:
        s = smtplib.SMTP() #创建邮件服务器对象
        s.connect(self.mail_host) #连接到指定的smtp服务器。参数分别表示smpt主机和端口
        s.login(self.mail_user, self.mail_pass) #登录到你邮箱
        s.sendmail(me, self.mail_list, msg.as_string()) #发送内容
        s.close()
        return True
    except Exception, e:
        print str(e)
        return False

if __name__ == '__main__':
    # 邮件登录
    mailto_list = ["你领导的邮件@163,com","aaaa@163.com"]
    mail_title = '接口测试报告:'
    test = Myemail(mailto_list, mail_title)
    print(test.SendMail())
复制代码
posted @ 2018-07-23 12:54  旭旭杂货店  阅读(454)  评论(0编辑  收藏  举报