IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 代码实现接口测试 -> 正文阅读

[网络协议]代码实现接口测试

一、 requests
1 介绍及安装
介绍:基于 python 语言开发的一个开源的库,能够完全满足基于 HTTP 协议的接口测试。

?Requests库是用Python编写的,基于urllib,采用Apache2 Licensed开源协议的HTTP库;

相比urllib库,Requests库更加方便,可以节约我们大量的工作,完全满足HTTP测试需求;

?1.2 安装

pip install requests  安装

 pip show requests  验证
2. 发送请求
常见的 HTTP 请求方式: GET POST PUT DELETE
使用 requests 发送网络请求非常简单,只需要调用HTTP请求类型所对应的方法即可。
发送 get 请求
# 导包
import requests

# 发送请求
response = requests.get("http://www.baidu.com")

# 查看响应
# 查看响应数据编码格式
print("原始的数据编码为:", response.encoding)
print("设置前响应数据:", response.text)

# 设置响应数据编码格式
response.encoding = "utf-8"
print("设置编码后数据编码为:", response.encoding)
print("设置后响应数据:", response.text)
请求方法的返回值 response Response 对象,可以从这个对象中获取响应信息。
比 如:
response.text 可以获取响应的文本内容

?

?3 发送post请求

response = requests.post(url, data=None, json=None)

""" :param url: 请求的URL 

:param data: (可选) 要发送到请求体中的字典、元组、字节或文件对象 

:param json: (可选) 要发送到请求体中的JSON数据 """
data: 参数接收 form 表单数据,后台会?动附加 form 表单请求信息头( data 数据格式为字典)
json: 参数接收 json 数据,后台会?动附加 json 表单请求信息头
headers = {"Content-Type":"application/json"}

?

3.1 提交 form 表单
"""
1. 请求TPshop项目的登录接口,
请求数据(username: 13088888888, password: 123456, verify_code: 1234)
2. 登录接口URL:http://localhost/index.php?m=Home&c=User&a=do_login
"""

# 导包
import requests

# 发请求
login_url = "http://localhost/index.php?m=Home&c=User&a=do_login"
login_data = {
    "username": "13488888888",
    "password": "123456",
    "verify_code": "8888"
}
response = requests.post(url=login_url, data=login_data)

# 看响应
print(response.json())

?3.2 提交json数据

"""
1. 请求IHRM项目的登录接口,请求数据( {"mobile":"13800000002", "password":"123456"} )
2. 登录接口URL:http://ihrm-test.itheima.net/api/sys/login
"""
# 导包
import requests

# 发送请求
login_url = "http://ihrm-test.itheima.net/api/sys/login"
login_data = {
    "mobile": "13800000002",
    "password": "123456"
}
response = requests.post(url=login_url, json=login_data)

# 查看响应
print(response.json())

4 其他请求方式(了解)

put:修改资源

delete:删除资源

head:响应数据中只包含请求头,前提是项目中已实现该功能

options:查看接口支持的请求方法,前提是项目中已实现该功能
import requests 

response = requests.put("http://www.baidu.com", data={"key": "value"}) 
response = requests.delete("http://www.baidu.com") 
response = requests.head("http://www.baidu.com") 
response = requests.options("http://www.baidu.com")
5 传递 URL 参数
如果需要在 URL 的查询字符串中传递数据,可以使用 params 参数来定义, params 传递的参数可以
是字符串或字典。
response = requests.get(url, params=None) 
response = requests.post(url, params=None, data=None)
# 导包
import requests

# 发送请求
# 直接通过url传递参数
# response = requests.get(" http://localhost/Home/Goods/search.html?q=iphone")

#  通过params传递参数:
#  (1)字符串
urlA = "http://localhost/Home/Goods/search.html"
stringA = "q=iphone"
response = requests.get(url=urlA, params=stringA)

#  (2)字典
dictA = {
    "q": "iphone"
}
response = requests.get(url=urlA, params=dictA)
# 查看响应
print(response.text)
6 响应内容解析
用途:断言
实现:
response.status_code :响应状态码
response.url :url地址信息
response.encoding :查看响应数据编码格式
response.headers :查看头部信息
response.cookies : 查看cookies信息
response.text :文本形式查看响应数据
response.content :字节码形式查看响应数据
response.json() :json形式查看响应数据

7 设置请求头

?使用方法: headers={"Content-Type":"application/json"}

思考:发送 HTTP 请求时,传递参数的方式有哪些?
如果需要为请求添加请求头数据,只需要传递一个字典类型的数据给 headers 参数就可以了
"""
1. 请求IHRM项目的登录接口,URL: http://ihrm-test.itheima.net/api/sys/login
2. 请求头: Content-Type: application/json
3. 请求体: {"mobile":"13800000002", "password":"123456"}
"""

import requests
login_url = "http://ihrm-test.itheima.net/api/sys/login"
login_header = {
    "Content-Type": "application/json"
}
login_data ={
    "mobile": "13800000002",
    "password": "123456"
}
# 发送请求
response = requests.post(url=login_url, json=login_data, headers=login_header)

# 查看响应
print(response.json())
8 设置 cookie (了解)
产生及应用

?

获取响应信息中的 cookie 数据:
cookies = response.cookies
发送请求时添加 cookie 数据,可以使用 cookies 参数:
requests.get(url, cookies={"c1": "v1"})

?案例:解决tpshop登录验证码问题

1. 使用requests库调用TPshop登录功能的相关接口,完成登录操作 

2. 登录成功后获取‘我的订单’页面的数据 

接口地址: 

获取验证码:http://localhost/index.php?m=Home&c=User&a=verify 

登录用户:(username: 13088888888, password: 123456, verify_code: 1234) 
登录:http://localhost/index.php?m=Home&c=User&a=do_login 
我的订单:http://localhost/Home/Order/order_list.html

?

import requests 

# 获取验证码 
response = requests.get("http://localhost/index.php?m=Home&c=User&a=verify") print(response.cookies) 
PHPSESSID = response.cookies.get("PHPSESSID") 
print(PHPSESSID) 
# 登录 
login_url = "http://localhost/index.php?m=Home&c=User&a=do_login" 
login_data = {

    "username": "13488888888", 
    "password": "123456", 
    "verify_code": "8888" }
cookies = { "PHPSESSID": PHPSESSID }
response = requests.post(url=login_url, data=login_data, cookies=cookies) 

print(response.json()) 
# 我的订单:http://localhost/Home/Order/order_list.html 
response = requests.get("http://localhost/Home/Order/order_list.html", cookies=cookies) 

print(response.text)
9 设置 session (掌握)
作用:在多个请求之间 存储数据并自动添加数据 ,如 cookies
使用:
实例化: session = requests.Session()
发送请求:
request.get() ==> session.get()
session对象代表一次用户会话:从客户端浏览器连接服务器开始,

到客户端浏览器与服务器断开 会话能让我们在跨请求时候保持某些参数,

比如在同一个 session 实例发出的所有请求之间保持 cookie
创建session对象 
session = requests.Session() 
得到session对象后,就可以调用该对象中的方法来发送请求。
import requests 

# 创建session对象 
session = requests.Session() 

# 获取验证码

response = session.get("http://localhost/index.php?m=Home&c=User&a=verify") 
# 登录 
login_url = "http://localhost/index.php?m=Home&c=User&a=do_login" 
login_data = { 
    "username": "13488888888", 
    "password": "123456", 
    "verify_code": "8888" }
response = session.post(url=login_url, data=login_data) 
print(response.json()) 
# 我的订单:http://localhost/Home/Order/order_list.html 
response = session.get("http://localhost/Home/Order/order_list.html") 
print(response.text)
二、集成 UnitTest
将接口测试脚本集成到UnitTest单元测试框架中,利用UnitTest的功能来运行接口测试用例。
1.1 使用 UnitTest 框架的目的
1. 方便管理和维护多个测试用例
2. 提供丰富的断言方法
3. 能够生成测试报告

案例:使用TPShop项目完成对登录功能的接口测试

?

获取验证码: http://localhost/index.php?m=Home&c=User&a=verify 
登录 : http://localhost/index.php?m=Home&c=User&a=do_login

?实现思路:

?

# 获取验证码: http://localhost/index.php?m=Home&c=User&a=verify
# 登录     : http://localhost/index.php?m=Home&c=User&a=do_login

# 导包
import requests
import unittest


# 创建测试类
class TPShopLogin(unittest.TestCase):
    def setUp(self):
        # 实例化session对象
        self.session = requests.Session()
        # 定义验证接口url地址
        self.url_verify = "http://localhost/index.php?m=Home&c=User&a=verify"
        # 定义正如接口url地址
        self.url_login = "http://localhost/index.php?m=Home&c=User&a=do_login"

    # teardown
    def tearDown(self):
        # 关闭session对象
        self.session.close()

    # 登录成功
    def test01_success(self):
        # 发送验证码请求并断言
        response = self.session.get(url=self.url_verify)
        self.assertEqual(200, response.status_code)
        self.assertIn("image", response.headers.get("Content-Type"))

        # 发登录请求并断言
        login_data = {
            "username": "13488888888",
            "password": "123456",
            "verify_code": "8888"
        }
        response = self.session.post(url=self.url_login, data=login_data)
        print(response.json())
        self.assertEqual(200, response.status_code)
        self.assertEqual(1, response.json().get("status"))
        self.assertIn("登陆成功", response.json().get("msg"))

    # 账号不存在
    def test02_user_is_not_exist(self):
        # 发送验证码请求并断言
        response = self.session.get(url=self.url_verify)
        self.assertEqual(200, response.status_code)
        self.assertIn("image", response.headers.get("Content-Type"))

        # 发登录请求并断言
        login_data = {
            "username": "13488888899",
            "password": "123456",
            "verify_code": "8888"
        }
        response = self.session.post(url=self.url_login, data=login_data)
        print(response.json())
        self.assertEqual(200, response.status_code)
        self.assertEqual(-1, response.json().get("status"))
        self.assertIn("账号不存在", response.json().get("msg"))


    # 密码错误
    def test03_password_error(self):
        # 发送验证码请求并断言
        response = self.session.get(url=self.url_verify)
        self.assertEqual(200, response.status_code)
        self.assertIn("image", response.headers.get("Content-Type"))

        # 发登录请求并断言
        login_data = {
            "username": "13488888888",
            "password": "error",
            "verify_code": "8888"
        }
        response = self.session.post(url=self.url_login, data=login_data)
        print(response.json())
        self.assertEqual(200, response.status_code)
        self.assertEqual(-2, response.json().get("status"))
        self.assertIn("密码错误", response.json().get("msg"))

?生成报告:

# 导包
import time
import unittest
from test10_unittest_tpshop import TPShopLogin
from test12_unittest_params import TPShopLogin2
from tools.HTMLTestRunner import HTMLTestRunner


# 封装测试套件
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TPShopLogin))
suite.addTest(unittest.makeSuite(TPShopLogin2))

# 指定报告路径
report = "./report/report-{}.html".format(time.strftime("%Y%m%d-%H%M%S"))

# 打开文件流
with open(report, "wb") as f:
    # 创建HTMLTestRunner运行器
    runner = HTMLTestRunner(f, title="tpshop接口测试报告")

    # 执行测试套件
    runner.run(suite)
实现参数化:
# 获取验证码: http://localhost/index.php?m=Home&c=User&a=verify
# 登录     : http://localhost/index.php?m=Home&c=User&a=do_login

# 导包
import json

import requests
import unittest
from parameterized import parameterized

# 构造测试数据
def build_data():
    test_data = []
    file = "./data/login.json"
    with open(file, encoding="utf-8") as f:
        json_data = json.load(f)
        for case_data in json_data:
            username = case_data.get("username")
            password = case_data.get("password")
            verify_code = case_data.get("verify_code")
            status_code = case_data.get("status_code")
            status = case_data.get("status")
            msg = case_data.get("msg")
            test_data.append((username, password, verify_code, status_code, status, msg))
    print("test_data=".format(username, password, verify_code, status_code, status, msg))
    return test_data


# 创建测试类
class TPShopLogin2(unittest.TestCase):
    def setUp(self):
        # 实例化session对象
        self.session = requests.Session()
        # 定义验证接口url地址
        self.url_verify = "http://localhost/index.php?m=Home&c=User&a=verify"
        # 定义正如接口url地址
        self.url_login = "http://localhost/index.php?m=Home&c=User&a=do_login"

    # teardown
    def tearDown(self):
        # 关闭session对象
        self.session.close()

    # 登录成功
    @parameterized.expand(build_data())
    def test01_login(self, username, password, verify_code, status_code, status, msg):
        # 发送验证码请求并断言
        response = self.session.get(url=self.url_verify)
        self.assertEqual(200, response.status_code)
        self.assertIn("image", response.headers.get("Content-Type"))

        # 发登录请求并断言
        login_data = {
            "username": username,
            "password": password,
            "verify_code": verify_code
        }
        response = self.session.post(url=self.url_login, data=login_data)
        print(response.json())
        self.assertEqual(status_code, response.status_code)
        self.assertEqual(status, response.json().get("status"))
        self.assertIn(msg, response.json().get("msg"))


一、接口测试框架开发
1 框架结构

?重点说明:

(1)核心在于将测试用例与被测试系统API进行分离,便于后期维护
(2)测试用例是通过unittest进行管理,并提供了丰富的断言(等于、包含等)
(3)可以通过参数化思想测试数据与测试脚本的分离
(4)可以调用数据库进行结果验证或将数据库作为参数化的数据源
(5)借助第三方工具快速的生成HTML报告
接口测试框架的结构说明:
API 用于封装被测系统的接口 
TestCase 将一个或者多个接口封装成测试用例,并使用UnitTest管理测试用例 
TestCase 可以调用数据库进行数据的校验 
为了方便维护测试数据,可以把测试脚本和测试数据分离开 
通过UnitTest断言接口返回的数据,并生成测试报告
2 框架目录结构

?3 封装被测试系统接口

按照功能模块定义封装被测系统的接口,方便测试脚本的调用,并且能够到达代码的复用。
对登录功能的相关接口进行封装,示例代码:
# 封装被测试系统接口 

# 定义接口类 

class LoginAPI: 
# 初始化 
    def __init__(self): 
        self.url_verify = "http://localhost/index.php?m=Home&c=User&a=verify"   
        self.url_login = "http://localhost/index.php?m=Home&c=User&a=do_login" 
# 获取验证码接口 
    def get_verify_code(self, session): 
        return session.get(self.url_verify) 
# 登录接口 
    def login(self, session, username, password, verify_code): 
        login_data = { 
            "username": username, 
            "password": password, 
            "verify_code": verify_code 
            }
        return session.post(url=self.url_login, data=login_data)

4 定义接口测试用例

api 模块中的一个或多个接口封装成一个测试用例,并使用测试框架 UnitTest 管理测试用例。
定义登录功能的测试用例,示例代码:
# 导包 
import requests 
import unittest from api.login 
import LoginAPI 
# 定义测试类 
class TestLoginAPI(unittest.TestCase): 
 前置处理 
    def setUp(self): 
        self.login_api = LoginAPI() 
        self.session = requests.Session() 
# 后置处理 
    def tearDown(self): 
        if self.session: 
            self.session.close() 

# 定义测试方法 

# 登录成功

    def test01_login_success(self): 
# 调用验证码接口 
        response = self.login_api.get_verify_code(self.session) 
# 断言 
        self.assertEqual(200, response.status_code) 
        self.assertIn("image", response.headers.get("Content-Type")) 
# 调用登录接口 
        response = self.login_api.login(self.session, "13488888888", "123456", "8888")
     
        print(response.json()) 
        self.assertEqual(200, response.status_code) 
        self.assertEqual(1, response.json().get("status")) 
        self.assertIn("登陆成功", response.json().get("msg"))

# 账号不正确 
    def test02_user_isnot_exist(self): 
# 调用验证码接口 
        response = self.login_api.get_verify_code(self.session) 
    # 断言 
        self.assertEqual(200, response.status_code) 
        self.assertIn("image", response.headers.get("Content-Type")) 
# 调用登录接口 
        response = self.login_api.login(self.session, "13488888899", "123456", "8888") 

        print(response.json()) 
        self.assertEqual(200, response.status_code) 
        self.assertEqual(-1, response.json().get("status")) 
        self.assertIn("账号不存在", response.json().get("msg")) 

# 密码错误 
    def test03_password_exist(self): 
# 调用验证码接口 
        response = self.login_api.get_verify_code(self.session) 

    # 断言 
        self.assertEqual(200, response.status_code) 
        self.assertIn("image", response.headers.get("Content-Type")) 
# 调用登录接口 
        response = self.login_api.login(self.session, "13488888888", "error", "8888")
        print(response.json()) 
        self.assertEqual(200, response.status_code) 
        self.assertEqual(-2, response.json().get("status")) 
        self.assertIn("密码错误", response.json().get("msg"))

?5 集成测试报告

# 导包 
import time 
import unittest from scripts.test01_login 
import TestLoginAPI from tools.HTMLTestRunner 
import HTMLTestRunner

# 封装测试套件 
suite = unittest.TestSuite() 
suite.addTest(unittest.makeSuite(TestLoginAPI)) 
# 指定报告路径 
report = "./report/report-{}.html".format(time.strftime("%Y%m%d-%H%M%S")) 
# 打开文件流 
with open(report, "wb") as f: 
# 创建HTMLTestRunner执行器 
    runner = HTMLTestRunner(f, title="接口测试报告") 
# 执行测试套件 
    runner.run(suite)
6 测试数据参数化
6.1 基于 json 文件实现参数化
# 导包 
import json 
import requests 
import unittest from api.login 
import LoginAPI from parameterized 
import parameterized 

# 构造测试数据 
def build_data(): 
    json_file = "../data/login.json" 
    test_data = [] 

    with open(json_file, encoding="utf-8") as f: 
        json_data = json.load(f) 
        for case_data in json_data: 
            username = case_data.get("username") 
            password = case_data.get("password") 
            verify_code = case_data.get("verify_code") 
            status_code = case_data.get("status_code") 
            content_type = case_data.get("content_type") 
            status = case_data.get("status") 
            msg = case_data.get("msg") 
    test_data.append((username, 
                        password,
                         verify_code, 
                            status_code, 
                             content_type, 
                                status, msg)) 
    print("test_data = {}".format((username, password, verify_code, status_code, 
    content_type, status, msg))) 
    return test_data 

# 定义测试类 
class TestLoginAPI(unittest.TestCase): 
# 前置处理 
    def setUp(self): 
        self.login_api = LoginAPI() 
        self.session = requests.Session()

# 后置处理 
    def tearDown(self): 
        if self.session: 
            self.session.close() 
# 定义测试方法 
    @parameterized.expand(build_data) 
    def test01_login(self, username, password,
                    verify_code, status_code, content_type, status, msg):
 # 调用验证码接口 
        response = self.login_api.get_verify_code(self.session) 
    # 断言 
        self.assertEqual(status_code, response.status_code) 
        self.assertIn(content_type, response.headers.get("Content-Type")) 
# 调用登录接口 
        response = self.login_api.login(self.session, username, password, verify_code) 

        print(response.json()) 

        self.assertEqual(status_code, response.status_code) 
        self.assertEqual(status, response.json().get("status")) 
        self.assertIn(msg, response.json().get("msg"))
6.2 基于数据库实现参数化
# 1.导包
import requests
import unittest
from api.login import LoginAPI
from tools.dbutil import DBUtil
from parameterized import parameterized

# 构造数据
def build_data():
    # 获取数据库的数据
    sql = "select * from t_login"
    db_data = DBUtil.exe_sql(sql)
    test_data = []
    for case_data in db_data:
        username = case_data[2]
        password = case_data[3]
        verify_code = case_data[4]
        status_code = case_data[5]
        content_type = case_data[6]
        status = case_data[7]
        msg = case_data[8]
        test_data.append((username, password, verify_code, content_type, status_code, status, msg))
        print(test_data)
    return test_data


# 2.创建测试类
class TestLogin(unittest.TestCase):
    # 2.1 前置处理
    def setUp(self):
        self.login_api = LoginAPI()  # 实例化接口类
        self.session = requests.Session()  # 创建session对象

    # 2.2 后置处理
    def tearDown(self):
        if self.session:
            self.session.close()

    @parameterized.expand(build_data())
    # 2.3.创建测试用例
    def test01_login(self, username, password, verify_code, content_type, status_code, status, msg):
        # 调用验证码接口获取验证,并进行断言
        response = self.login_api.get_verify_code(self.session)
        self.assertEqual(status_code, response.status_code)
        self.assertIn(content_type, response.headers.get("Content-Type"))

        # 调用登录接口获取登录信息,并进行断言
        response = self.login_api.login(self.session, username, password, verify_code)
        print(response.json())
        self.assertEqual(status_code, response.status_code)
        self.assertEqual(status, response.json().get("status"))
        self.assertIn(msg, response.json().get("msg"))

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-01-04 13:46:39  更:2022-01-04 13:47:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 12:48:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码