pytest测试框架之HTTP协议接口测试
pytest测试框架之HTTP协议接口测试
接口测试
日常测试中接口测试是一项重要的工作,尤其是HTTP协议的接口测试更加普遍。比如一些常用的测试框架或者工具(RobotFramework框架,TestNG框架,Postman等)都支持HTTP接口的测试,而这节内容主要介绍HTTP接口在pytest框架下的应用。
测试分层
复习下HTTP协议规范
HTTP协议是基于TCP协议(三次握手)的7层协议(不了解的可以搜索下网络协议模型),所以在开始使用工具之前我们通过浏览器的开发者工具看下HTTP请求的基本消息格式。
我们以输入百度网站为例,通过打开开发者工具,看下访问百度的HTTP请求。
通过上面几张图可以看到 HTTP请求的URL为https://www.baidu.com, 请求的method为Get,请求响应的status为200,还包括发送请求的消息头headers信息和响应返回的消息头Headers信息。
做接口测试我们关注的肯定也是上述HTTP请求的内容,通过传入的参数,断言返回的消息响应码/消息体是否满足我们的预期。
安装所需的Python包
在pytest框架下我们主要介绍两个包requests(作为HTTP客户端)和pytest插件pytest-httpserver(作为HTTP的服务端)。
pytest安装
使用pip命令安装: pip install pytest -i https://mirrors.aliyun.com/pypi/simple/
pytest-httpserver安装
使用pip命令安装: pip install pytest-httpserver -i https://mirrors.aliyun.com/pypi/simple/
requests安装
使用pip命令安装: pip3.10 install requests -i
https://mirrors.aliyun.com/pypi/simple/
PS:安装在pytest工程所运行的Python环境,Python的安装目录或者虚拟环境目录,可以参考之前文章查看运行环境PyCharm配置pytest运行环境。
pytest-httpserver插件介绍
官网使用介绍 请参考pytest-httpserver — pytest_httpserver 1.0.12 documentation
pytest-httpserver插件安装后,默认会有一些fixture函数直接使用(fixture函数请参考之前问文章Pytest框架中fixture功能详解)。
在pytest_plugin.py中有fixture函数httpserver,该函数会初始化一个HTTPserver,当然我们也可以直接使用HTTPServer。
启动httpserver需要监听的ip和port ,首先会取os模块配置的环境变量,如下:
listen_host = os.environ.get("PYTEST_HTTPSERVER_HOST")
listen_port = os.environ.get("PYTEST_HTTPSERVER_PORT")
如果环境变量获取为None,则取HTTPserver类的类属性作为默认值:
DEFAULT_LISTEN_HOST = "localhost"
DEFAULT_LISTEN_PORT = 0 # Use ephemeral port
以下是源代码:
如果不想使用默认的ip和端口,我们可以重新设置环境变量的ip地址和端口
import os
import pytest
#设置环境变量
os.environ['PYTEST_HTTPSERVER_HOST'] = '127.0.0.1'
os.environ['PYTEST_HTTPSERVER_PORT'] = '8080'
#获取环境变量值
listen_host = os.environ.get("PYTEST_HTTPSERVER_HOST")
listen_port = os.environ.get("PYTEST_HTTPSERVER_PORT")
#打印
print(listen_host,listen_port)
打印结果:
127.0.0.1 8080
用上面的ip和端口,我们启动一个httpserver:
from pytest_httpserver import *
#初始化类
http_server = HTTPServer(listen_host,listen_port)
#设置url 和 method
http_server.expect_request(
"/index.html", method="get").respond_with_json({"code": "200"})
#启动
http_server.start()
httpserver启动后,我们可以登陆浏览器,访问如下:
以上函数解释:
- expect_request 方法:用于创建HTTP请求地址,设置http的uri地址,或者http的method(GET,POST等),或者http的请求参数(?问号后面的参数),或者http请求响应中返回的json体等
- respond_with_json方法:设置http请求响应的json体,可定义响应码(200等)。
- start方法:启动httpserver。对应的stop方法是关闭httpserver
requests库介绍
requests库是一个简单易用的HTTP库,使用前先导入requests包。
import requests
以下是一些常用函数介绍:
- get方法
requests.get('http://127.0.0.1:8080/index.html',headers={'user-agent': 'my-app/0.0.1'})
其中headers为添加的请求头信息。
- post方法
requests.post('http://127.0.0.1:8080/index.html'', data = {'key':'value'})
其中data为请求body体。
- 处理响应
不管是get还是post方法,我们都可以访问响应对象的属性来获取所需的响应信息,比如:
response.text:获取响应内容的字符串形式。
response.content:获取响应内容的二进制形式。
response.status_code:获取HTTP响应状态码。
response.headers:获取响应头。
response.json():如果响应内容是JSON格式,可以直接调用这个方法来获取JSON数据。
HTTP接口用例
在pytest框架下我们创建测试用例,并校验响应的statuscode和内容。
创建两条用例分别请求httpserver的get和post。
import requests
#使用fixture函数httpserver
def test_1(httpserver):
#通过httpserver这个fixture函数,启动一个server
httpserver.expect_request(
"/service", method="post", json={ "title": "hello pytest"}
).respond_with_json({"code": "200"})
#通过requests库发起http请求
rsp = requests.post("http://127.0.0.1:8080/service", json={ "title": "hello pytest"})
assert rsp.status_code == 200
assert rsp.json() == {"code": "200"}
def test_2(httpserver):
httpserver.expect_request(
"/index.html", method="get").respond_with_json({"code": "200"})
rsp = requests.get(httpserver.url_for("/index.html"))
assert rsp.status_code == 200
assert rsp.json() == {"code": "200"}
以上我们简要介绍了使用Python库requests和pytest插件pytest-httpserver在pytest框架下的HTTP接口用例,大家可以在线下多多实践,当然对于大型的项目,我们还要规划好整个测试用例目录结构。
共勉:东汉·班固《汉书·枚乘传》:“泰山之管穿石,单极之绠断干。水非石之钻,索非木之锯,渐靡使之然也。”
- 指水滴不断地滴,可以滴穿石头;
- 比喻坚持不懈,集细微的力量也能成就难能的功劳。