如何用 Python、ESP32 和 n8n 建立自主實體裝置 QA 測試農場(繞過 AWS Device Farm)
How I Built an Autonomous Physical Device QA Farm with Python, ESP32, and n8n (Bypassing AWS Device Farm)
作者用 Python、ESP32 和 n8n 建立自主實體手機 UI QA 測試農場,以 ESP32-CAM 光學擷取畫面,讓 OpenCV 和 Vision LLM 在不依賴手機作業系統的情況下驗證 UI。文中所述 ESP32-CAM 售價為 $5,並以 RTSP 將畫面串流至本地伺服器,延遲低於 100ms;n8n 負責觸發測試及將結果路由至 Jira、Slack 等服務。
If you've ever tried running automated UI tests on a fleet of physical mobile devices, you know the pain. Cloud-based device farms (like AWS Device Farm or BrowserStack) cost thousands of dollars per month and throttle your CI/CD pipelines due to harsh concurrent usage limits.
On the flip side, trying to orchestrate your own local hardware farm usually results in a nightmare of proprietary enterprise software and notoriously unstable USB (adb) connections that drop mid-test.
In this guide, I'll show you how I bypassed these bottlenecks by building an Autonomous Mobile UI QA Fleet Manager. We're going to use Python-based AI agents, n8n for workflow routing, OpenCV, and ultra-cheap ESP32 microcontrollers to optically test physical devices with zero OS-level overhead.
1. The Bottleneck: Why Commercial Solutions are Fragile
The standard approach to mobile QA relies on USB hubs and adb (Android Debug Bridge) or XCUITest. But USB hubs are notorious for power fluctuations, causing devices to randomly disconnect.
Furthermore, OS-level screen recording consumes device resources, altering the performance metrics of the app you are trying to test.
By physically mounting a $5 ESP32-CAM over the mobile device, we decouple the testing mechanism from the device's OS entirely. It acts as an independent "eye," streaming the screen via low-latency RTSP to a Python backend where OpenCV and Vision LLMs assert the UI state.
2. The Architecture: Hardware-Software Hybrid Pipeline
Here is the step-by-step breakdown of how the fleet operates:
- Trigger (n8n Webhook): A GitHub Action triggers an n8n workflow indicating a new build is ready.
- Fleet Orchestrator (Python API): n8n sends a POST request to our local Python Fleet API. The API checks which ESP32 nodes (and their paired physical devices) are idle and assigns the test suite.
- Hardware Streaming (C++ / ESP32): The ESP32 utilizes optimized C++ firmware to stream the physical device's screen via RTSP to the local server with sub-100ms latency.
- Vision Engine (Python / OpenCV / AI Agent): The Python backend ingests the stream, applies domain sanitization to the test parameters, and uses OpenCV combined with a Vision LLM to assert UI elements (e.g., "Did the login button turn green?").
- Routing & Alerting (n8n): Results are passed back to n8n, which automatically updates Jira, routes failures to a Slack channel, or logs passing metrics into your CRM/Database.
3. The Code & Logic: Vision Assertions & Prompt Structuring
To make this autonomous, we need a robust Python engine that can sanitize the incoming test requests, grab a frame from the ESP32 RTSP stream, and pass it to a Vision LLM with a structured prompt.
Here is the core logic for the Python Vision Agent:
import cv2
import base64
import requests
from urllib.parse import urlparse
# 1. Domain Sanitization: Ensure we are testing the right environment
def sanitize_test_domain(raw_url):
parsed = urlparse(raw_url)
domain = parsed.netloc if parsed.netloc else parsed.path
clean_domain = domain.replace('www.', '').split(':')[0]
return clean_domain
# 2. Capture Frame from ESP32 RTSP Stream
def capture_esp32_frame(rtsp_url):
cap = cv2.VideoCapture(rtsp_url)
ret, frame = cap.read()
cap.release()
if not ret:
raise Exception("ESP32 Stream Timeout or Disconnect")
# Encode to base64 for LLM
_, buffer = cv2.imencode('.jpg', frame)
return base64.b64encode(buffer).decode('utf-8')
# 3. LLM Prompt Structuring for Autonomous UI QA
def assert_ui_state(base64_image, expected_domain, target_element):
prompt = f"""
You are an expert QA automation agent. Analyze this physical device screen.
Context: We are testing the domain '{expected_domain}'.
Task: Verify if the '{target_element}' is visible and properly rendered.
Rules:
- Return ONLY a JSON object.
- Format: {{"element_found": true/false, "confidence": 0-100, "notes": "..."}}
"""
payload = {
"model": "gpt-4o",
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": prompt},
{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{base64_image}"}}
]
}
]
}
# Fire request to OpenAI (or local LLaVA model)
response = requests.post(
"https://api.openai.com/v1/chat/completions",
headers={"Authorization": f"Bearer {YOUR_API_KEY}"},
json=payload
)
return response.json()['choices'][0]['message']['content']
On the hardware side, the ESP32 requires highly optimized firmware to maintain that RTSP stream without memory leaks. Using esp_camera_fb_get() inside a tight RTOS task ensures the frame buffer is constantly flushed to the network socket.
4. Deployment & Performance: Timeouts & Node Routing
When scaling from 1 to 50 physical devices, network congestion and timeouts become your biggest enemy.
Handling RTSP Timeouts
If an ESP32 drops off the network, your Python Orchestrator must not block the CI/CD pipeline. Implement a strict timeout parameter in your OpenCV capture function. If the timeout triggers, the Orchestrator marks the node as offline and automatically re-routes the test to the next available device in the pool.
CI/CD and CRM Routing via n8n
The beauty of exposing the Python Orchestrator as a REST API is seamless integration with n8n.
You can set up an n8n webhook that listens for GitHub merge events. n8n dynamically maps the test suite, fires it to the Python API, and waits for the webhook callback. If the AI Agent returns "element_found": false, n8n can automatically:
- Create a Jira ticket with the base64 screen capture attached.
- Ping the developer on Slack.
- Log the failure in your internal CRM or database to track device-specific failure rates.
5. Conclusion & Ready-to-use Workflow
Building your own physical device farm doesn't require massive enterprise budgets or dealing with flaky USB hubs. By decoupling the "eyes" of the test (ESP32 + OpenCV) from the OS of the mobile device, you get infinite scaling at a fraction of the cost.
You can take the architecture and code snippets above and build this out yourself. However, if you want to skip the trial-and-error of writing C++ memory management for the ESP32, dealing with RTSP threading in Python, and setting up the n8n routing logic, I've packaged the entire system.
The Autonomous Mobile UI QA Fleet Manager — ESP32 Vision Testing Engine includes the optimized C++ firmware, the Python Orchestrator API, the OpenCV engine, and the n8n workflows out of the box.
Grab the turnkey production-ready package with test fixtures and JSON workflows here:
- Instant Access on Whop: Get the Fleet Manager
- Direct Download on Gumroad: Download Here (Use promo code **EARLYBIRD* at checkout for 20% off).*
Happy testing, and may your CI/CD pipelines always be green!
🛠️ D'autres outils MR Studio qui pourraient vous intéresser :
來源:DEV Community · dev.to