This commit is contained in:
gongwenxin
2025-07-19 08:44:40 +08:00
parent 9a4afa8238
commit fcdfe71646
152 changed files with 598342 additions and 73747 deletions
@@ -0,0 +1,129 @@
from ddms_compliance_suite.test_framework_core import BaseAPITestCase, ValidationResult, APIResponseContext, APIRequestContext, TestSeverity
from typing import Dict, Any, List, Optional
import re
class PaginationParamsCheckTestCase(BaseAPITestCase):
"""
检查API请求中是否包含标准分页参数:pageNo、pageSize和isSearchCount
只有名称含有"查询"一类,并且不含有"详情"一类的API才应用这个验证
"""
id = "TC-DMS-PAGINATION-001"
name = "分页参数检查"
description = "检查API请求参数中是否包含标准分页参数:pageNo、pageSize和isSearchCount。只有名称含有'查询''列表'等并且不含有'详情'一类的API才应用此验证。"
severity = TestSeverity.MEDIUM
tags = ["pagination", "params", "backend-guide"]
# 这个测试用例不需要发送实际请求
skip_execution = True
@classmethod
def applies_to(cls, endpoint_spec: Dict[str, Any], **kwargs) -> bool:
"""
此测试用例仅适用于满足以下条件的端点:
1. 是GET或POST方法。
2. API描述中包含分页相关的关键词(如'查询', '列表')。
3. API描述中不包含排除的关键词(如'详情')。
"""
path = endpoint_spec.get('path', '')
method = endpoint_spec.get('method', '').lower()
if method not in ['get', 'post']:
return False
summary = endpoint_spec.get('summary', '')
description = endpoint_spec.get('description', '')
operation_id = endpoint_spec.get('operationId', '')
include_keywords = ["查询", "列表", "分页", "page", "list", "query", "search", "find"]
exclude_keywords = ["详情", "明细", "detail", "info", "get", "查看"]
api_description_text = f"{summary} {description} {operation_id} {path}".lower()
contains_include_keyword = any(keyword.lower() in api_description_text for keyword in include_keywords)
contains_exclude_keyword = any(keyword.lower() in api_description_text for keyword in exclude_keywords)
return contains_include_keyword and not contains_exclude_keyword
def __init__(self, endpoint_spec: Dict[str, Any], global_api_spec: Dict[str, Any], json_schema_validator: Optional[Any] = None, llm_service: Optional[Any] = None):
super().__init__(endpoint_spec, global_api_spec, json_schema_validator, llm_service=llm_service)
def validate_response(self, response_context: APIResponseContext, request_context: APIRequestContext) -> List[ValidationResult]:
"""
检查API请求中是否包含标准分页参数
"""
results = []
path = self.endpoint_spec.get('path', '')
method = self.endpoint_spec.get('method', '').lower()
# 初始化检查结果
found_page_no = False
found_page_size = False
found_is_search_count = False
# 检查查询参数
parameters = self.endpoint_spec.get('parameters', [])
for param in parameters:
param_name = param.get('name', '')
param_in = param.get('in', '')
if param_in == 'query':
if param_name == 'pageNo':
found_page_no = True
elif param_name == 'pageSize':
found_page_size = True
elif param_name == 'isSearchCount':
found_is_search_count = True
# 检查请求体(如果是POST请求)
if method == 'post':
request_body = self.endpoint_spec.get('requestBody', {})
content = request_body.get('content', {})
for media_type, media_content in content.items():
if 'schema' in media_content:
schema = self._get_resolved_schema(media_content['schema'])
if 'properties' in schema:
properties = schema['properties']
# 检查请求体属性
if 'pageNo' in properties:
found_page_no = True
if 'pageSize' in properties:
found_page_size = True
if 'isSearchCount' in properties:
found_is_search_count = True
# 汇总检查结果
if found_page_no and found_page_size and found_is_search_count:
results.append(self.passed(
message=f"API请求包含所有标准分页参数:pageNo、pageSize和isSearchCount",
details={"path": path, "method": method.upper()}
))
else:
# 计算缺失的参数
missing_params = []
if not found_page_no:
missing_params.append("pageNo")
if not found_page_size:
missing_params.append("pageSize")
if not found_is_search_count:
missing_params.append("isSearchCount")
if missing_params:
results.append(self.failed(
message=f"API请求缺少标准分页参数:{', '.join(missing_params)}",
details={
"path": path,
"method": method.upper(),
"missing_params": missing_params,
"found_params": {
"pageNo": found_page_no,
"pageSize": found_page_size,
"isSearchCount": found_is_search_count
}
}
))
return results