244 lines
6.9 KiB
Python
244 lines
6.9 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
工作手机SDK v3.0 - 完整系统测试
|
||
测试所有接口和设备控制功能
|
||
|
||
运行: python3 tests/test_full_system.py
|
||
(勿用 pytest 收集本文件:需 SDK 与 ADB 在线,由 main() 显式执行)
|
||
"""
|
||
|
||
import os
|
||
import sys
|
||
import time
|
||
|
||
import requests
|
||
|
||
BASE_URL = os.environ.get("SDK_BASE_URL", "http://localhost:8899")
|
||
API_KEY = os.environ.get("SDK_API_KEY", "workphone-secret-key")
|
||
|
||
HEADERS = {
|
||
"Content-Type": "application/json",
|
||
"X-API-Key": API_KEY,
|
||
}
|
||
|
||
passed = 0
|
||
failed = 0
|
||
total = 0
|
||
|
||
|
||
def run_check(name: str, func):
|
||
"""运行单条检查(原 test 名与 pytest 冲突,已改名)"""
|
||
global passed, failed, total
|
||
total += 1
|
||
try:
|
||
result = func()
|
||
if result:
|
||
passed += 1
|
||
print(f" ✅ {name}")
|
||
else:
|
||
failed += 1
|
||
print(f" ❌ {name}")
|
||
except Exception as e:
|
||
failed += 1
|
||
print(f" ❌ {name} - 异常: {e}")
|
||
|
||
|
||
def main() -> int:
|
||
global passed, failed, total
|
||
passed = failed = total = 0
|
||
|
||
print("\n🔧 === 基础接口测试 ===\n")
|
||
|
||
def check_health():
|
||
r = requests.get(f"{BASE_URL}/health", timeout=10)
|
||
d = r.json()
|
||
return d.get("status") == "healthy" and d.get("adb_devices", 0) >= 1
|
||
|
||
def check_root():
|
||
r = requests.get(f"{BASE_URL}/", timeout=10)
|
||
return r.status_code == 200
|
||
|
||
def check_docs():
|
||
r = requests.get(f"{BASE_URL}/docs", timeout=10)
|
||
return r.status_code == 200
|
||
|
||
run_check("健康检查 (/health)", check_health)
|
||
run_check("根路由 (/)", check_root)
|
||
run_check("API文档 (/docs)", check_docs)
|
||
|
||
print("\n📱 === ADB设备控制测试 ===\n")
|
||
|
||
device_serial = None
|
||
|
||
def check_adb_list():
|
||
nonlocal device_serial
|
||
r = requests.get(f"{BASE_URL}/api/v3/adb/devices", timeout=15)
|
||
d = r.json()
|
||
devices = d.get("data", [])
|
||
if devices:
|
||
device_serial = devices[0]["serial"]
|
||
return devices[0]["status"] == "online"
|
||
return False
|
||
|
||
def check_adb_info():
|
||
r = requests.get(
|
||
f"{BASE_URL}/api/v3/adb/devices/{device_serial}", timeout=15
|
||
)
|
||
d = r.json()
|
||
return d.get("code") == 200 and bool(
|
||
d.get("data", {}).get("android_version")
|
||
)
|
||
|
||
def check_adb_screenshot():
|
||
r = requests.post(
|
||
f"{BASE_URL}/api/v3/adb/devices/{device_serial}/screenshot", timeout=30
|
||
)
|
||
d = r.json()
|
||
return d.get("code") == 200 and d.get("data", {}).get("size", 0) > 10000
|
||
|
||
def check_adb_uitree():
|
||
r = requests.get(
|
||
f"{BASE_URL}/api/v3/adb/devices/{device_serial}/ui-tree", timeout=30
|
||
)
|
||
d = r.json()
|
||
return d.get("code") == 200 and d.get("data", {}).get("length", 0) > 100
|
||
|
||
def check_adb_click():
|
||
r = requests.post(
|
||
f"{BASE_URL}/api/v3/adb/devices/{device_serial}/click",
|
||
json={"x": 540, "y": 1200},
|
||
timeout=15,
|
||
)
|
||
return r.json().get("code") == 200
|
||
|
||
def check_adb_swipe():
|
||
r = requests.post(
|
||
f"{BASE_URL}/api/v3/adb/devices/{device_serial}/swipe",
|
||
json={"direction": "up"},
|
||
timeout=15,
|
||
)
|
||
return r.json().get("code") == 200
|
||
|
||
def check_adb_key_home():
|
||
r = requests.post(
|
||
f"{BASE_URL}/api/v3/adb/devices/{device_serial}/key",
|
||
json={"key": "home"},
|
||
timeout=15,
|
||
)
|
||
return r.json().get("code") == 200
|
||
|
||
def check_adb_key_back():
|
||
r = requests.post(
|
||
f"{BASE_URL}/api/v3/adb/devices/{device_serial}/key",
|
||
json={"key": "back"},
|
||
timeout=15,
|
||
)
|
||
return r.json().get("code") == 200
|
||
|
||
def check_adb_current_app():
|
||
r = requests.get(
|
||
f"{BASE_URL}/api/v3/adb/devices/{device_serial}/app/current",
|
||
timeout=15,
|
||
)
|
||
d = r.json()
|
||
return d.get("code") == 200 and d.get("data", {}).get("package")
|
||
|
||
def check_adb_app_list():
|
||
r = requests.get(
|
||
f"{BASE_URL}/api/v3/adb/devices/{device_serial}/app/list", timeout=30
|
||
)
|
||
return r.json().get("code") == 200
|
||
|
||
def check_adb_input():
|
||
r = requests.post(
|
||
f"{BASE_URL}/api/v3/adb/devices/{device_serial}/input",
|
||
json={"text": "test", "clear": True},
|
||
timeout=30,
|
||
)
|
||
return r.json().get("code") == 200
|
||
|
||
def check_adb_click_text():
|
||
try:
|
||
requests.post(
|
||
f"{BASE_URL}/api/v3/adb/devices/{device_serial}/key",
|
||
json={"key": "home"},
|
||
timeout=30,
|
||
)
|
||
except Exception:
|
||
pass
|
||
time.sleep(1)
|
||
r = requests.post(
|
||
f"{BASE_URL}/api/v3/adb/devices/{device_serial}/click-text",
|
||
json={"text": "Chrome"},
|
||
timeout=30,
|
||
)
|
||
d = r.json()
|
||
return d.get("code") in [200, 404]
|
||
|
||
run_check("ADB设备列表", check_adb_list)
|
||
run_check("ADB设备信息", check_adb_info)
|
||
run_check("ADB截图", check_adb_screenshot)
|
||
run_check("ADB获取UI树", check_adb_uitree)
|
||
run_check("ADB点击坐标", check_adb_click)
|
||
run_check("ADB滑动", check_adb_swipe)
|
||
run_check("ADB按Home键", check_adb_key_home)
|
||
run_check("ADB按返回键", check_adb_key_back)
|
||
run_check("ADB获取当前APP", check_adb_current_app)
|
||
run_check("ADB获取APP列表", check_adb_app_list)
|
||
run_check("ADB输入文字", check_adb_input)
|
||
run_check("ADB点击文字", check_adb_click_text)
|
||
|
||
if device_serial:
|
||
try:
|
||
requests.post(
|
||
f"{BASE_URL}/api/v3/adb/devices/{device_serial}/key",
|
||
json={"key": "home"},
|
||
timeout=30,
|
||
)
|
||
except Exception:
|
||
pass
|
||
time.sleep(0.5)
|
||
|
||
print("\n🌐 === 统一API测试 ===\n")
|
||
|
||
def check_unified_send():
|
||
if not device_serial:
|
||
return False
|
||
r = requests.post(
|
||
f"{BASE_URL}/api/v3/message/send",
|
||
json={
|
||
"device_id": device_serial,
|
||
"platform": "wechat",
|
||
"to_id": "测试",
|
||
"content": "测试消息",
|
||
"msg_type": "text",
|
||
},
|
||
timeout=90,
|
||
)
|
||
d = r.json()
|
||
return d.get("code") == 200
|
||
|
||
run_check("统一发送消息", check_unified_send)
|
||
|
||
if device_serial:
|
||
requests.post(
|
||
f"{BASE_URL}/api/v3/adb/devices/{device_serial}/key",
|
||
json={"key": "home"},
|
||
timeout=10,
|
||
)
|
||
|
||
print(f"\n{'='*50}")
|
||
print(f"📊 测试结果: {passed}/{total} 通过, {failed} 失败")
|
||
print(f"{'='*50}")
|
||
|
||
if failed == 0:
|
||
print("🎉 所有测试通过!工作手机SDK完全可用!")
|
||
else:
|
||
print(f"⚠️ 有 {failed} 个测试失败,需要排查")
|
||
|
||
return 0 if failed == 0 else 1
|
||
|
||
|
||
if __name__ == "__main__":
|
||
sys.exit(main())
|