{"title":"Pruebas automatizadas de apps iOS","slug":"automated-testing-ios","category":"guides","summary":"Use Synapse + Computer Control API para automatizar pruebas de apps iOS vía Simulator.","audience":["human","llm"],"tags":["guide","ios","testing","automation"],"difficulty":"advanced","updated":"2026-06-27","word_count":341,"read_minutes":2,"lang":"es","translated":true,"requested_lang":"es","content_markdown":"\n# Pruebas automatizadas de apps iOS\n\nCombine el sistema de memoria de Synapse con la Computer Control API para\nconstruir pruebas de apps iOS dirigidas por LLM. El LLM recuerda escenarios de\ntest, aprende de fallos pasados y se adapta a cambios de UI.\n\n## Arquitectura\n\n```\n┌──────────────┐    commands    ┌──────────────┐    screenshots    ┌──────────────┐\n│  LLM Agent   │ ─────────────▶│  Synapse     │ ────────────────▶ │  iOS Sim     │\n│  (Claude)    │               │  Computer    │ ◀──────────────── │  (via agent) │\n└──────────────┘               │  Control     │    results        └──────────────┘\n       │                       └──────────────┘\n       │ store/recall\n       ▼\n┌──────────────┐\n│  Memories    │ (test scenarios, past failures, UI patterns)\n└──────────────┘\n```\n\n## Requisitos previos\n\n- Cuenta de Synapse + Mind Key\n- Servidor MCP de Synapse configurado en Claude Desktop\n- iOS Simulator con `screen-remote-agent` instalado\n- Computadora registrada en Synapse (consulte [API de Computer Control](/docs/api/computers))\n\n## Paso 1: Registrar la computadora Simulator\n\nEn el Mac que ejecuta iOS Simulator:\n\n```bash\n# Get install code from Synapse\ncurl -X POST https://synapse.schaefer.zone/computers/install-code \\\n  -H \"Authorization: Bearer YOUR_MIND_KEY\" \\\n  -d '{\"computer_name\":\"ios-sim\"}'\n# → { \"install_code\": \"ic_...\" }\n\n# Run screen-remote-agent on the Mac\n# (uses the install code to register)\n```\n\n## Paso 2: Almacenar escenarios de test en memoria\n\nAlmacene escenarios de test reutilizables como memorias:\n\n```python\nimport requests\n\ndef store_test_scenario(name, steps, app):\n    requests.post(f\"{URL}/memory\",\n        headers={\"Authorization\": f\"Bearer {MIND_KEY}\"},\n        json={\n            \"category\": \"skill\",\n            \"key\": f\"test_scenario_{name}\",\n            \"content\": f\"App: {app}\\nSteps:\\n\" + \"\\n\".join(steps),\n            \"tags\": [\"test\", \"ios\", app],\n            \"priority\": \"high\"\n        })\n\nstore_test_scenario(\"login_flow\", [\n    \"Launch app\",\n    \"Tap email field\",\n    \"Type test@example.com\",\n    \"Tap password field\",\n    \"Type password123\",\n    \"Tap Login button\",\n    \"Verify home screen appears\"\n], \"MyApp\")\n```\n\n## Paso 3: Ejecución de tests dirigida por LLM\n\nEn Claude Desktop (con Synapse MCP configurado):\n\n```\nRun the login_flow test scenario on the iOS Simulator.\nTake a screenshot after each step and verify the expected UI.\nIf any step fails, store the failure as a memory so we can\navoid it next time.\n```\n\nClaude hará:\n\n1. Llamar a `memory_search` para encontrar la memoria `test_scenario_login_flow`\n2. Llamar a `computer_screenshot` para ver el estado actual\n3. Ejecutar cada paso vía `computer_command_queue` (clic, escribir)\n4. Verificar resultados vía capturas de pantalla\n5. Almacenar cualquier fallo como memorias `mistake`\n\n## Paso 4: Tests autoreparables\n\nCuando un test falla, almacene el fallo y la recuperación:\n\n```python\ndef store_test_failure(scenario, step, error, recovery):\n    requests.post(f\"{URL}/memory\",\n        headers={\"Authorization\": f\"Bearer {MIND_KEY}\"},\n        json={\n            \"category\": \"mistake\",\n            \"key\": f\"failure_{scenario}_{step}\",\n            \"content\": f\"Scenario: {scenario}\\nStep: {step}\\nError: {error}\\nRecovery: {recovery}\",\n            \"tags\": [\"test\", \"failure\", \"ios\", scenario],\n            \"priority\": \"high\"\n        })\n\n# Example\nstore_test_failure(\"login_flow\", \"tap_login\",\n    \"Login button not found at expected coordinates\",\n    \"Button moved due to new logo. Search by accessibility label instead.\")\n```\n\nLa próxima vez que el LLM ejecute el test, recupera el fallo y aplica la\nrecuperación automáticamente.\n\n## Paso 5: Seguimiento de resultados de test\n\nHaga seguimiento de las ejecuciones de test como tareas:\n\n```python\ndef track_test_run(scenario, status, duration):\n    requests.post(f\"{URL}/mind/task\",\n        headers={\"Authorization\": f\"Bearer {MIND_KEY}\",\n                 \"Content-Type\": \"application/json\"},\n        json={\n            \"title\": f\"Test: {scenario}\",\n            \"description\": f\"Status: {status}, Duration: {duration}s\",\n            \"priority\": \"normal\"\n        })\n```\n\n## Comandos comunes\n\n| Acción | Comando |\n|--------|---------|\n| Lanzar Simulator | `xcrun simctl launch booted com.example.app` |\n| Captura de pantalla | `computer_screenshot` (vía Synapse MCP) |\n| Tap en (x,y) | `computer_command_queue {type:\"click\", payload:{x,y}}` |\n| Escribir texto | `computer_command_queue {type:\"type\", payload:{text:\"...\"}}` |\n| Pulsar Home | `computer_command_queue {type:\"key\", payload:{keys:[\"Cmd\",\"Shift\",\"H\"]}}` |\n\n## Mejores prácticas\n\n> [!TIP]\n> - **Almacene coordenadas de UI como memorias** — la UI cambia, pero el LLM puede reaprender\n> - **Use etiquetas de accesibilidad** — más estables que las coordenadas\n> - **Almacene datos de test por separado** — use variables para usuarios y contraseñas\n> - **Ejecute tests en estado limpio** — resetee el Simulator entre ejecuciones\n> - **Guarde capturas de los fallos** — útil para depurar\n\n## Próximos pasos\n\n- [Tests autoreparables](/docs/guides/self-healing-tests)\n- [API de Computer Control](/docs/api/computers)\n- [Mejores prácticas de memoria](/docs/guides/memory-best-practices)\n","content_html":"<h1>Pruebas automatizadas de apps iOS</h1>\n<p>Combine el sistema de memoria de Synapse con la Computer Control API para\nconstruir pruebas de apps iOS dirigidas por LLM. El LLM recuerda escenarios de\ntest, aprende de fallos pasados y se adapta a cambios de UI.</p>\n<h2>Arquitectura</h2>\n<pre><code class=\"hljs language-plaintext\">┌──────────────┐    commands    ┌──────────────┐    screenshots    ┌──────────────┐\n│  LLM Agent   │ ─────────────▶│  Synapse     │ ────────────────▶ │  iOS Sim     │\n│  (Claude)    │               │  Computer    │ ◀──────────────── │  (via agent) │\n└──────────────┘               │  Control     │    results        └──────────────┘\n       │                       └──────────────┘\n       │ store/recall\n       ▼\n┌──────────────┐\n│  Memories    │ (test scenarios, past failures, UI patterns)\n└──────────────┘</code></pre><h2>Requisitos previos</h2>\n<ul>\n<li>Cuenta de Synapse + Mind Key</li>\n<li>Servidor MCP de Synapse configurado en Claude Desktop</li>\n<li>iOS Simulator con <code>screen-remote-agent</code> instalado</li>\n<li>Computadora registrada en Synapse (consulte <a href=\"/docs/api/computers\">API de Computer Control</a>)</li>\n</ul>\n<h2>Paso 1: Registrar la computadora Simulator</h2>\n<p>En el Mac que ejecuta iOS Simulator:</p>\n<pre><code class=\"hljs language-bash\"><span class=\"hljs-comment\"># Get install code from Synapse</span>\ncurl -X POST https://synapse.schaefer.zone/computers/install-code \\\n  -H <span class=\"hljs-string\">&quot;Authorization: Bearer YOUR_MIND_KEY&quot;</span> \\\n  -d <span class=\"hljs-string\">&#x27;{&quot;computer_name&quot;:&quot;ios-sim&quot;}&#x27;</span>\n<span class=\"hljs-comment\"># → { &quot;install_code&quot;: &quot;ic_...&quot; }</span>\n\n<span class=\"hljs-comment\"># Run screen-remote-agent on the Mac</span>\n<span class=\"hljs-comment\"># (uses the install code to register)</span></code></pre><h2>Paso 2: Almacenar escenarios de test en memoria</h2>\n<p>Almacene escenarios de test reutilizables como memorias:</p>\n<pre><code class=\"hljs language-python\"><span class=\"hljs-keyword\">import</span> requests\n\n<span class=\"hljs-keyword\">def</span> <span class=\"hljs-title function_\">store_test_scenario</span>(<span class=\"hljs-params\">name, steps, app</span>):\n    requests.post(<span class=\"hljs-string\">f&quot;<span class=\"hljs-subst\">{URL}</span>/memory&quot;</span>,\n        headers={<span class=\"hljs-string\">&quot;Authorization&quot;</span>: <span class=\"hljs-string\">f&quot;Bearer <span class=\"hljs-subst\">{MIND_KEY}</span>&quot;</span>},\n        json={\n            <span class=\"hljs-string\">&quot;category&quot;</span>: <span class=\"hljs-string\">&quot;skill&quot;</span>,\n            <span class=\"hljs-string\">&quot;key&quot;</span>: <span class=\"hljs-string\">f&quot;test_scenario_<span class=\"hljs-subst\">{name}</span>&quot;</span>,\n            <span class=\"hljs-string\">&quot;content&quot;</span>: <span class=\"hljs-string\">f&quot;App: <span class=\"hljs-subst\">{app}</span>\\nSteps:\\n&quot;</span> + <span class=\"hljs-string\">&quot;\\n&quot;</span>.join(steps),\n            <span class=\"hljs-string\">&quot;tags&quot;</span>: [<span class=\"hljs-string\">&quot;test&quot;</span>, <span class=\"hljs-string\">&quot;ios&quot;</span>, app],\n            <span class=\"hljs-string\">&quot;priority&quot;</span>: <span class=\"hljs-string\">&quot;high&quot;</span>\n        })\n\nstore_test_scenario(<span class=\"hljs-string\">&quot;login_flow&quot;</span>, [\n    <span class=\"hljs-string\">&quot;Launch app&quot;</span>,\n    <span class=\"hljs-string\">&quot;Tap email field&quot;</span>,\n    <span class=\"hljs-string\">&quot;Type test@example.com&quot;</span>,\n    <span class=\"hljs-string\">&quot;Tap password field&quot;</span>,\n    <span class=\"hljs-string\">&quot;Type password123&quot;</span>,\n    <span class=\"hljs-string\">&quot;Tap Login button&quot;</span>,\n    <span class=\"hljs-string\">&quot;Verify home screen appears&quot;</span>\n], <span class=\"hljs-string\">&quot;MyApp&quot;</span>)</code></pre><h2>Paso 3: Ejecución de tests dirigida por LLM</h2>\n<p>En Claude Desktop (con Synapse MCP configurado):</p>\n<pre><code class=\"hljs language-plaintext\">Run the login_flow test scenario on the iOS Simulator.\nTake a screenshot after each step and verify the expected UI.\nIf any step fails, store the failure as a memory so we can\navoid it next time.</code></pre><p>Claude hará:</p>\n<ol>\n<li>Llamar a <code>memory_search</code> para encontrar la memoria <code>test_scenario_login_flow</code></li>\n<li>Llamar a <code>computer_screenshot</code> para ver el estado actual</li>\n<li>Ejecutar cada paso vía <code>computer_command_queue</code> (clic, escribir)</li>\n<li>Verificar resultados vía capturas de pantalla</li>\n<li>Almacenar cualquier fallo como memorias <code>mistake</code></li>\n</ol>\n<h2>Paso 4: Tests autoreparables</h2>\n<p>Cuando un test falla, almacene el fallo y la recuperación:</p>\n<pre><code class=\"hljs language-python\"><span class=\"hljs-keyword\">def</span> <span class=\"hljs-title function_\">store_test_failure</span>(<span class=\"hljs-params\">scenario, step, error, recovery</span>):\n    requests.post(<span class=\"hljs-string\">f&quot;<span class=\"hljs-subst\">{URL}</span>/memory&quot;</span>,\n        headers={<span class=\"hljs-string\">&quot;Authorization&quot;</span>: <span class=\"hljs-string\">f&quot;Bearer <span class=\"hljs-subst\">{MIND_KEY}</span>&quot;</span>},\n        json={\n            <span class=\"hljs-string\">&quot;category&quot;</span>: <span class=\"hljs-string\">&quot;mistake&quot;</span>,\n            <span class=\"hljs-string\">&quot;key&quot;</span>: <span class=\"hljs-string\">f&quot;failure_<span class=\"hljs-subst\">{scenario}</span>_<span class=\"hljs-subst\">{step}</span>&quot;</span>,\n            <span class=\"hljs-string\">&quot;content&quot;</span>: <span class=\"hljs-string\">f&quot;Scenario: <span class=\"hljs-subst\">{scenario}</span>\\nStep: <span class=\"hljs-subst\">{step}</span>\\nError: <span class=\"hljs-subst\">{error}</span>\\nRecovery: <span class=\"hljs-subst\">{recovery}</span>&quot;</span>,\n            <span class=\"hljs-string\">&quot;tags&quot;</span>: [<span class=\"hljs-string\">&quot;test&quot;</span>, <span class=\"hljs-string\">&quot;failure&quot;</span>, <span class=\"hljs-string\">&quot;ios&quot;</span>, scenario],\n            <span class=\"hljs-string\">&quot;priority&quot;</span>: <span class=\"hljs-string\">&quot;high&quot;</span>\n        })\n\n<span class=\"hljs-comment\"># Example</span>\nstore_test_failure(<span class=\"hljs-string\">&quot;login_flow&quot;</span>, <span class=\"hljs-string\">&quot;tap_login&quot;</span>,\n    <span class=\"hljs-string\">&quot;Login button not found at expected coordinates&quot;</span>,\n    <span class=\"hljs-string\">&quot;Button moved due to new logo. Search by accessibility label instead.&quot;</span>)</code></pre><p>La próxima vez que el LLM ejecute el test, recupera el fallo y aplica la\nrecuperación automáticamente.</p>\n<h2>Paso 5: Seguimiento de resultados de test</h2>\n<p>Haga seguimiento de las ejecuciones de test como tareas:</p>\n<pre><code class=\"hljs language-python\"><span class=\"hljs-keyword\">def</span> <span class=\"hljs-title function_\">track_test_run</span>(<span class=\"hljs-params\">scenario, status, duration</span>):\n    requests.post(<span class=\"hljs-string\">f&quot;<span class=\"hljs-subst\">{URL}</span>/mind/task&quot;</span>,\n        headers={<span class=\"hljs-string\">&quot;Authorization&quot;</span>: <span class=\"hljs-string\">f&quot;Bearer <span class=\"hljs-subst\">{MIND_KEY}</span>&quot;</span>,\n                 <span class=\"hljs-string\">&quot;Content-Type&quot;</span>: <span class=\"hljs-string\">&quot;application/json&quot;</span>},\n        json={\n            <span class=\"hljs-string\">&quot;title&quot;</span>: <span class=\"hljs-string\">f&quot;Test: <span class=\"hljs-subst\">{scenario}</span>&quot;</span>,\n            <span class=\"hljs-string\">&quot;description&quot;</span>: <span class=\"hljs-string\">f&quot;Status: <span class=\"hljs-subst\">{status}</span>, Duration: <span class=\"hljs-subst\">{duration}</span>s&quot;</span>,\n            <span class=\"hljs-string\">&quot;priority&quot;</span>: <span class=\"hljs-string\">&quot;normal&quot;</span>\n        })</code></pre><h2>Comandos comunes</h2>\n<table>\n<thead>\n<tr>\n<th>Acción</th>\n<th>Comando</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>Lanzar Simulator</td>\n<td><code>xcrun simctl launch booted com.example.app</code></td>\n</tr>\n<tr>\n<td>Captura de pantalla</td>\n<td><code>computer_screenshot</code> (vía Synapse MCP)</td>\n</tr>\n<tr>\n<td>Tap en (x,y)</td>\n<td><code>computer_command_queue {type:&quot;click&quot;, payload:{x,y}}</code></td>\n</tr>\n<tr>\n<td>Escribir texto</td>\n<td><code>computer_command_queue {type:&quot;type&quot;, payload:{text:&quot;...&quot;}}</code></td>\n</tr>\n<tr>\n<td>Pulsar Home</td>\n<td><code>computer_command_queue {type:&quot;key&quot;, payload:{keys:[&quot;Cmd&quot;,&quot;Shift&quot;,&quot;H&quot;]}}</code></td>\n</tr>\n</tbody></table>\n<h2>Mejores prácticas</h2>\n<div class=\"callout callout-ok\"></div><h2>Próximos pasos</h2>\n<ul>\n<li><a href=\"/docs/guides/self-healing-tests\">Tests autoreparables</a></li>\n<li><a href=\"/docs/api/computers\">API de Computer Control</a></li>\n<li><a href=\"/docs/guides/memory-best-practices\">Mejores prácticas de memoria</a></li>\n</ul>\n","urls":{"html":"/docs/guides/automated-testing-ios","text":"/docs/guides/automated-testing-ios?format=text","json":"/docs/guides/automated-testing-ios?format=json","llm":"/docs/guides/automated-testing-ios?format=llm"},"translations_available":["en","zh","hi","es","fr","ar","pt","ru","ja","de","it","ko","nl","pl","tr","sv","vi","th","id","uk"]}