接口测试
1.接口的概念
- 程序内部的接口:程序内部接口指同一程序或系统内不同模块、组件或类之间的交互点,用于数据传递、功能调用或资源共享
- 系统对外的接口:是不同系统、模块或服务之间进行交互的边界定义,通常通过预定义的协议、数据格式和通信方式实现。它允许外部实体(如用户、其他系统或第三方应用)与系统进行数据交换或功能调用,而无需了解内部实现细节
2.接口测试
接口测试是软件测试的一种类型,专注于验证不同系统、组件或服务之间的交互点(即接口)是否按预期工作。主要检查数据传输、格式、协议以及业务逻辑的正确性,确保系统间通信的可靠性和稳定性。
接口测试重要性
接口就像软件里的 “快递通道”—— 前端、后端、不同系统之间传数据、调功能,都得走这条道。接口测试,就是检查这条 “通道” 通不通、安全不安全、能不能扛住压力。
- 一是防 “钻空子”,前端校验(比如密码长度限制)很容易绕开,接口测试能盯着后端,避免有人直接发恶意请求偷数据、非法登录;
- 二是早排雷,后端接口做好就能测,不用等前端,发现问题早,改起来又快又便宜,总比上线后用户用不了再修强;
- 三是保稳定,比如电商大促时,接口若没测过并发,一多人用就崩,用户付不了款、查不到订单,损失就大了。
因此,接口测试的重要性就体现出来了
如何执行接口测试
通过接⼝设计⽤例
通过性验证
通过性验证确保接口在正常输入条件下正确执行并返回预期结果,是接口测试的基础。
基本功能测试
依据接口文档定义的功能,使用符合要求的输入参数进行测试。例如,获取用户信息的接口传入已知存在的用户ID“12345”,验证返回的用户名、年龄、联系方式等数据是否准确。
验证响应内容时需检查状态码(如200)及响应数据的完整性和准确性。
参数组合
测试接口在不同参数组合下的表现,覆盖参数间的相互影响和边界情况。
参数排列组合
列出所有输入参数及其取值范围,通过笛卡尔积生成组合用例。例如文件上传接口的“文件类型”(.docx、.pdf、.jpg)、“文件大小”(<1MB、1-10MB、>10MB)、“是否加密”(是/否)组合测试。
验证每种组合下接口的行为,如文件上传成功与否、加密设置是否生效。
边界参数组合
关注参数边界值及其组合。例如分页查询接口测试(页码=1,每页数量=1)或(页码=最大值,每页数量=最大值),避免越界错误。
结合业务逻辑测试边界,如订单金额满减优惠的临界值(99元、100元、101元)与其他参数组合,验证优惠计算准确性。
接口安全
发现潜在安全漏洞,保护系统和用户数据。
身份认证与授权
未授权访问测试:不提供认证信息调用接口,验证是否返回401错误。例如直接请求订单详情接口,检查是否拒绝访问。
权限绕过测试:用低权限用户访问高权限接口(如普通用户调用删除接口),验证是否返回403错误。
认证信息过期测试:使用过期令牌调用接口,检查是否返回“令牌过期”提示并阻止访问。
数据安全
敏感数据加密测试:通过抓包工具检查密码等敏感数据是否明文传输,确保接口加密传输且服务器可正确解密。
SQL注入测试:在参数中注入恶意SQL,验证接口是否拒绝执行并返回输入不合法提示。
异常验证
测试接口在异常情况下的处理能力,确保稳定性和健壮性。
输入异常
参数缺失测试:逐一缺失必填参数(如注册接口缺少邮箱),验证是否返回明确错误(如“邮箱不能为空”)。
参数类型错误测试:传入类型不符的参数(如字符串“abc”代替整型年龄),检查是否提示“参数类型错误”。
非法字符测试:输入特殊符号或乱码,验证接口是否拒绝并给出错误提示。
环境异常
网络异常测试:模拟网络延迟或中断,观察接口是否返回超时或连接失败提示,并在恢复后正常工作。
服务器资源不足测试:限制内存/CPU使用率至90%以上,调用接口检查是否返回“服务器繁忙”提示且系统无崩溃。
依赖服务异常测试:停用数据库或第三方服务,验证接口是否返回“服务不可用”提示而非错误数据或崩溃。
结合业务逻辑来设计⽤例
根据自己的系统设计测试用例,依据软件系统所承载的实际业务流程、规则及需求,来构建具有针对性和有效性的测试用例。
接口化自动化测试
接口自动化测试是软件测试中的一种方法,通过自动化脚本模拟客户端与服务器之间的接口交互,验证接口功能、性能和安全性。它能提高测试效率、减少人工错误,并支持持续集成。
接⼝⾃动化流程
1.需求分析
分析请求:深入理解接口的功能、业务规则、输入输出要求等,明确测试范围和重点。比如明确接⼝的URL、请求⽅法(如get、post、PUT、DELETE等)、请求头、请求参 数和请求体等信息。
分析响应:确定接⼝返回的数据格式、状态码以及可能的错误信息。
2.挑选自动化接口
根据项目特点和需求,优先选择稳定性高、变更频率低且业务关键的接口进行自动化。
- 功能复杂度:优先选择功能复杂、逻辑分⽀多的接⼝进⾏⾃动化测试。
- ⾼⻛险功能:选择对业务影响⼤、⻛险⾼的接⼝进⾏⾃动化测试,确保其稳定性和可靠性。
- 重复性⾼:对于需要频繁执⾏的测试任务,如回归测试中的接⼝测试,⾃动化测试可以避免重复⼿ 动测试的繁琐和低效,提⾼测试效率。
3.设计⾃动化测试⽤例
如果在功能测试阶段已经设计了测试⽤例,可以直接拿来使⽤。
如果无则根据接⼝需求和功能,设计正向测试⽤例(正常场景)和反向测试⽤例(异常场景),包括边 界值测试、参数组合测试等。
4.搭建⾃动化测试环境
选择合适的编程语言和开发工具,以及我们的设备的配置和网络环境等
5. 设计⾃动化执⾏框架
设计⼀个框架来执⾏测试⽤例,包括报告⽣成、参数化处理和⽤例执⾏逻辑。
6. 编写代码
根据设计好的测试⽤例和框架,编写⾃动化测试脚本。
7. 执⾏⽤例
使⽤测试框架(如pytest)来执⾏编写的测试⽤例。
8. ⽣成测试报告
测试完成后,⽣成测试报告。可以使⽤pytest --html=report.html
生成 HTML 格式报告
requests模块
Python 的 requests
库是一个简单易用的 HTTP 库,用于发送各种 HTTP 请求(如 GET、POST),并处理响应数据。它简化了网络通信,是 Web 开发、API 调用和数据爬取的常用工具。
1.安装
在python的终端中输入命名行
pip install requests==2.31.0
2.Response 对象提供的属性/⽅法介绍
属性/方法 | 描述 |
---|---|
r.status_code | 响应状态码 |
r.content | 字节方式的响应体,会自动解码gzip和deflate压缩 |
r.headers | 以字典对象存储服务器响应头,若键不存在则返回None |
r.json() | Requests中内置的JSON解析方法,将响应体解析为JSON格式 |
r.url | 获取实际请求的URL |
r.encoding | 编码格式,根据响应头部的字符编码确定 |
r.cookies | 获取服务器设置的cookies |
r.raw | 返回原始响应体,不进行任何处理 |
r.text | 字符串方式的响应体,会自动根据响应头部的字符编码进行解码 |
r.raise_for_status() | 如果请求返回的状态码不是200,抛出HTTPError异常 |
常⻅请求⽅法
requests.get(url, params=None, **kwargs)
: 发送 GET 请求,用于获取数据。requests.post(url, data=None, json=None, **kwargs)
: 发送 POST 请求,用于提交数据。requests.put(url, data=None, **kwargs)
: 发送 PUT 请求,用于更新资源。requests.delete(url, **kwargs)
: 发送 DELETE 请求,用于删除资源。
代码示例
r = requests.get("https://www.baidu.com")
#传递的时候进行参数的指定req_get = requests.request(url="https://www.baidu.com",method="GET")print(r)#打印状态码print(r.status_code)
# 打印响应体字符串格式print(r.text)
添加请求头信息
请求接口常见参数的名称、数据类型和描述:
参数名 | 数据类型/结构 | 描述 |
---|---|---|
url | 字符串 | 请求的目标接口地址 |
headers | 字典 | 包含要发送的HTTP头部信息 |
cookies | 字典/列表/RequestsCookieJar | 包含需要随请求发送的cookies |
files | 字典 | 包含需要上传的文件信息 |
data | 字典/列表/字节串 | 包含请求体数据,用于表单提交或原始数据发送 |
json | 字典 | 自动序列化为JSON格式并作为请求体发送 |
params | 字典/列表/字节串 | 作为查询字符串附加到URL末尾 |
auth | 元组 (用户名, 密码) | 用于HTTP基础认证的凭据 |
timeout | 浮点数/元组 | 请求超时时间设置(单位:秒) |
proxies | 字典 | 配置代理服务器信息(如{'http': 'http://10.10.1.10:3128'} ) |
verify | 布尔值/字符串 | 控制SSL证书验证(True 为默认验证,False 跳过验证,字符串指定CA路径) |
代码示例
需要加什么参数就写什么
# 这里自己找网站尝试
url = "****"data = {"username" : "zhangsan","password" : 123456
}req_post = requests.request(url=url , method= "POST",data=data)print(req_post.json())
⾃动化框架pytest
pytest 是 Python 的⼀个强⼤测试框架,⽀持单元测试、功能测试和 API 测试。它以简洁的语法和丰富的插件系统著称,适合从简单到复杂的测试需求。
安装 pytest
通过 pip 安装 pytest:
pip install pytest
安装后的解释器变化
编写测试用例
- ⽂件名必须以 test_ 开头或者 _test 结尾
- 测试类必须以 Test 开头,并且不能有__init__ ⽅法(初始化方法类似于java中的构造方法)
- 测试⽅法必须以test 开头
class Test():def test01(self):print('the_Test01_test01')def test02(self):print('the_Test01_test02')
当满⾜以上要求后,可通过命令⾏参数pytest 直接运⾏符合条件的⽤例。
pytest命令参数
pytest 常用命令行参数及其功能说明的表格(加粗的为常用):
命令 | 功能描述 | 备注 |
---|---|---|
pytest | 在当前目录及其子目录中搜索并运行测试 | 默认行为 |
pytest -v | 增加输出的详细程度(显示每个测试用例的详细信息) | |
pytest -s | 显示测试中的 print 语句输出(默认被捕获) | |
pytest test_module.py | 运行指定的测试模块 | |
pytest test_dir/ | 运行指定目录下的所有测试 | |
pytest -k <keyword> | 只运行测试名包含指定关键字的测试 | 支持表达式(如 -k "not slow" ) |
pytest -m <marker> | 只运行标记为指定标记的测试(如 @pytest.mark.slow ) | 需预先标记测试 |
pytest -q | 减少输出的详细程度(静默模式) | |
pytest --html=report.html | 生成 HTML 格式的测试报告 | 需安装 pytest-html 插件 |
pytest --cov | 测量测试覆盖率(默认统计当前目录) | 需安装 pytest-cov 插件 |
示例一:运⾏符合运⾏规则的⽤例
pytest
⽰例2:详细打印,并输⼊print内容
pytest -s -v
或者pytest -sv (
可以连写)
⽰例3:指定⽂件/测试⽤例
#指定⽂件:pytest 包名/⽂件名pytest cases/test_01.py#指定测试⽤例: pytest 包名/⽂件名::类名::⽅法名pytest cases/test_01.py::Test::test_a
pytest配置⽂件
创建 pytest.ini ⽂件,该⽂件为pytest 的配置⽂件。
配置选项 | 作用描述 |
---|---|
addopts | 指定在命令行中默认包含的选项(如 -v 或 --tb=native )。 |
testpaths | 指定搜索测试的目录列表(如 tests 或 integration_tests )。 |
python_files | 定义测试模块的文件匹配模式(如 test_*.py 或 *_test.py )。 |
python_classes | 定义测试类的名称前缀或模式(如 Test* 或 *Test )。 |
python_functions | 定义测试函数或方法的名称前缀或模式(如 test_* 或 *_test )。 |
norecursedirs | 指定在搜索测试时应忽略的目录(如 .* 或 node_modules )。 |
markers | 注册自定义标记(如 slow 或 integration ),用于分类测试用例。 |
示例配置
在 pytest.ini
文件中使用上述配置:
[pytest]
addopts = -vs
testpaths = ./cases
python_files = test_*.py
python_classes = Test*
python_functions = test_*
前后置
在测试框架中,前后置是指在执⾏测试⽤例前和测试⽤例后执⾏⼀些额外的操作,这些操作可以⽤于 设置测试环境、准备测试数据等,以确保测试的可靠性
- setup_method 和 teardown_method :这两个⽅法⽤于类中的每个测试⽅法的前置和后置操作。
- setup_class 和 teardown_class :这两个⽅法⽤于整个测试类的前置和后置操作。
- fixture :这是 pytest 推荐的⽅式来实现测试⽤例的前置和后置操作。灵活的控制和更强⼤的功能。
代码示例1
class Test():def setup_method(self):print("setup_method: 准备执行测试方法 ")def teardown_method(self):print("teardown_method: 清理测试方法 ")def test01(self):print('the_Test01_test01')def test02(self):print('the_Test01_test02')
代码示例2
class Test():def setup_class(self):print("setup_method: 准备执行测试方法 ")def teardown_class(self):print("teardown_method: 清理测试方法 ")def test01(self):print('the_Test01_test01')def test02(self):print('the_Test01_test02')
断⾔
断⾔( assert )是⼀种调试辅助⼯具,⽤于检查程序的状态是否符合预期。
assert 条件, 错误信息
代码示例1,基本数据断言
a = 1
b = 1
assert a == ba = 'hello'
b = 'hellw'
assert a == b
代码示例2,列表断言
a = ['a',2,'hello']
b = ['a',3,'hellw']
assert a == b
还有一个函数断言和接口断言就不示例了,懒~
参数化
参数化是一种通过将代码或模型中的固定值替换为变量(参数)来实现灵活性和可复用的技术。
⽰例1:在⽤例上使⽤参数化
import pytest@pytest.mark.parametrize("test_input,expected", [("3+5", 8), ("2+4", 6),("6*9", 42)])def test_eval(test_input, expected):assert eval(test_input) == expected
⽰例2:在类上使⽤参数化
@pytest.mark.parametrize('n,expected', [(1, 2), (3, 4)])
# pytestmark = pytest.mark.parametrize("n,expected", [(1, 2), (3, 4)])
# 全局变量赋值
class TestClass:def test_cases(self,n,expected):assert n + 1 == expecteddef test_cases1(self, n, expected):assert n*1 + 1 == expected
fixture
pytest 中的 fixture 是⼀种强⼤的机制,⽤于提供测试函数所需的资源或上下⽂。它可以⽤于设置测试环境、准备数据等。
fixture标记的⽅法调⽤
@pytest.fixture
def fixture_01():print('这是一个fixture标记的方法')
// 可作为参数使用
def test01(fixture_01):print('这里调用了fixture的方法')
#假设需要登录状态访问其他页的情况下
@pytest.fixture()
def login():print("我登录了")def test_list(login):print('列表页')def test_detail(login):print('详情页')
fixture嵌套
# 创建第一个fixture并返回a
@pytest.fixture
def first_entry():return "a"#创建第二个fixtrue并建立列表
@pytest.fixture
def order(first_entry):return [first_entry]# 添加一个b并加断言观察
def test_string(order):order.append("b")assert order == ["a", "b"]
yield fixture
yield fixture
是一种特殊的装置(fixture)实现方式。它通过 yield
语句将装置分为两部分:设置阶段和清理阶段。装置在 yield
前的代码属于设置逻辑,yield
后的代码属于清理逻辑。
#yield fixture
@pytest.fixture()
def login():print("我登录了")yieldprint('我下线了')def test_list(login):print('列表页')def test_detail(login):print('详情页')
带参数的fixture
scope参数详解
scope参数用于控制fixture的作用范围,决定了fixture的生命周期。可选值包括:
- function(默认):每个测试函数都会调用一次fixture
- class:同一个测试类中共享这个fixture
- module:同一个测试模块中共享这个fixture(一个文件里)
- session:整个测试会话中共享这个fixture
autouse参数
autouse参数默认为False。当设置为True时,每个测试函数都会自动调用该fixture,无需显式传入。
params参数
params参数用于参数化fixture,支持列表传入。每个参数值都会使fixture执行一次,类似于for循环的效果。
ids参数
ids参数需要与params配合使用,为每个参数化实例指定可读的标识符(给参数取名字)。
name参数
name参数用于为fixture显式设置一个名称。如果使用了name来引用,则在测试函数中需要使用这个名称来调用fixture(给fixture取名字)。
@pytest.fixture(scope='class')
def login():print("我登录了")yieldprint('我下线了')
class Testcase:def test_list(self,login):print('列表页')def test_detail(self,login):print('详情页')
通过 params 实现参数化
@pytest.fixture(params=[1, 2, 3])
# request 是 pytest 提供的一个特殊对象,request.param 用于获取当前 fixture 实例化时使用的参数值。
def num(request):return request.paramdef test_square(num):result = num * numassert result >= 0