This commit is contained in:
gongwenxin 2025-06-01 00:38:36 +08:00
parent a4e175bc15
commit b3ac2408be
13 changed files with 5048 additions and 6740 deletions

View File

@ -18,7 +18,7 @@
* 对每一个选定的 API 端点:
* 通过 `TestCaseRegistry` 获取所有适用于该端点的自定义测试用例类。
* 实例化每个测试用例类。
* 调用 `_prepare_initial_request_data` 方法准备初始请求数据(路径参数、查询参数、请求头、请求体)。此方法会根据全局配置和测试用例自身的配置决定是否使用 LLM 进行数据生成,并利用 `LLMService` 和动态 Pydantic 模型创建(`_create_pydantic_model_from_schema`来实现。如果LLM未启用或不适用则使用传统的基于 Schema 的数据生成逻辑(`_generate_params_from_list`, `_generate_data_from_schema`。此阶段还实现了端点级别的LLM参数缓存。
* 调用 `_prepare_initial_request_data` 方法准备初始请求数据(路径参数、查询参数、请求头、请求体)。此方法会根据全局配置和测试用例自身的配置决定是否使用 LLM 进行数据生成,并利用 `LLMService` 和动态 Pydantic 模型创建(`_create_pydantic_model_from_schema`来实现。如果LLM未启用或不适用则使用传统的基于 Schema 的数据生成逻辑(`_generate_params_from_list`, `_generate_parameters_from_schema`。此阶段还实现了端点级别的LLM参数缓存。
* 依次调用测试用例实例中定义的 `generate_*` 方法,允许测试用例修改生成的请求数据。
* 调用测试用例实例中定义的 `validate_request_*` 方法,对即将发送的请求进行预校验。
* 使用 `APICaller` 发送最终构建的 API 请求。
@ -132,7 +132,7 @@
* `validate_response(self, response_context: APIResponseContext, request_context: APIRequestContext) -> List[ValidationResult]`
* 检查状态码、响应头、响应体内容是否符合预期。
* 进行业务逻辑相关的断言。
* **性能检查方法 (可选)**:
* **性能检查方法**:
* `check_performance(self, response_context: APIResponseContext, request_context: APIRequestContext) -> List[ValidationResult]`
* 通常用于检查响应时间 `response_context.elapsed_time`

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@ class StatusCode200Check(BaseAPITestCase):
# applicable_paths_regex = None
execution_order = 1 # 执行顺序
is_critical_setup_test = True
# use_llm_for_body: bool = True
use_llm_for_body: bool = True
# use_llm_for_path_params: bool = True
# use_llm_for_query_params: bool = True
# use_llm_for_headers: bool = True

View File

@ -5,7 +5,6 @@ import json
import logging
import re
from typing import Optional, Dict, Any, List
import requests
from pydantic import BaseModel, Field
from pydantic.json_schema import models_json_schema
@ -59,7 +58,7 @@ class LLMService:
self,
messages: List[Dict[str, str]],
max_tokens: int = 1024,
temperature: float = 0.7,
temperature: float = 0.1,
# TODO: Consider adding a parameter like response_format_type: Optional[str] = None
# if the LLM API supports forcing JSON output (e.g., { "type": "json_object" })
) -> Optional[str]:
@ -114,7 +113,7 @@ class LLMService:
pydantic_model_class: type[BaseModel],
prompt_instruction: Optional[str] = None,
max_tokens: int = 1024,
temperature: float = 0.7
temperature: float = 0.1
) -> Optional[Dict[str, Any]]:
"""
根据给定的Pydantic模型类生成JSON Schema并调用LLM生成符合该Schema的参数字典
@ -178,6 +177,65 @@ class LLMService:
return None
def generate_data_from_schema(
self,
schema_dict: dict,
prompt_instruction: Optional[str] = None,
max_tokens: int = 1024,
temperature: float = 0.1
) -> Optional[Dict[str, Any]]:
"""
根据给定的JSON Schema字典调用LLM生成符合该Schema的数据对象
"""
try:
schema_str = json.dumps(schema_dict, indent=2, ensure_ascii=False)
logger.debug(f"LLMService.generate_data_from_schema: 使用的JSON Schema:\n{schema_str}")
system_prompt = (
"你是一个API测试数据生成助手。你的任务是根据用户提供的JSON Schema和额外指令"
"生成一个符合该Schema的JSON对象。请确保你的输出严格是一个JSON对象"
"不包含任何额外的解释、注释或Markdown标记。"
)
user_prompt_content = f"请为以下JSON Schema生成一个有效的JSON对象实例:\n\n```json\n{schema_str}\n```\n"
if prompt_instruction:
user_prompt_content += f"\n请遵循以下额外指令:\n{prompt_instruction}"
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt_content}
]
assistant_response_content = self._execute_chat_completion_request(
messages=messages,
max_tokens=max_tokens,
temperature=temperature
)
if assistant_response_content:
# 尝试从返回内容中提取JSON部分
json_match = re.search(r'```json\n(.*?)\n```', assistant_response_content, re.DOTALL)
if json_match:
json_str = json_match.group(1)
else:
first_brace = assistant_response_content.find('{')
last_brace = assistant_response_content.rfind('}')
if first_brace != -1 and last_brace != -1 and last_brace > first_brace:
json_str = assistant_response_content[first_brace : last_brace+1]
else:
json_str = assistant_response_content
try:
generated_data = json.loads(json_str)
logger.info("成功从LLM生成并解析了数据。")
return generated_data
except json.JSONDecodeError as e_json:
logger.error(f"无法将LLM响应解析为JSON: {e_json}\n原始响应片段: '{json_str[:500]}'")
else:
logger.warning("从LLM获取的响应内容为空或请求失败。")
except Exception as e:
logger.error(f"执行LLM数据生成时发生未知错误: {e}", exc_info=True)
return None
# --- 示例用法 (用于模块内测试) ---
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG,

View File

@ -1029,85 +1029,117 @@ class APITestOrchestrator:
# 1. 处理路径参数
path_param_specs = [p for p in parameters if p.get('in') == 'path']
for param_spec in path_param_specs:
name = param_spec.get('name')
if not name: continue
if path_param_specs:
should_use_llm = self._should_use_llm_for_param_type("path_params", test_case_instance)
if should_use_llm and self.llm_service:
self.logger.info(f"Attempting LLM generation for path parameter '{name}' in '{operation_id}'")
# generated_value = self.llm_service.generate_data_for_parameter(param_spec, endpoint_spec, "path")
# initial_path_params[name] = generated_value if generated_value is not None else f"llm_placeholder_for_{name}"
initial_path_params[name] = f"llm_path_{name}" # Placeholder
else:
if 'example' in param_spec:
initial_path_params[name] = param_spec['example']
elif param_spec.get('schema') and 'example' in param_spec['schema']:
initial_path_params[name] = param_spec['schema']['example'] # OpenAPI 3.0 `parameter.schema.example`
elif 'default' in param_spec.get('schema', {}):
initial_path_params[name] = param_spec['schema']['default']
elif 'default' in param_spec: # OpenAPI 2.0 `parameter.default`
initial_path_params[name] = param_spec['default']
self.logger.info(f"Attempting LLM generation for path parameters in '{operation_id}'")
path_schema, path_model_name = self._build_object_schema_for_params(path_param_specs, f"{operation_id}_PathParams")
if path_schema:
llm_path_params = self.llm_service.generate_data_from_schema(
path_schema,
prompt_instruction=None,
max_tokens=256,
temperature=0.1
)
if llm_path_params:
initial_path_params = llm_path_params
else:
self.logger.warning(f"LLM failed to generate path params for '{operation_id}', fallback to default.")
else:
schema = param_spec.get('schema', {})
param_type = schema.get('type', 'string')
if param_type == 'integer': initial_path_params[name] = 123
elif param_type == 'number': initial_path_params[name] = 1.23
elif param_type == 'boolean': initial_path_params[name] = True
elif param_type == 'string' and schema.get('format') == 'uuid': initial_path_params[name] = str(UUID(int=0)) # Example UUID
elif param_type == 'string' and schema.get('format') == 'date': initial_path_params[name] = dt.date.today().isoformat()
elif param_type == 'string' and schema.get('format') == 'date-time': initial_path_params[name] = dt.datetime.now().isoformat()
else: initial_path_params[name] = f"param_{name}"
self.logger.debug(f"Initial path param for '{operation_id}': {name} = {initial_path_params.get(name)}")
self.logger.warning(f"Failed to build schema for path params in '{operation_id}', fallback to default.")
if not initial_path_params: # fallback
for param_spec in path_param_specs:
name = param_spec.get('name')
if not name: continue
if 'example' in param_spec:
initial_path_params[name] = param_spec['example']
elif param_spec.get('schema') and 'example' in param_spec['schema']:
initial_path_params[name] = param_spec['schema']['example'] # OpenAPI 3.0 `parameter.schema.example`
elif 'default' in param_spec.get('schema', {}):
initial_path_params[name] = param_spec['schema']['default']
elif 'default' in param_spec: # OpenAPI 2.0 `parameter.default`
initial_path_params[name] = param_spec['default']
else:
schema = param_spec.get('schema', {})
param_type = schema.get('type', 'string')
if param_type == 'integer': initial_path_params[name] = 123
elif param_type == 'number': initial_path_params[name] = 1.23
elif param_type == 'boolean': initial_path_params[name] = True
elif param_type == 'string' and schema.get('format') == 'uuid': initial_path_params[name] = str(UUID(int=0)) # Example UUID
elif param_type == 'string' and schema.get('format') == 'date': initial_path_params[name] = dt.date.today().isoformat()
elif param_type == 'string' and schema.get('format') == 'date-time': initial_path_params[name] = dt.datetime.now().isoformat()
else: initial_path_params[name] = f"param_{name}"
self.logger.debug(f"Initial path param for '{operation_id}': {initial_path_params}")
# 2. 处理查询参数
query_param_specs = [p for p in parameters if p.get('in') == 'query']
for param_spec in query_param_specs:
name = param_spec.get('name')
if not name: continue
if query_param_specs:
should_use_llm = self._should_use_llm_for_param_type("query_params", test_case_instance)
if should_use_llm and self.llm_service:
self.logger.info(f"Attempting LLM generation for query parameter '{name}' in '{operation_id}'")
initial_query_params[name] = f"llm_query_{name}" # Placeholder
else:
if 'example' in param_spec:
initial_query_params[name] = param_spec['example']
elif param_spec.get('schema') and 'example' in param_spec['schema']:
initial_query_params[name] = param_spec['schema']['example']
elif 'default' in param_spec.get('schema', {}):
initial_query_params[name] = param_spec['schema']['default']
elif 'default' in param_spec:
initial_query_params[name] = param_spec['default']
else:
initial_query_params[name] = f"query_val_{name}" # Simplified default
self.logger.debug(f"Initial query param for '{operation_id}': {name} = {initial_query_params.get(name)}")
self.logger.info(f"Attempting LLM generation for query parameters in '{operation_id}'")
query_schema, query_model_name = self._build_object_schema_for_params(query_param_specs, f"{operation_id}_QueryParams")
if query_schema:
llm_query_params = self.llm_service.generate_data_from_schema(
query_schema,
prompt_instruction=None,
max_tokens=512,
temperature=0.1
)
if llm_query_params:
initial_query_params = llm_query_params
else:
self.logger.warning(f"LLM failed to generate query params for '{operation_id}', fallback to default.")
if not initial_query_params: # fallback
for param_spec in query_param_specs:
name = param_spec.get('name')
if not name: continue
if 'example' in param_spec:
initial_query_params[name] = param_spec['example']
elif param_spec.get('schema') and 'example' in param_spec['schema']:
initial_query_params[name] = param_spec['schema']['example']
elif 'default' in param_spec.get('schema', {}):
initial_query_params[name] = param_spec['schema']['default']
elif 'default' in param_spec:
initial_query_params[name] = param_spec['default']
else:
initial_query_params[name] = f"query_val_{name}"
self.logger.debug(f"Initial query param for '{operation_id}': {initial_query_params}")
# 3. 处理请求头参数 (包括规范定义的和标准的 Content-Type/Accept)
header_param_specs = [p for p in parameters if p.get('in') == 'header']
for param_spec in header_param_specs:
name = param_spec.get('name')
if not name: continue
# 标准头 Content-Type 和 Accept 会在后面专门处理
if name.lower() in ['content-type', 'accept', 'authorization']:
self.logger.debug(f"Skipping standard header '{name}' in parameter processing for '{operation_id}'. It will be handled separately.")
continue
custom_header_param_specs = [p for p in header_param_specs if p.get('name', '').lower() not in ['content-type', 'accept', 'authorization']]
if custom_header_param_specs:
should_use_llm = self._should_use_llm_for_param_type("headers", test_case_instance)
if should_use_llm and self.llm_service:
self.logger.info(f"Attempting LLM generation for header '{name}' in '{operation_id}'")
initial_headers[name] = f"llm_header_{name}" # Placeholder
else:
if 'example' in param_spec:
initial_headers[name] = str(param_spec['example'])
elif param_spec.get('schema') and 'example' in param_spec['schema']:
initial_headers[name] = str(param_spec['schema']['example'])
elif 'default' in param_spec.get('schema', {}):
initial_headers[name] = str(param_spec['schema']['default'])
elif 'default' in param_spec:
initial_headers[name] = str(param_spec['default'])
else:
initial_headers[name] = f"header_val_{name}"
self.logger.debug(f"Initial custom header param for '{operation_id}': {name} = {initial_headers.get(name)}")
self.logger.info(f"Attempting LLM generation for header parameters in '{operation_id}'")
header_schema, header_model_name = self._build_object_schema_for_params(custom_header_param_specs, f"{operation_id}_HeaderParams")
if header_schema:
llm_header_params = self.llm_service.generate_data_from_schema(
header_schema,
prompt_instruction=None,
max_tokens=256,
temperature=0.1
)
if llm_header_params:
for k, v in llm_header_params.items():
initial_headers[k] = str(v)
else:
self.logger.warning(f"LLM failed to generate header params for '{operation_id}', fallback to default.")
if not any(k for k in initial_headers if k.lower() not in ['content-type', 'accept', 'authorization']): # fallback
for param_spec in custom_header_param_specs:
name = param_spec.get('name')
if not name: continue
if 'example' in param_spec:
initial_headers[name] = str(param_spec['example'])
elif param_spec.get('schema') and 'example' in param_spec['schema']:
initial_headers[name] = str(param_spec['schema']['example'])
elif 'default' in param_spec.get('schema', {}):
initial_headers[name] = str(param_spec['schema']['default'])
elif 'default' in param_spec:
initial_headers[name] = str(param_spec['default'])
else:
initial_headers[name] = f"header_val_{name}"
self.logger.debug(f"Initial custom header param for '{operation_id}': {initial_headers}")
# 3.1 设置 Content-Type
# 优先从 requestBody.content 获取 (OpenAPI 3.x)
@ -1163,7 +1195,12 @@ class APITestOrchestrator:
should_use_llm_for_body = self._should_use_llm_for_param_type("body", test_case_instance)
if should_use_llm_for_body and self.llm_service:
self.logger.info(f"Attempting LLM generation for request body of '{operation_id}' with schema...")
initial_body = self.llm_service.generate_data_from_schema(request_body_schema, endpoint_spec, "requestBody")
initial_body = self.llm_service.generate_data_from_schema(
request_body_schema,
prompt_instruction=None, # 如有自定义指令可替换
max_tokens=1024,
temperature=0.1
)
if initial_body is None:
self.logger.warning(f"LLM failed to generate request body for '{operation_id}'. Falling back to default schema generator.")
initial_body = self._generate_data_from_schema(request_body_schema, context_name=f"{operation_id}_body", operation_id=operation_id)

5220
log.txt

File diff suppressed because it is too large Load Diff

47
ppt.md Normal file
View File

@ -0,0 +1,47 @@
# BaseAPITestCase 核心方法能力一览
## 1. 生命周期钩子方法(可重写)
| 方法名 | 能力描述 |
| ---------------------------- | ---------------------------------------------------------------- |
| `__init__` | 初始化测试用例,加载接口 schema、参数、上下文等 |
| `generate_path_params` | 生成/修改路径参数(如 `/user/{id}` 中的 `id`),支持动态构造 |
| `generate_query_params` | 生成/修改 query 参数,支持边界值、缺失、类型异常等场景 |
| `generate_headers` | 生成/修改请求头,支持鉴权、格式异常等测试 |
| `generate_request_body` | 生成/修改请求体,支持字段缺失、类型不符等复杂场景 |
| `modify_request_url` | 动态修改请求 URL适用于特殊路径拼接等需求 |
| `validate_request_url` | 请求发送前校验 URL 合规性 |
| `validate_request_headers` | 请求发送前校验头部数据 |
| `validate_request_body` | 请求发送前校验请求体 |
| `validate_response` | 响应校验,断言状态码、响应体、业务逻辑等 |
| `check_performance` | 性能校验,检查响应耗时等 |
## 2. 辅助工具方法(极大简化用例开发)
| 方法名 | 能力描述 |
| ------------------------------------- | ------------------------------------------------------------- |
| `_get_resolved_request_body_schema` | 获取并解析当前接口的请求体 schema自动处理 $ref |
| `_find_removable_field_path` | 查找可被移除的必填字段路径,便于生成“缺失字段”场景 |
| `_remove_value_at_path` | 按路径从数据中移除指定字段,支持嵌套结构 |
| `_find_simple_type_field_in_schema` | 查找 schema 中第一个简单类型字段,便于类型异常测试 |
| `_find_first_simple_type_parameter` | 查找第一个简单类型的参数(如 query/header便于参数异常测试 |
| `_find_required_parameter_name` | 查找第一个必填参数名 |
| `expect_error_response` | 标准化校验错误响应(状态码、错误码等),减少样板代码 |
| `validate_data_against_schema` | 用 schema 校验任意数据结构,便于响应体合规性断言 |
| `passed` / `failed` | 快速生成验证结果对象,便于断言输出 |
## 3. 日志与上下文
| 方法名/属性 | 能力描述 |
| ------------------------ | -------------------------------- |
| `self.logger` | 统一日志输出,便于调试与结果追踪 |
| `self.endpoint_spec` | 当前接口的详细规范,已处理 $ref |
| `self.global_api_spec` | 全局 API 规范,便于跨接口引用 |
---
> **说明**
>
> - 生命周期钩子方法由框架自动调用,用户可按需重写,实现灵活的请求构造与验证。
> - 辅助工具方法极大简化了 schema 处理、字段查找、数据操作等底层细节,让用例开发者专注于业务逻辑。
> - 通过这些方法,测试用例可轻松实现“字段缺失、类型异常、参数边界、响应断言、性能校验”等多种自动化测试能力。

View File

@ -96,7 +96,7 @@
"test_case_name": "Error Code 4001 - Request Body Type Mismatch Validation",
"test_case_severity": "中",
"status": "失败",
"message": "当请求体字段 'isSearchCount' 类型不匹配时期望API返回状态码在 [400, 422] 中,或返回4xx客户端错误且业务码为 '4001'. 实际收到状态码 200. 响应体中的业务码 ('code') 为 '44'.",
"message": "当请求体字段 'isSearchCount' 类型不匹配时期望API返回状态码在 [400, 422] 中,或返回业务码为 '4001'. 实际收到状态码 200. 响应体中的业务码 ('code') 为 '44'.",
"duration_seconds": 0.02025704109109938,
"timestamp": "2025-05-29T16:45:26.000770",
"validation_points": [

897
test_reportllm.json Normal file
View File

@ -0,0 +1,897 @@
{
"summary_metadata": {
"start_time": "2025-06-01T00:34:02.816967",
"end_time": "2025-06-01T00:34:38.063887",
"duration_seconds": "35.25"
},
"endpoint_stats": {
"total_defined": 6,
"total_tested": 6,
"passed": 0,
"failed": 6,
"partial_success": 0,
"error": 0,
"skipped": 0,
"success_rate_percentage": "0.00"
},
"test_case_stats": {
"total_applicable": 42,
"total_executed": 42,
"passed": 24,
"failed": 18,
"error_in_execution": 0,
"skipped_during_endpoint_execution": 0,
"success_rate_percentage": "57.14"
},
"detailed_results": [
{
"endpoint_id": "POST /api/dms/{dms_instance_code}/v1/message/push/{schema}/{version}",
"endpoint_name": "数据推送接口",
"overall_status": "失败",
"duration_seconds": 7.210219,
"start_time": "2025-06-01T00:34:02.817544",
"end_time": "2025-06-01T00:34:10.027763",
"executed_test_cases": [
{
"test_case_id": "TC-STATUS-001",
"test_case_name": "基本状态码 200 检查",
"test_case_severity": "严重",
"status": "通过",
"message": "响应状态码为 200符合预期 200。",
"duration_seconds": 7.01280862512067,
"timestamp": "2025-06-01T00:34:09.830624",
"validation_points": [
{
"passed": true,
"message": "响应状态码为 200符合预期 200。"
}
]
},
{
"test_case_id": "TC-CORE-FUNC-001",
"test_case_name": "Response Body JSON Schema Validation",
"test_case_severity": "严重",
"status": "通过",
"message": "Schema验证步骤完成未发现问题或schema不适用/未为此响应定义)。",
"duration_seconds": 0.04320399998687208,
"timestamp": "2025-06-01T00:34:09.874023",
"validation_points": [
{
"passed": true,
"message": "Schema验证步骤完成未发现问题或schema不适用/未为此响应定义)。"
}
]
},
{
"test_case_id": "TC-SECURITY-001",
"test_case_name": "HTTPS Protocol Mandatory Verification",
"test_case_severity": "严重",
"status": "失败",
"message": "API通过HTTP (http://127.0.0.1:4523/m1/6389742-6086420-default/api/dms/example_dms_instance_code/v1/message/push/example_schema/example_version) 响应了成功的状态码 200这违反了HTTPS强制策略。",
"duration_seconds": 0.03913083393126726,
"timestamp": "2025-06-01T00:34:09.913300",
"validation_points": [
{
"status_code": 200
}
]
},
{
"test_case_id": "TC-ERROR-4001-QUERY",
"test_case_name": "Error Code 4001 - Query Parameter Type Mismatch Validation",
"test_case_severity": "中",
"status": "通过",
"message": "跳过测试:在查询参数中未找到合适的字段来测试类型不匹配。",
"duration_seconds": 0.026711334008723497,
"timestamp": "2025-06-01T00:34:09.940128",
"validation_points": [
{
"passed": true,
"message": "跳过测试:在查询参数中未找到合适的字段来测试类型不匹配。"
}
]
},
{
"test_case_id": "TC-ERROR-4001-BODY",
"test_case_name": "Error Code 4001 - Request Body Type Mismatch Validation",
"test_case_severity": "中",
"status": "失败",
"message": "当请求体字段 'isSearchCount' 类型不匹配时期望API返回状态码在 [400, 422] 中或返回4xx客户端错误且业务码为 '4001'. 实际收到状态码 200. 响应体中的业务码 ('code') 为 '84'.",
"duration_seconds": 0.027765541803091764,
"timestamp": "2025-06-01T00:34:09.967981",
"validation_points": [
{
"status_code": 200,
"response_body": {
"code": 84,
"message": "ea",
"data": {
"total": 90,
"list": [
{
"dsid": "39",
"dataRegion": "Duis nostrud",
"gasReleaseMon": null,
"gasReleaseYear": null,
"releaseGasCum": null
},
{
"dsid": "23",
"dataRegion": "culpa ea enim et non",
"gasReleaseMon": null,
"gasReleaseYear": null,
"releaseGasCum": null
},
{
"dsid": "50",
"dataRegion": "nisi eu nostrud culpa",
"gasReleaseMon": null,
"gasReleaseYear": null,
"releaseGasCum": null
}
]
}
},
"expected_http_status_codes": [
400,
422
],
"expected_business_code": "4001",
"mismatched_field": "body.isSearchCount"
}
]
},
{
"test_case_id": "TC-ERROR-4003-BODY",
"test_case_name": "Error Code 4003 - Missing Required Request Body Field Validation",
"test_case_severity": "高",
"status": "通过",
"message": "跳过测试在API规范中未找到合适的必填请求体字段用于移除测试。",
"duration_seconds": 0.026672749780118465,
"timestamp": "2025-06-01T00:34:09.994986",
"validation_points": [
{
"passed": true,
"message": "跳过测试在API规范中未找到合适的必填请求体字段用于移除测试。"
}
]
},
{
"test_case_id": "TC-ERROR-4003-QUERY",
"test_case_name": "Error Code 4003 - Missing Required Query Parameter Validation",
"test_case_severity": "高",
"status": "通过",
"message": "跳过测试在API规范中未找到合适的必填查询参数用于移除测试。",
"duration_seconds": 0.03259733412414789,
"timestamp": "2025-06-01T00:34:10.027695",
"validation_points": [
{
"passed": true,
"message": "跳过测试在API规范中未找到合适的必填查询参数用于移除测试。"
}
]
}
]
},
{
"endpoint_id": "POST /api/dms/{dms_instance_code}/v1/cd_geo_unit/{version}",
"endpoint_name": "地质单元列表查询",
"overall_status": "失败",
"duration_seconds": 11.292211,
"start_time": "2025-06-01T00:34:10.027830",
"end_time": "2025-06-01T00:34:21.320041",
"executed_test_cases": [
{
"test_case_id": "TC-STATUS-001",
"test_case_name": "基本状态码 200 检查",
"test_case_severity": "严重",
"status": "通过",
"message": "响应状态码为 200符合预期 200。",
"duration_seconds": 11.112421334022656,
"timestamp": "2025-06-01T00:34:21.140621",
"validation_points": [
{
"passed": true,
"message": "响应状态码为 200符合预期 200。"
}
]
},
{
"test_case_id": "TC-CORE-FUNC-001",
"test_case_name": "Response Body JSON Schema Validation",
"test_case_severity": "严重",
"status": "通过",
"message": "Schema验证步骤完成未发现问题或schema不适用/未为此响应定义)。",
"duration_seconds": 0.029472541995346546,
"timestamp": "2025-06-01T00:34:21.170422",
"validation_points": [
{
"passed": true,
"message": "Schema验证步骤完成未发现问题或schema不适用/未为此响应定义)。"
}
]
},
{
"test_case_id": "TC-SECURITY-001",
"test_case_name": "HTTPS Protocol Mandatory Verification",
"test_case_severity": "严重",
"status": "失败",
"message": "API通过HTTP (http://127.0.0.1:4523/m1/6389742-6086420-default/api/dms/example_dms_instance_code/v1/cd_geo_unit/1.0.0) 响应了成功的状态码 200这违反了HTTPS强制策略。",
"duration_seconds": 0.028989958111196756,
"timestamp": "2025-06-01T00:34:21.199627",
"validation_points": [
{
"status_code": 200
}
]
},
{
"test_case_id": "TC-ERROR-4001-QUERY",
"test_case_name": "Error Code 4001 - Query Parameter Type Mismatch Validation",
"test_case_severity": "中",
"status": "失败",
"message": "当查询参数 'pageNo' (路径: 'pageNo') 类型不匹配时期望API返回状态码在 [400, 422] 中或返回4xx客户端错误且业务码为 '4001'. 实际收到状态码 200. 响应体中的业务码 ('code') 为 '61'.",
"duration_seconds": 0.03363720793277025,
"timestamp": "2025-06-01T00:34:21.233641",
"validation_points": [
{
"status_code": 200,
"response_body": {
"code": 61,
"message": "dolore ad magna labore",
"data": {
"total": 17,
"list": [
{
"dsid": "76",
"dataRegion": "commodo dolor pariatur laborum reprehenderit",
"gasReleaseMon": null,
"gasReleaseYear": null,
"releaseGasCum": null
},
{
"dsid": "3",
"dataRegion": "ut commodo in ea enim",
"gasReleaseMon": null,
"gasReleaseYear": null,
"releaseGasCum": null
}
]
}
},
"expected_http_status_codes": [
400,
422
],
"expected_business_code": "4001",
"mismatched_param": "pageNo"
}
]
},
{
"test_case_id": "TC-ERROR-4001-BODY",
"test_case_name": "Error Code 4001 - Request Body Type Mismatch Validation",
"test_case_severity": "中",
"status": "失败",
"message": "当请求体字段 'isSearchCount' 类型不匹配时期望API返回状态码在 [400, 422] 中或返回4xx客户端错误且业务码为 '4001'. 实际收到状态码 200. 响应体中的业务码 ('code') 为 '16'.",
"duration_seconds": 0.029159249970689416,
"timestamp": "2025-06-01T00:34:21.263112",
"validation_points": [
{
"status_code": 200,
"response_body": {
"code": 16,
"message": "nostrud proident enim laborum culpa",
"data": {
"total": 63,
"list": [
{
"dsid": "66",
"dataRegion": "sit ad",
"gasReleaseMon": null,
"gasReleaseYear": null,
"releaseGasCum": null
}
]
}
},
"expected_http_status_codes": [
400,
422
],
"expected_business_code": "4001",
"mismatched_field": "body.isSearchCount"
}
]
},
{
"test_case_id": "TC-ERROR-4003-BODY",
"test_case_name": "Error Code 4003 - Missing Required Request Body Field Validation",
"test_case_severity": "高",
"status": "通过",
"message": "跳过测试在API规范中未找到合适的必填请求体字段用于移除测试。",
"duration_seconds": 0.028349458938464522,
"timestamp": "2025-06-01T00:34:21.291758",
"validation_points": [
{
"passed": true,
"message": "跳过测试在API规范中未找到合适的必填请求体字段用于移除测试。"
}
]
},
{
"test_case_id": "TC-ERROR-4003-QUERY",
"test_case_name": "Error Code 4003 - Missing Required Query Parameter Validation",
"test_case_severity": "高",
"status": "通过",
"message": "跳过测试在API规范中未找到合适的必填查询参数用于移除测试。",
"duration_seconds": 0.02780358400195837,
"timestamp": "2025-06-01T00:34:21.319898",
"validation_points": [
{
"passed": true,
"message": "跳过测试在API规范中未找到合适的必填查询参数用于移除测试。"
}
]
}
]
},
{
"endpoint_id": "PUT /api/dms/{dms_instance_code}/v1/cd_geo_unit",
"endpoint_name": "地质单元数据修改",
"overall_status": "失败",
"duration_seconds": 1.695961,
"start_time": "2025-06-01T00:34:21.320157",
"end_time": "2025-06-01T00:34:23.016118",
"executed_test_cases": [
{
"test_case_id": "TC-STATUS-001",
"test_case_name": "基本状态码 200 检查",
"test_case_severity": "严重",
"status": "通过",
"message": "响应状态码为 200符合预期 200。",
"duration_seconds": 1.529003000119701,
"timestamp": "2025-06-01T00:34:22.849539",
"validation_points": [
{
"passed": true,
"message": "响应状态码为 200符合预期 200。"
}
]
},
{
"test_case_id": "TC-CORE-FUNC-001",
"test_case_name": "Response Body JSON Schema Validation",
"test_case_severity": "严重",
"status": "通过",
"message": "针对 PUT http://127.0.0.1:4523/m1/6389742-6086420-default/api/dms/example_dms_instance_code/v1/cd_geo_unit (状态码 200) 的响应体 conforms to the JSON schema.",
"duration_seconds": 0.030560707906261086,
"timestamp": "2025-06-01T00:34:22.880198",
"validation_points": [
{
"passed": true,
"message": "针对 PUT http://127.0.0.1:4523/m1/6389742-6086420-default/api/dms/example_dms_instance_code/v1/cd_geo_unit (状态码 200) 的响应体 conforms to the JSON schema."
}
]
},
{
"test_case_id": "TC-SECURITY-001",
"test_case_name": "HTTPS Protocol Mandatory Verification",
"test_case_severity": "严重",
"status": "失败",
"message": "API通过HTTP (http://127.0.0.1:4523/m1/6389742-6086420-default/api/dms/example_dms_instance_code/v1/cd_geo_unit) 响应了成功的状态码 200这违反了HTTPS强制策略。",
"duration_seconds": 0.025434250012040138,
"timestamp": "2025-06-01T00:34:22.905808",
"validation_points": [
{
"status_code": 200
}
]
},
{
"test_case_id": "TC-ERROR-4001-QUERY",
"test_case_name": "Error Code 4001 - Query Parameter Type Mismatch Validation",
"test_case_severity": "中",
"status": "失败",
"message": "当查询参数 'id' (路径: 'id') 类型不匹配时期望API返回状态码在 [400, 422] 中或返回4xx客户端错误且业务码为 '4001'. 实际收到状态码 200. 响应体中的业务码 ('code') 为 '50'.",
"duration_seconds": 0.02286758297123015,
"timestamp": "2025-06-01T00:34:22.928771",
"validation_points": [
{
"status_code": 200,
"response_body": {
"code": 50,
"message": "nulla dolore cillum",
"data": false
},
"expected_http_status_codes": [
400,
422
],
"expected_business_code": "4001",
"mismatched_param": "id"
}
]
},
{
"test_case_id": "TC-ERROR-4001-BODY",
"test_case_name": "Error Code 4001 - Request Body Type Mismatch Validation",
"test_case_severity": "中",
"status": "失败",
"message": "当请求体字段 'id' 类型不匹配时期望API返回状态码在 [400, 422] 中或返回4xx客户端错误且业务码为 '4001'. 实际收到状态码 200. 响应体中的业务码 ('code') 为 '17'.",
"duration_seconds": 0.031667542178183794,
"timestamp": "2025-06-01T00:34:22.960534",
"validation_points": [
{
"status_code": 200,
"response_body": {
"code": 17,
"message": "in",
"data": false
},
"expected_http_status_codes": [
400,
422
],
"expected_business_code": "4001",
"mismatched_field": "body.id"
}
]
},
{
"test_case_id": "TC-ERROR-4003-BODY",
"test_case_name": "Error Code 4003 - Missing Required Request Body Field Validation",
"test_case_severity": "高",
"status": "通过",
"message": "当移除必填请求体字段 'id' 时API响应了状态码 200 (非主要预期HTTP状态 [400, 422]但为4xx客户端错误), 且响应体中包含预期的业务错误码 '4003' (字段: 'code').",
"duration_seconds": 0.024940666975453496,
"timestamp": "2025-06-01T00:34:22.985617",
"validation_points": [
{
"passed": true,
"message": "当移除必填请求体字段 'id' 时API响应了状态码 200 (非主要预期HTTP状态 [400, 422]但为4xx客户端错误), 且响应体中包含预期的业务错误码 '4003' (字段: 'code')."
}
]
},
{
"test_case_id": "TC-ERROR-4003-QUERY",
"test_case_name": "Error Code 4003 - Missing Required Query Parameter Validation",
"test_case_severity": "高",
"status": "失败",
"message": "当移除必填查询参数 'id' 时期望API返回状态码在 [400, 422] 中或返回4xx客户端错误且业务码为 '4003'. 实际收到状态码 200. 响应体中的业务码 ('code') 为 '47'.",
"duration_seconds": 0.030161542119458318,
"timestamp": "2025-06-01T00:34:23.015963",
"validation_points": [
{
"status_code": 200,
"response_body": {
"code": 47,
"message": "irure laborum",
"data": false
},
"expected_http_status_codes": [
400,
422
],
"expected_business_code": "4003",
"removed_param": "query.id"
}
]
}
]
},
{
"endpoint_id": "DELETE /api/dms/{dms_instance_code}/v1/cd_geo_unit",
"endpoint_name": "地质单元数据删除",
"overall_status": "失败",
"duration_seconds": 1.609212,
"start_time": "2025-06-01T00:34:23.016230",
"end_time": "2025-06-01T00:34:24.625442",
"executed_test_cases": [
{
"test_case_id": "TC-STATUS-001",
"test_case_name": "基本状态码 200 检查",
"test_case_severity": "严重",
"status": "通过",
"message": "响应状态码为 200符合预期 200。",
"duration_seconds": 1.438529249979183,
"timestamp": "2025-06-01T00:34:24.455129",
"validation_points": [
{
"passed": true,
"message": "响应状态码为 200符合预期 200。"
}
]
},
{
"test_case_id": "TC-CORE-FUNC-001",
"test_case_name": "Response Body JSON Schema Validation",
"test_case_severity": "严重",
"status": "通过",
"message": "针对 DELETE http://127.0.0.1:4523/m1/6389742-6086420-default/api/dms/example_dms_instance_code/v1/cd_geo_unit (状态码 200) 的响应体 conforms to the JSON schema.",
"duration_seconds": 0.029119000071659684,
"timestamp": "2025-06-01T00:34:24.484468",
"validation_points": [
{
"passed": true,
"message": "针对 DELETE http://127.0.0.1:4523/m1/6389742-6086420-default/api/dms/example_dms_instance_code/v1/cd_geo_unit (状态码 200) 的响应体 conforms to the JSON schema."
}
]
},
{
"test_case_id": "TC-SECURITY-001",
"test_case_name": "HTTPS Protocol Mandatory Verification",
"test_case_severity": "严重",
"status": "失败",
"message": "API通过HTTP (http://127.0.0.1:4523/m1/6389742-6086420-default/api/dms/example_dms_instance_code/v1/cd_geo_unit) 响应了成功的状态码 200这违反了HTTPS强制策略。",
"duration_seconds": 0.0279640001244843,
"timestamp": "2025-06-01T00:34:24.512658",
"validation_points": [
{
"status_code": 200
}
]
},
{
"test_case_id": "TC-ERROR-4001-QUERY",
"test_case_name": "Error Code 4001 - Query Parameter Type Mismatch Validation",
"test_case_severity": "中",
"status": "失败",
"message": "当查询参数 'id' (路径: 'id') 类型不匹配时期望API返回状态码在 [400, 422] 中或返回4xx客户端错误且业务码为 '4001'. 实际收到状态码 200. 响应体中的业务码 ('code') 为 '26'.",
"duration_seconds": 0.02449787501245737,
"timestamp": "2025-06-01T00:34:24.537289",
"validation_points": [
{
"status_code": 200,
"response_body": {
"code": 26,
"message": "mollit Duis",
"data": true
},
"expected_http_status_codes": [
400,
422
],
"expected_business_code": "4001",
"mismatched_param": "id"
}
]
},
{
"test_case_id": "TC-ERROR-4001-BODY",
"test_case_name": "Error Code 4001 - Request Body Type Mismatch Validation",
"test_case_severity": "中",
"status": "失败",
"message": "当请求体字段 'version' 类型不匹配时期望API返回状态码在 [400, 422] 中或返回4xx客户端错误且业务码为 '4001'. 实际收到状态码 200. 响应体中的业务码 ('code') 为 '63'.",
"duration_seconds": 0.02469349978491664,
"timestamp": "2025-06-01T00:34:24.562116",
"validation_points": [
{
"status_code": 200,
"response_body": {
"code": 63,
"message": "fugiat eu tempor",
"data": false
},
"expected_http_status_codes": [
400,
422
],
"expected_business_code": "4001",
"mismatched_field": "body.version"
}
]
},
{
"test_case_id": "TC-ERROR-4003-BODY",
"test_case_name": "Error Code 4003 - Missing Required Request Body Field Validation",
"test_case_severity": "高",
"status": "通过",
"message": "跳过测试在API规范中未找到合适的必填请求体字段用于移除测试。",
"duration_seconds": 0.025086957961320877,
"timestamp": "2025-06-01T00:34:24.587350",
"validation_points": [
{
"passed": true,
"message": "跳过测试在API规范中未找到合适的必填请求体字段用于移除测试。"
}
]
},
{
"test_case_id": "TC-ERROR-4003-QUERY",
"test_case_name": "Error Code 4003 - Missing Required Query Parameter Validation",
"test_case_severity": "高",
"status": "失败",
"message": "当移除必填查询参数 'id' 时期望API返回状态码在 [400, 422] 中或返回4xx客户端错误且业务码为 '4003'. 实际收到状态码 200. 响应体中的业务码 ('code') 为 '73'.",
"duration_seconds": 0.037851457949727774,
"timestamp": "2025-06-01T00:34:24.625365",
"validation_points": [
{
"status_code": 200,
"response_body": {
"code": 73,
"message": "ullamco occaecat sit cupidatat Excepteur",
"data": true
},
"expected_http_status_codes": [
400,
422
],
"expected_business_code": "4003",
"removed_param": "query.id"
}
]
}
]
},
{
"endpoint_id": "POST /api/dms/{dms_instance_code}/v1/cd_geo_unit",
"endpoint_name": "地质单元数据添加",
"overall_status": "失败",
"duration_seconds": 5.622572,
"start_time": "2025-06-01T00:34:24.625494",
"end_time": "2025-06-01T00:34:30.248066",
"executed_test_cases": [
{
"test_case_id": "TC-STATUS-001",
"test_case_name": "基本状态码 200 检查",
"test_case_severity": "严重",
"status": "通过",
"message": "响应状态码为 200符合预期 200。",
"duration_seconds": 5.46320699993521,
"timestamp": "2025-06-01T00:34:30.090080",
"validation_points": [
{
"passed": true,
"message": "响应状态码为 200符合预期 200。"
}
]
},
{
"test_case_id": "TC-CORE-FUNC-001",
"test_case_name": "Response Body JSON Schema Validation",
"test_case_severity": "严重",
"status": "通过",
"message": "Schema验证步骤完成未发现问题或schema不适用/未为此响应定义)。",
"duration_seconds": 0.02542745810933411,
"timestamp": "2025-06-01T00:34:30.115690",
"validation_points": [
{
"passed": true,
"message": "Schema验证步骤完成未发现问题或schema不适用/未为此响应定义)。"
}
]
},
{
"test_case_id": "TC-SECURITY-001",
"test_case_name": "HTTPS Protocol Mandatory Verification",
"test_case_severity": "严重",
"status": "失败",
"message": "API通过HTTP (http://127.0.0.1:4523/m1/6389742-6086420-default/api/dms/example_dms_instance_code/v1/cd_geo_unit) 响应了成功的状态码 200这违反了HTTPS强制策略。",
"duration_seconds": 0.023582458030432463,
"timestamp": "2025-06-01T00:34:30.139370",
"validation_points": [
{
"status_code": 200
}
]
},
{
"test_case_id": "TC-ERROR-4001-QUERY",
"test_case_name": "Error Code 4001 - Query Parameter Type Mismatch Validation",
"test_case_severity": "中",
"status": "通过",
"message": "跳过测试:在查询参数中未找到合适的字段来测试类型不匹配。",
"duration_seconds": 0.02305808407254517,
"timestamp": "2025-06-01T00:34:30.162526",
"validation_points": [
{
"passed": true,
"message": "跳过测试:在查询参数中未找到合适的字段来测试类型不匹配。"
}
]
},
{
"test_case_id": "TC-ERROR-4001-BODY",
"test_case_name": "Error Code 4001 - Request Body Type Mismatch Validation",
"test_case_severity": "中",
"status": "失败",
"message": "当请求体字段 'version' 类型不匹配时期望API返回状态码在 [400, 422] 中或返回4xx客户端错误且业务码为 '4001'. 实际收到状态码 200. 响应体中的业务码 ('code') 为 '100'.",
"duration_seconds": 0.02860183292068541,
"timestamp": "2025-06-01T00:34:30.191222",
"validation_points": [
{
"status_code": 200,
"response_body": {
"code": 100,
"message": "ullamco sunt Duis",
"data": false
},
"expected_http_status_codes": [
400,
422
],
"expected_business_code": "4001",
"mismatched_field": "body.version"
}
]
},
{
"test_case_id": "TC-ERROR-4003-BODY",
"test_case_name": "Error Code 4003 - Missing Required Request Body Field Validation",
"test_case_severity": "高",
"status": "失败",
"message": "当移除必填请求体字段 'data.0.bsflag' 时期望API返回状态码在 [400, 422] 中或返回4xx客户端错误且业务码为 '4003'. 实际收到状态码 200. 响应体中的业务码 ('code') 为 '24'.",
"duration_seconds": 0.030035334173589945,
"timestamp": "2025-06-01T00:34:30.221409",
"validation_points": [
{
"status_code": 200,
"response_body": {
"code": 24,
"message": "tempor exercitation occaecat laboris ea",
"data": false
},
"expected_http_status_codes": [
400,
422
],
"expected_business_code": "4003",
"removed_field": "body.data.0.bsflag"
}
]
},
{
"test_case_id": "TC-ERROR-4003-QUERY",
"test_case_name": "Error Code 4003 - Missing Required Query Parameter Validation",
"test_case_severity": "高",
"status": "通过",
"message": "跳过测试在API规范中未找到合适的必填查询参数用于移除测试。",
"duration_seconds": 0.026296500116586685,
"timestamp": "2025-06-01T00:34:30.247916",
"validation_points": [
{
"passed": true,
"message": "跳过测试在API规范中未找到合适的必填查询参数用于移除测试。"
}
]
}
]
},
{
"endpoint_id": "GET /api/dms/{dms_instance_code}/v1/cd_geo_unit/{version}/{id}",
"endpoint_name": "地质单元查询详情",
"overall_status": "失败",
"duration_seconds": 7.815613,
"start_time": "2025-06-01T00:34:30.248238",
"end_time": "2025-06-01T00:34:38.063851",
"executed_test_cases": [
{
"test_case_id": "TC-STATUS-001",
"test_case_name": "基本状态码 200 检查",
"test_case_severity": "严重",
"status": "通过",
"message": "响应状态码为 200符合预期 200。",
"duration_seconds": 7.642308250069618,
"timestamp": "2025-06-01T00:34:37.891148",
"validation_points": [
{
"passed": true,
"message": "响应状态码为 200符合预期 200。"
}
]
},
{
"test_case_id": "TC-CORE-FUNC-001",
"test_case_name": "Response Body JSON Schema Validation",
"test_case_severity": "严重",
"status": "通过",
"message": "针对 GET http://127.0.0.1:4523/m1/6389742-6086420-default/api/dms/example_dms_instance_code/v1/cd_geo_unit/1.0.0/example_id (状态码 200) 的响应体 conforms to the JSON schema.",
"duration_seconds": 0.025693500181660056,
"timestamp": "2025-06-01T00:34:37.916967",
"validation_points": [
{
"passed": true,
"message": "针对 GET http://127.0.0.1:4523/m1/6389742-6086420-default/api/dms/example_dms_instance_code/v1/cd_geo_unit/1.0.0/example_id (状态码 200) 的响应体 conforms to the JSON schema."
}
]
},
{
"test_case_id": "TC-SECURITY-001",
"test_case_name": "HTTPS Protocol Mandatory Verification",
"test_case_severity": "严重",
"status": "失败",
"message": "API通过HTTP (http://127.0.0.1:4523/m1/6389742-6086420-default/api/dms/example_dms_instance_code/v1/cd_geo_unit/1.0.0/example_id) 响应了成功的状态码 200这违反了HTTPS强制策略。",
"duration_seconds": 0.027092833071947098,
"timestamp": "2025-06-01T00:34:37.944155",
"validation_points": [
{
"status_code": 200
}
]
},
{
"test_case_id": "TC-ERROR-4001-QUERY",
"test_case_name": "Error Code 4001 - Query Parameter Type Mismatch Validation",
"test_case_severity": "中",
"status": "通过",
"message": "跳过测试:在查询参数中未找到合适的字段来测试类型不匹配。",
"duration_seconds": 0.03259037504903972,
"timestamp": "2025-06-01T00:34:37.976836",
"validation_points": [
{
"passed": true,
"message": "跳过测试:在查询参数中未找到合适的字段来测试类型不匹配。"
}
]
},
{
"test_case_id": "TC-ERROR-4001-BODY",
"test_case_name": "Error Code 4001 - Request Body Type Mismatch Validation",
"test_case_severity": "中",
"status": "失败",
"message": "当请求体字段 'isSearchCount' 类型不匹配时期望API返回状态码在 [400, 422] 中或返回4xx客户端错误且业务码为 '4001'. 实际收到状态码 200. 响应体中的业务码 ('code') 为 '82'.",
"duration_seconds": 0.035141333006322384,
"timestamp": "2025-06-01T00:34:38.012121",
"validation_points": [
{
"status_code": 200,
"response_body": {
"code": 82,
"message": "id ipsum tempor",
"data": {
"total": 63,
"list": [
{
"dsid": "28",
"dataRegion": "est id culpa dolore consequat",
"gasReleaseMon": null,
"gasReleaseYear": null,
"releaseGasCum": null
}
]
}
},
"expected_http_status_codes": [
400,
422
],
"expected_business_code": "4001",
"mismatched_field": "body.isSearchCount"
}
]
},
{
"test_case_id": "TC-ERROR-4003-BODY",
"test_case_name": "Error Code 4003 - Missing Required Request Body Field Validation",
"test_case_severity": "高",
"status": "通过",
"message": "跳过测试在API规范中未找到合适的必填请求体字段用于移除测试。",
"duration_seconds": 0.0262297501321882,
"timestamp": "2025-06-01T00:34:38.038437",
"validation_points": [
{
"passed": true,
"message": "跳过测试在API规范中未找到合适的必填请求体字段用于移除测试。"
}
]
},
{
"test_case_id": "TC-ERROR-4003-QUERY",
"test_case_name": "Error Code 4003 - Missing Required Query Parameter Validation",
"test_case_severity": "高",
"status": "通过",
"message": "跳过测试在API规范中未找到合适的必填查询参数用于移除测试。",
"duration_seconds": 0.02522541698999703,
"timestamp": "2025-06-01T00:34:38.063766",
"validation_points": [
{
"passed": true,
"message": "跳过测试在API规范中未找到合适的必填查询参数用于移除测试。"
}
]
}
]
}
]
}