first commit
This commit is contained in:
414
test_api.py
Executable file
414
test_api.py
Executable file
@@ -0,0 +1,414 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
陪诊系统后台API接口测试脚本
|
||||
支持更详细的测试和结果输出
|
||||
"""
|
||||
|
||||
import requests
|
||||
import json
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from typing import Dict, Optional
|
||||
|
||||
# 服务器地址配置
|
||||
# 默认使用公网地址,如果无法访问会自动尝试本地地址
|
||||
SERVER_URL = "http://101.43.95.130:8039"
|
||||
LOCAL_URL = "http://localhost:8039"
|
||||
|
||||
# 测试结果统计
|
||||
class TestResult:
|
||||
def __init__(self):
|
||||
self.total = 0
|
||||
self.passed = 0
|
||||
self.failed = 0
|
||||
self.results = []
|
||||
|
||||
# 颜色输出
|
||||
class Colors:
|
||||
GREEN = '\033[0;32m'
|
||||
RED = '\033[0;31m'
|
||||
YELLOW = '\033[1;33m'
|
||||
BLUE = '\033[0;34m'
|
||||
NC = '\033[0m' # No Color
|
||||
|
||||
def print_colored(text, color=Colors.NC):
|
||||
"""打印带颜色的文本"""
|
||||
print(f"{color}{text}{Colors.NC}")
|
||||
|
||||
def test_api(name: str, method: str, url: str,
|
||||
data: Optional[Dict] = None,
|
||||
headers: Optional[Dict] = None,
|
||||
expected_status: list = [200, 401, 403]) -> tuple:
|
||||
"""
|
||||
测试API接口
|
||||
|
||||
Args:
|
||||
name: 接口名称
|
||||
method: 请求方法 (GET/POST)
|
||||
url: 接口URL
|
||||
data: 请求数据(POST用)
|
||||
headers: 请求头
|
||||
expected_status: 期望的HTTP状态码列表
|
||||
|
||||
Returns:
|
||||
(success: bool, status_code: int, response: dict)
|
||||
"""
|
||||
try:
|
||||
if headers is None:
|
||||
headers = {"Content-Type": "application/json"}
|
||||
|
||||
if method.upper() == "GET":
|
||||
response = requests.get(url, headers=headers, timeout=10)
|
||||
else:
|
||||
response = requests.post(url, json=data, headers=headers, timeout=10)
|
||||
|
||||
status_code = response.status_code
|
||||
success = status_code in expected_status
|
||||
|
||||
# 尝试解析JSON响应
|
||||
try:
|
||||
response_data = response.json()
|
||||
except:
|
||||
response_data = {"raw": response.text[:200]}
|
||||
|
||||
return success, status_code, response_data
|
||||
|
||||
except requests.exceptions.ConnectionError:
|
||||
return False, 0, {"error": "连接失败,无法访问服务器"}
|
||||
except requests.exceptions.Timeout:
|
||||
return False, 0, {"error": "请求超时"}
|
||||
except Exception as e:
|
||||
return False, 0, {"error": str(e)}
|
||||
|
||||
def check_server_available(url):
|
||||
"""检查服务器是否可用"""
|
||||
try:
|
||||
response = requests.get(f"{url}/", timeout=3)
|
||||
return True, response.status_code
|
||||
except:
|
||||
return False, 0
|
||||
|
||||
def run_tests():
|
||||
"""运行所有测试"""
|
||||
result = TestResult()
|
||||
|
||||
# 自动检测可用的服务器地址
|
||||
global SERVER_URL
|
||||
print("正在检测服务器地址...")
|
||||
server_available, status = check_server_available(SERVER_URL)
|
||||
if not server_available:
|
||||
print_colored(f"公网地址 {SERVER_URL} 无法访问,尝试本地地址...", Colors.YELLOW)
|
||||
local_available, _ = check_server_available(LOCAL_URL)
|
||||
if local_available:
|
||||
SERVER_URL = LOCAL_URL
|
||||
print_colored(f"使用本地地址: {SERVER_URL}", Colors.GREEN)
|
||||
else:
|
||||
print_colored("本地地址也无法访问,请检查服务是否运行", Colors.RED)
|
||||
return 1
|
||||
|
||||
print("=" * 60)
|
||||
print_colored("陪诊系统后台API接口测试", Colors.BLUE)
|
||||
print("=" * 60)
|
||||
print(f"服务器地址: {SERVER_URL}")
|
||||
print(f"开始时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
print()
|
||||
|
||||
# 测试用例列表
|
||||
test_cases = [
|
||||
# 基础接口(无需认证)
|
||||
{
|
||||
"name": "首页接口",
|
||||
"method": "GET",
|
||||
"url": f"{SERVER_URL}/",
|
||||
"data": None,
|
||||
"headers": None
|
||||
},
|
||||
{
|
||||
"name": "验证码接口",
|
||||
"method": "GET",
|
||||
"url": f"{SERVER_URL}/captchaImage",
|
||||
"data": None,
|
||||
"headers": None
|
||||
},
|
||||
|
||||
# 登录相关接口
|
||||
{
|
||||
"name": "微信登录接口",
|
||||
"method": "POST",
|
||||
"url": f"{SERVER_URL}/weixinLogin",
|
||||
"data": {
|
||||
"wxcode": "test_code",
|
||||
"encryptedData": "test_data",
|
||||
"iv": "test_iv"
|
||||
},
|
||||
"headers": {"Content-Type": "application/x-www-form-urlencoded"}
|
||||
},
|
||||
{
|
||||
"name": "获取用户Token接口",
|
||||
"method": "GET",
|
||||
"url": f"{SERVER_URL}/getUserToken",
|
||||
"data": {"phonenumber": "13800138000"},
|
||||
"headers": None
|
||||
},
|
||||
|
||||
# 系统配置接口(需要认证)
|
||||
{
|
||||
"name": "价格配置接口",
|
||||
"method": "GET",
|
||||
"url": f"{SERVER_URL}/system/config/configKey/price",
|
||||
"data": None,
|
||||
"headers": {"Authorization": "Bearer test_token"}
|
||||
},
|
||||
{
|
||||
"name": "价格类型配置接口",
|
||||
"method": "GET",
|
||||
"url": f"{SERVER_URL}/system/config/configKey/priceType",
|
||||
"data": None,
|
||||
"headers": {"Authorization": "Bearer test_token"}
|
||||
},
|
||||
|
||||
# 医院相关接口
|
||||
{
|
||||
"name": "医院列表接口",
|
||||
"method": "GET",
|
||||
"url": f"{SERVER_URL}/system/hospital/list",
|
||||
"data": None,
|
||||
"headers": {"Authorization": "Bearer test_token"}
|
||||
},
|
||||
|
||||
# 订单相关接口(需要认证)
|
||||
{
|
||||
"name": "订单列表接口",
|
||||
"method": "GET",
|
||||
"url": f"{SERVER_URL}/system/view/list",
|
||||
"data": None,
|
||||
"headers": {"Authorization": "Bearer test_token"}
|
||||
},
|
||||
{
|
||||
"name": "创建订单接口",
|
||||
"method": "POST",
|
||||
"url": f"{SERVER_URL}/system/order/insertOrderPz",
|
||||
"data": {
|
||||
"bId": 104,
|
||||
"cId": 1,
|
||||
"yuguMoney": "200",
|
||||
"yuliu9": "2",
|
||||
"yuliu10": "1",
|
||||
"hospitalId": 1,
|
||||
"startTime": "2024-01-01",
|
||||
"yuliu11": "13800138000"
|
||||
},
|
||||
"headers": {"Authorization": "Bearer test_token"}
|
||||
},
|
||||
|
||||
# 用户相关接口(需要认证)
|
||||
{
|
||||
"name": "用户列表接口",
|
||||
"method": "GET",
|
||||
"url": f"{SERVER_URL}/system/user/list",
|
||||
"data": None,
|
||||
"headers": {"Authorization": "Bearer test_token"}
|
||||
},
|
||||
{
|
||||
"name": "获取用户信息接口",
|
||||
"method": "GET",
|
||||
"url": f"{SERVER_URL}/getInfo",
|
||||
"data": None,
|
||||
"headers": {"Authorization": "Bearer test_token"}
|
||||
},
|
||||
]
|
||||
|
||||
# 执行测试
|
||||
print("-" * 60)
|
||||
print_colored("1. 基础接口测试(无需认证)", Colors.YELLOW)
|
||||
print("-" * 60)
|
||||
|
||||
for i, test in enumerate(test_cases[:2], 1):
|
||||
result.total += 1
|
||||
print(f"测试 {result.total}: {test['name']} ... ", end="", flush=True)
|
||||
|
||||
success, status_code, response_data = test_api(
|
||||
test['name'],
|
||||
test['method'],
|
||||
test['url'],
|
||||
test['data'],
|
||||
test['headers']
|
||||
)
|
||||
|
||||
if success:
|
||||
result.passed += 1
|
||||
print_colored("✓ 通过", Colors.GREEN)
|
||||
print(f" HTTP状态码: {status_code}")
|
||||
if isinstance(response_data, dict) and 'code' in response_data:
|
||||
print(f" 响应码: {response_data.get('code')}")
|
||||
if 'msg' in response_data:
|
||||
print(f" 消息: {response_data.get('msg')}")
|
||||
else:
|
||||
result.failed += 1
|
||||
print_colored("✗ 失败", Colors.RED)
|
||||
print(f" HTTP状态码: {status_code}")
|
||||
if isinstance(response_data, dict) and 'error' in response_data:
|
||||
print(f" 错误: {response_data.get('error')}")
|
||||
|
||||
result.results.append({
|
||||
"name": test['name'],
|
||||
"success": success,
|
||||
"status_code": status_code,
|
||||
"response": response_data
|
||||
})
|
||||
print()
|
||||
|
||||
print("-" * 60)
|
||||
print_colored("2. 登录相关接口测试", Colors.YELLOW)
|
||||
print("-" * 60)
|
||||
|
||||
for test in test_cases[2:4]:
|
||||
result.total += 1
|
||||
print(f"测试 {result.total}: {test['name']} ... ", end="", flush=True)
|
||||
|
||||
success, status_code, response_data = test_api(
|
||||
test['name'],
|
||||
test['method'],
|
||||
test['url'],
|
||||
test['data'],
|
||||
test['headers']
|
||||
)
|
||||
|
||||
if success:
|
||||
result.passed += 1
|
||||
print_colored("✓ 通过", Colors.GREEN)
|
||||
print(f" HTTP状态码: {status_code}")
|
||||
if isinstance(response_data, dict):
|
||||
if 'code' in response_data:
|
||||
print(f" 响应码: {response_data.get('code')}")
|
||||
if 'msg' in response_data:
|
||||
print(f" 消息: {response_data.get('msg')}")
|
||||
else:
|
||||
result.failed += 1
|
||||
print_colored("✗ 失败", Colors.RED)
|
||||
print(f" HTTP状态码: {status_code}")
|
||||
if isinstance(response_data, dict) and 'error' in response_data:
|
||||
print(f" 错误: {response_data.get('error')}")
|
||||
|
||||
result.results.append({
|
||||
"name": test['name'],
|
||||
"success": success,
|
||||
"status_code": status_code,
|
||||
"response": response_data
|
||||
})
|
||||
print()
|
||||
|
||||
print("-" * 60)
|
||||
print_colored("3. 系统配置接口测试(需要认证)", Colors.YELLOW)
|
||||
print("-" * 60)
|
||||
|
||||
for test in test_cases[4:6]:
|
||||
result.total += 1
|
||||
print(f"测试 {result.total}: {test['name']} ... ", end="", flush=True)
|
||||
|
||||
success, status_code, response_data = test_api(
|
||||
test['name'],
|
||||
test['method'],
|
||||
test['url'],
|
||||
test['data'],
|
||||
test['headers']
|
||||
)
|
||||
|
||||
if success:
|
||||
result.passed += 1
|
||||
print_colored("✓ 通过", Colors.GREEN)
|
||||
print(f" HTTP状态码: {status_code}")
|
||||
if status_code == 401 or status_code == 403:
|
||||
print_colored(" (接口存在,但需要有效Token)", Colors.YELLOW)
|
||||
else:
|
||||
result.failed += 1
|
||||
print_colored("✗ 失败", Colors.RED)
|
||||
print(f" HTTP状态码: {status_code}")
|
||||
|
||||
result.results.append({
|
||||
"name": test['name'],
|
||||
"success": success,
|
||||
"status_code": status_code,
|
||||
"response": response_data
|
||||
})
|
||||
print()
|
||||
|
||||
print("-" * 60)
|
||||
print_colored("4. 业务接口测试(需要认证)", Colors.YELLOW)
|
||||
print("-" * 60)
|
||||
|
||||
for test in test_cases[6:]:
|
||||
result.total += 1
|
||||
print(f"测试 {result.total}: {test['name']} ... ", end="", flush=True)
|
||||
|
||||
success, status_code, response_data = test_api(
|
||||
test['name'],
|
||||
test['method'],
|
||||
test['url'],
|
||||
test['data'],
|
||||
test['headers']
|
||||
)
|
||||
|
||||
if success:
|
||||
result.passed += 1
|
||||
print_colored("✓ 通过", Colors.GREEN)
|
||||
print(f" HTTP状态码: {status_code}")
|
||||
if status_code == 401 or status_code == 403:
|
||||
print_colored(" (接口存在,但需要有效Token)", Colors.YELLOW)
|
||||
else:
|
||||
result.failed += 1
|
||||
print_colored("✗ 失败", Colors.RED)
|
||||
print(f" HTTP状态码: {status_code}")
|
||||
|
||||
result.results.append({
|
||||
"name": test['name'],
|
||||
"success": success,
|
||||
"status_code": status_code,
|
||||
"response": response_data
|
||||
})
|
||||
print()
|
||||
|
||||
# 输出测试结果统计
|
||||
print("=" * 60)
|
||||
print_colored("测试结果统计", Colors.BLUE)
|
||||
print("=" * 60)
|
||||
print(f"总测试数: {result.total}")
|
||||
print_colored(f"通过: {result.passed}", Colors.GREEN)
|
||||
print_colored(f"失败: {result.failed}", Colors.RED)
|
||||
if result.total > 0:
|
||||
pass_rate = (result.passed * 100) // result.total
|
||||
print(f"通过率: {pass_rate}%")
|
||||
print()
|
||||
print(f"结束时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
print()
|
||||
|
||||
# 输出详细结果
|
||||
if result.failed > 0:
|
||||
print_colored("失败的接口详情:", Colors.YELLOW)
|
||||
for r in result.results:
|
||||
if not r['success']:
|
||||
print(f" - {r['name']}: HTTP {r['status_code']}")
|
||||
print()
|
||||
|
||||
# 判断整体结果
|
||||
if result.failed == 0:
|
||||
print_colored("所有接口测试通过!", Colors.GREEN)
|
||||
return 0
|
||||
else:
|
||||
print_colored("部分接口测试失败,请检查服务器状态和网络连接", Colors.YELLOW)
|
||||
print_colored("提示:401/403状态码表示接口存在但需要有效认证", Colors.YELLOW)
|
||||
return 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
exit_code = run_tests()
|
||||
sys.exit(exit_code)
|
||||
except KeyboardInterrupt:
|
||||
print("\n\n测试被用户中断")
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print_colored(f"\n测试过程中发生错误: {str(e)}", Colors.RED)
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
Reference in New Issue
Block a user