Files
rlz/test_api.py
2026-01-26 15:02:59 +08:00

415 lines
13 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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)