# Pipeline kiểm thử tự sửa chữa Bộ kiểm thử truyền thống bị hỏng khi UI thay đổi. Kiểm thử tự sửa chữa sử dụng bộ nhớ Synapse để học từ lỗi quá khứ và thích ứng — giảm kiểm thử flaky và gánh nặng bảo trì. ## Khái niệm ``` ┌─────────┐ fails ┌──────────┐ store ┌──────────┐ │ Test │ ───────▶ │ Synapse │ ───────▶ │ Memories │ │ Run │ │ Memory │ │ (failures)│ └─────────┘ └──────────┘ └──────────┘ ▲ │ │ recall │ │ before next run │ └─────────────────────┘ ``` 1. Kiểm thử chạy 2. Nếu thất bại, lưu lỗi (cái gì sai, tại sao, cách sửa) 3. Lần chạy tiếp: thu hồi lỗi liên quan trước khi thực thi 4. Áp dụng sửa chữa đã biết tự động ## Triển khai ### Bước 1: Wrapper kiểm thử Bọc mỗi kiểm thử với thu hồi/lưu bộ nhớ: ```python import requests from datetime import datetime URL = "https://synapse.schaefer.zone" MIND_KEY = "mk_..." def self_healing_test(test_name, test_fn): """Decorator: wrap a test with self-healing memory.""" def wrapper(): # 1. Recall past failures for this test past_failures = requests.get( f"{URL}/memory/search?q={test_name}+failure", headers={"Authorization": f"Bearer {MIND_KEY}"} ).json() # 2. Run test with failure context try: test_fn(known_failures=past_failures) except Exception as e: # 3. Store the failure store_failure(test_name, e, traceback.format_exc()) raise return wrapper def store_failure(test_name, error, traceback_str): requests.post(f"{URL}/memory", headers={"Authorization": f"Bearer {MIND_KEY}", "Content-Type": "application/json"}, json={ "category": "mistake", "key": f"test_failure_{test_name}_{datetime.now().isoformat()}", "content": f"Test: {test_name}\nError: {error}\nTrace:\n{traceback_str}", "tags": ["test", "failure", test_name], "priority": "high" }) ``` ### Bước 2: Logic kiểm thử thích ứng Bên trong kiểm thử, kiểm tra lỗi đã biết và áp dụng sửa chữa: ```python @self_healing_test def test_login_page(browser, known_failures=None): browser.goto("https://app.com/login") # Check if we've seen this page change before if known_failures and known_failures.get("results"): for failure in known_failures["results"]: if "button moved" in failure["content"].lower(): # Use accessibility label instead of coordinates browser.click(by_label="Login button") return # Default: use coordinates browser.click(x=150, y=400) ``` ### Bước 3: Chiến lược khôi phục Lưu chiến lược khôi phục dưới dạng bộ nhớ: ```python def store_recovery(failure_type, strategy): requests.post(f"{URL}/memory", headers={"Authorization": f"Bearer {MIND_KEY}", "Content-Type": "application/json"}, json={ "category": "skill", "key": f"recovery_{failure_type}", "content": strategy, "tags": ["test", "recovery", failure_type], "priority": "high" }) # Store recoveries for common failures store_recovery("element_not_found", "When element not found by ID, try by CSS class, then by XPath, " "then by accessibility label. Take screenshot for debugging.") store_recovery("timeout", "Increase timeout to 30s. If still fails, check if page is loading " "dynamically — wait for specific element instead of fixed time.") store_recovery("stale_element", "Re-find element before each interaction. Don't cache element references " "across page transitions.") ``` ### Bước 4: Tích hợp CI ```yaml # .gitlab-ci.yml test:self-healing: script: - export SYNAPSE_MIND_KEY=$SYNAPSE_TEST_MIND_KEY - pytest tests/ --self-healing after_script: # Summarize new failures - python scripts/synapse_failure_summary.py ``` ### Bước 5: Bảng điều khiển phân tích lỗi ```python # Get all test failures from the last week r = requests.get( f"{URL}/memory/search?q=test+failure", headers={"Authorization": f"Bearer {MIND_KEY}"} ) # Group by test name failures = {} for mem in r.json().get("results", []): test_name = extract_test_name(mem["content"]) failures.setdefault(test_name, []).append(mem) # Report for test, fails in sorted(failures.items(), key=lambda x: -len(x[1])): print(f"{test}: {len(fails)} failures") ``` ## Thực hành tốt nhất > [!TIP] > - **Lưu traceback** — chúng chứa dòng chính xác bị lỗi > - **Gắn tag theo tên kiểm thử** — cho phép lọc nhanh > - **Sử dụng danh mục `mistake`** — tách khỏi bộ nhớ thông thường > - **Đặt ưu tiên `high`** — lỗi không bao giờ được quên > - **Dọn dẹp định kỳ** — xóa bộ nhớ cho vấn đề đã giải quyết > - **Không lưu dữ liệu nhạy cảm** — thông tin xác thực, PII ## Mẫu lỗi phổ biến cần lưu | Loại lỗi | Cần lưu gì | |--------------|---------------| | Không tìm thấy phần tử | Selector đã thử, trạng thái trang, ảnh chụp màn hình | | Timeout | Thời gian chờ, đang chờ cái gì | | Assertion thất bại | Giá trị mong đợi so với thực tế | | Lỗi mạng | URL, mã trạng thái, body phản hồi | | Permission denied | Quyền yêu cầu, vai trò người dùng hiện tại | ## Bước tiếp theo - [Kiểm thử iOS tự động](/docs/guides/automated-testing-ios) - [Thực hành tốt nhất về bộ nhớ](/docs/guides/memory-best-practices) - [Cookbook khôi phục lỗi](/docs/llm-cookbook/error-recovery)