如何使用Pytest校验POST接口请求body合法性,让非法参数用例按预期失败
解决方案
核心问题
你当前的测试仅对合法请求的返回状态码做了校验,针对非法参数场景,没有校验接口是否按照预期返回错误状态码(通常为400 Bad Request),因此只要接口返回200,无论参数是否合法测试都会通过。同时原代码存在语法疏漏:json.dumps构造payload时缺少闭合右括号。
具体修改方案
推荐使用pytest参数化功能统一管理所有测试场景,避免重复编码,同时可根据你的需求选择两种校验逻辑:
方案1:校验接口自身的参数校验能力是否生效
即验证非法参数传入时,接口是否会正常拒绝请求,返回400状态码,完整代码如下:
import requests import pytest import json # 定义所有测试用例:(payload字典, 预期状态码, 用例说明) test_cases = [ ({"CategoryId": 1, "CategoryType": "Apple"}, 200, "合法参数请求成功"), ({"CategoryId": "A", "CategoryType": "Cake"}, 400, "CategoryId非整数+CategoryType取值非法"), ({"CategoryType": "Apple"}, 400, "缺失必填字段CategoryId"), ({"CategoryId": "", "CategoryType": "Apple"}, 400, "CategoryId为空值"), ] @pytest.mark.parametrize("payload_dict, expect_status, case_desc", test_cases) def test_category_interface(payload_dict, expect_status, case_desc): url = "https://xxxxx.com/category" payload = json.dumps(payload_dict) headers = { 'Content-Type': 'application/json', 'x-api-key': 'ju876djg3jd8' } response = requests.request("POST", url, headers=headers, data=payload) # 校验状态码符合预期,也可根据接口返回规则补充业务错误码的校验 assert response.status_code == expect_status, f"用例[{case_desc}]失败,预期状态码{expect_status},实际返回{response.status_code}"
方案2:发送请求前先校验本地构造的payload是否符合规范
如果你的需求是先保证自己构造的请求参数符合接口要求再发送,可引入jsonschema库做参数格式校验:
- 先安装依赖:
pip install jsonschema - 代码示例:
import requests import json import pytest from jsonschema import validate, ValidationError # 定义接口参数校验规则 payload_schema = { "type": "object", "properties": { "CategoryId": {"type": "integer"}, "CategoryType": {"enum": ["Apple", "Banana", "Cherry"]} }, "required": ["CategoryId", "CategoryType"] } def test_valid_payload_request(): url = "https://xxxxx.com/category" payload_dict = { "CategoryId": 1, "CategoryType": "Apple" } # 先校验payload格式是否符合要求,不符合会直接抛出ValidationError导致测试失败 try: validate(instance=payload_dict, schema=payload_schema) except ValidationError as e: pytest.fail(f"payload格式不符合规范:{e.message}") payload = json.dumps(payload_dict) headers = { 'Content-Type': 'application/json', 'x-api-key': 'ju876djg3jd8' } response = requests.request("POST", url, headers=headers, data=payload) assert response.status_code == 200
内容的提问来源于stack exchange,提问作者Makiyo
相关产品推荐
相关产品推荐

