Files
ai-web-tester/tests/test_cases.py
empty a67ad26a52
Some checks failed
AI Web Tester CI / test (push) Has been cancelled
feat: 实现AI驱动的Web自动化测试框架
主要功能:
- 纯视觉元素定位 + DOM辅助的混合方案
- 解决 mouse.click() 与 Vue 页面交互问题
- 使用 elementFromPoint + JS click/focus 实现可靠点击
- 智能元素定位: 根据描述生成CSS选择器获取精确坐标
- 区域扫描作为后备定位方案
- 完整的测试报告生成 (HTML+JSON)
- 截图记录每个操作步骤

技术改进:
- controller.py: 改进 click_at 使用 JavaScript 交互
- executor.py: 添加 _find_element_by_description 智能定位
- planner.py: 增强 prompt 传入视口尺寸
- main.py: 获取实际视口大小传给 planner
2025-12-28 15:34:22 +08:00

200 lines
6.4 KiB
Python
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
"""
测试用例模板 - 快速设计和运行多个测试(支持并行执行)
"""
import sys
sys.path.insert(0, ".")
from src import WebTester
from concurrent.futures import ThreadPoolExecutor, as_completed
from typing import List, Dict, Any
import time
# ============================================================
# 测试用例配置
# ============================================================
TEST_CASES = [
{
"name": "Example.com 链接测试",
"url": "http://47.99.105.253:8084",
"goal": "填入账号admin 密码password登录成功",
},
# 添加更多测试用例...
]
# ============================================================
# 测试执行器
# ============================================================
def run_single_case(case: Dict[str, Any], model: str = "claude",
headless: bool = True) -> Dict[str, Any]:
"""运行单个测试用例(独立浏览器实例)"""
name = case.get("name", "Unknown")
url = case["url"]
goal = case["goal"]
result = {
"name": name,
"url": url,
"goal": goal,
"status": "failed",
}
try:
with WebTester(model=model, headless=headless) as tester:
tester.goto(url)
test_result = tester.test(goal)
result["status"] = "passed"
result["steps"] = test_result["steps"]
result["report"] = test_result["report"]
except Exception as e:
result["error"] = str(e)
return result
def run_tests(model: str = "claude", headless: bool = False):
"""串行运行所有测试用例"""
results = []
with WebTester(model=model, headless=headless) as tester:
for i, case in enumerate(TEST_CASES, 1):
name = case.get("name", f"Test {i}")
url = case["url"]
goal = case["goal"]
print(f"\n{'='*60}")
print(f"🧪 [{i}/{len(TEST_CASES)}] {name}")
print(f" URL: {url}")
print(f" Goal: {goal}")
print(f"{'='*60}")
try:
tester.goto(url)
result = tester.test(goal)
# 检查所有步骤是否成功
all_passed = all(r.get("success", False) for r in result.get("results", []))
failed_count = sum(1 for r in result.get("results", []) if not r.get("success", False))
if all_passed:
print(f"✅ 完成: {result['steps']} 步骤")
status = "passed"
else:
print(f"⚠️ 部分失败: {failed_count}/{result['steps']} 步骤失败")
status = "failed"
print(f"📄 报告: {result['report']}")
results.append({
"name": name,
"status": status,
"steps": result["steps"],
"report": result["report"],
})
except Exception as e:
print(f"❌ 失败: {e}")
results.append({
"name": name,
"status": "failed",
"error": str(e),
})
_print_summary(results)
return results
def run_tests_parallel(model: str = "claude", max_workers: int = 3):
"""
并行运行所有测试用例
Args:
model: AI 模型
max_workers: 最大并行数(默认 3
"""
print(f"\n🚀 并行模式启动 (workers={max_workers})")
print(f"📋 待执行测试: {len(TEST_CASES)}\n")
results = []
start_time = time.time()
with ThreadPoolExecutor(max_workers=max_workers) as executor:
# 提交所有任务
future_to_case = {
executor.submit(run_single_case, case, model, True): case
for case in TEST_CASES
}
# 收集结果
for future in as_completed(future_to_case):
case = future_to_case[future]
try:
result = future.result()
status = "" if result["status"] == "passed" else ""
print(f"{status} {result['name']}")
results.append(result)
except Exception as e:
print(f"{case['name']}: {e}")
results.append({
"name": case["name"],
"status": "failed",
"error": str(e),
})
elapsed = time.time() - start_time
print(f"\n⏱️ 总耗时: {elapsed:.1f}")
_print_summary(results)
return results
def _print_summary(results: List[Dict[str, Any]]):
"""打印测试总结"""
print(f"\n{'='*60}")
print("📊 测试总结")
print(f"{'='*60}")
passed = sum(1 for r in results if r["status"] == "passed")
failed = len(results) - passed
print(f"✅ 通过: {passed}")
print(f"❌ 失败: {failed}")
if results:
print(f"📈 通过率: {passed/len(results)*100:.1f}%")
def run_single_test(url: str, goal: str, model: str = "claude"):
"""运行单个测试"""
with WebTester(model=model) as tester:
tester.goto(url)
result = tester.test(goal)
print(f"✅ 完成: {result['steps']} 步骤")
print(f"📄 报告: {result['report']}")
return result
# ============================================================
# 主入口
# ============================================================
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="AI Web Tester - 测试用例运行器")
parser.add_argument("--url", help="单个测试的 URL")
parser.add_argument("--goal", help="单个测试的目标描述")
parser.add_argument("--model", default="claude", choices=["claude", "openai"], help="AI 模型")
parser.add_argument("--headless", action="store_true", help="无头模式运行")
parser.add_argument("--parallel", action="store_true", help="并行执行测试")
parser.add_argument("--workers", type=int, default=3, help="并行工作线程数")
args = parser.parse_args()
if args.url and args.goal:
run_single_test(args.url, args.goal, args.model)
elif args.parallel:
run_tests_parallel(model=args.model, max_workers=args.workers)
else:
run_tests(model=args.model, headless=args.headless)