AI 測試大師 / mcp-test-runner

AI 測試大師 — Servidor MCP que impulsa pytest / Jest / Cypress / Go / Maestro. Analiza, genera, ejecuta, asesora. Web + Móvil (iOS/Android/BlueStacks).

Documentación

mk-qa-master logo

MK QA Master

AI 測試大師 — tu bucle de QA con IA, de analizar a aconsejar.

English · 繁體中文

PyPI CI Glama score License: MIT Buy Me a Coffee

Servidor MCP universal para ejecutar pruebas en pytest / Jest / Cypress / Go, con analizador DOM integrado, historial de ejecuciones y un coach de auto-mejora. Estable desde v1.0.0 (2026-06-02) — consulta Promesa de estabilidad más abajo.

Un servidor de Model Context Protocol que permite a Claude Desktop / Cursor / cualquier cliente MCP manejar tu suite de pruebas de principio a fin: ejecutar pruebas, inspeccionar fallos (captura de pantalla + vídeo + traza), analizar una URL en vivo para redactar casos de prueba y — tras cada ejecución — producir un plan de acción priorizado que te dice exactamente qué corregir o escribir a continuación.

QA_RUNNERFrameworkLenguajeDestino
pytest / pytest-playwright / playwrightpytest + PlaywrightPythonWeb
jestJestJavaScriptWeb
cypressCypressJavaScriptWeb
go / go-testgo testGoBackend
maestro / mobileMaestroYAMLiOS + Android
schemathesis / apiSchemathesisOpenAPI 3.x / Swagger 2.0API (desde v0.6.0)
newman / postmanNewmanPostman collection v2.xAPI (desde v0.6.1)

Notas de diseño completas: docs/framework.md.


Qué incluye

  • Ejecutar pruebas en múltiples frameworks (web + móvil + API) mediante una única superficie MCP

  • Móvil vía Maestro (desde v0.3.0): las mismas herramientas MCP, iOS Simulator / Android Emulator / dispositivo real; flujos YAML; multiplataforma sin reescrituras

  • Pruebas de API nativas — dos runners (desde v0.6.0 / v0.6.1): dos pares comparten ahora el espacio de pruebas de API, cada uno alimentado por el artefacto que tu equipo ya mantiene.

    • Schemathesis (QA_RUNNER=schemathesis, desde v0.6.0): apunta a una URL OpenAPI 3.x / Swagger 2.0 o a un esquema file:// y obtén pruebas fuzzeadas basadas en propiedades que cubren códigos de estado, esquemas de respuesta, tipos de contenido y violaciones de 5xx-on-fuzz.
    • Newman (QA_RUNNER=newman, desde v0.6.1): apunta a una colección Postman 2.x exportada (más archivos opcionales de entorno / globales) y Newman reproduce cada petición, ejecuta las aserciones pm.test(...) integradas y devuelve un nodeid mk-qa-master por aserción. Newman es un prerrequisito del sistema (npm install -g newman) — es un paquete npm, no pip, así que no se distribuye como extra de Python.

    Ambos se integran en la misma superficie de herramientas MCP que los runners web / móvil, y ambos alimentan el mismo pipeline de report.json / historial / flake / optimizador. Las pruebas de API existentes escritas en pytest+httpx, Jest+supertest, Cypress cy.request() o Go net/http/httptest siguen usando sus runners existentes — no se necesita migración. La verificación de proveedor Pact permanece en la hoja de ruta condicional de v0.7.0.

  • Artefactos de fallo: captura de pantalla (incrustada en base64), vídeo, trace.zip de Playwright / grabaciones de Maestro

  • Historial de ejecuciones: cada ejecución se captura; el informe HTML muestra una tendencia sparkline

  • Analizador DOM / pantallaanalyze_url para web (formularios / navegación / diálogos / CTAs + los endpoints de API que la página consulta) y analyze_screen para móvil (maestro hierarchy → módulos form / cta / tab_bar)

  • Generación inteligente de pruebas (generate_test): pásale un módulo de analizador y escribe un .py de Playwright o un .yaml de Maestro ejecutable con selectores concretos, no stubs # TODO

  • Reintento automático de flakes — lado pytest vía pytest-rerunfailures; lado Maestro vía wrapper de reintento personalizado (sin --reruns nativo); las pruebas flaky se muestran por separado de los fallos reales

  • Coach de auto-mejora (get_optimization_plan): análisis posterior a la ejecución desde tres perspectivas — calidad de la suite, usabilidad de MCP, efectividad de la generación con IA

  • Salida JUnit XML para integraciones de CI (GitHub Actions / Jenkins / GitLab)


Instalación

Dos vías — elige la que coincida con cómo lo vas a usar.

A. Ejecutar vía uvx (instalación cero, recomendado para usuarios finales)

Añade mk-qa-master a tu configuración de cliente sin instalar nada globalmente; uv lo descarga y ejecuta en un entorno efímero por sesión:

{
  "mcpServers": {
    "mk-qa-master": {
      "command": "uvx",
      "args": ["mk-qa-master"],
      "env": { "QA_RUNNER": "pytest", "QA_PROJECT_ROOT": "/path/to/your-test-project" }
    }
  }
}

Eso es toda la configuración. La primera llamada descarga el paquete; las llamadas posteriores se cachean. Cambiar de versión: uvx mk-qa-master@0.4.1 ....

B. Instalar en un venv de proyecto (para contribuidores / hacking)

pip install mk-qa-master       # or: pip install -e . from a clone
playwright install                # only if you use pytest-playwright
pip install pytest-rerunfailures  # optional, enables auto-retry

Luego apunta tu configuración de cliente al mismo intérprete de Python:

"command": "/path/to/.venv/bin/python",
"args": ["-m", "mk_qa_master.server"]

Verificar la instalación (v1.4+)

mk-qa-master doctor          # human-readable check report
mk-qa-master doctor --json   # for CI gates / host-LLM consumption

Comprueba la versión de Python, ffmpeg + mediamtx en PATH, dependencias principales, extras [edge], registro de runners y la superficie de herramientas MCP. Sale con 0 cuando no falta nada crítico (las advertencias sobre funciones no utilizadas no fallan), 1 cuando mk-qa-master no puede ejecutarse limpiamente. Ejecútalo tras una instalación nueva o cuando una herramienta MCP devuelva missing_extras.

Prerrequisitos específicos por runner

QA_RUNNERTambién necesitas
pytest / pytest-playwrightpip install pytest-playwright + playwright install chromium
jestUn proyecto Node con jest instalado (npm i -D jest)
cypressUn proyecto Node con cypress instalado (npm i -D cypress)
goCadena de herramientas Go en PATH
maestroCLI de Maestro + un simulador / emulador / dispositivo iniciado (o BlueStacks accesible vía adb connect)
schemathesis / apipip install 'mk-qa-master[api]' (incluye schemathesis>=3.0,<4)
newman / postmannpm install -g newman (Newman es un paquete npm, no pip — no hay extra que instalar)

Pruebas de API (QA_RUNNER=schemathesis)

Apunta el runner a cualquier esquema OpenAPI 3.x / Swagger 2.0 y Schemathesis genera casos de prueba basados en propiedades por operación — cubriendo conformidad del esquema de respuesta, conformidad de códigos de estado, comprobaciones de tipo de contenido y 5xx-on-fuzz. Los resultados fluyen por el mismo pipeline de report.json / historial / flake / optimizador que tus pruebas de UI.

El recorrido completo de principio a fin está en docs/walkthrough-api.md; una muestra autocontenida de 3 endpoints está en examples/sample_api_project/.

Configuración de 5 líneas

"env": {
  "QA_RUNNER": "schemathesis",
  "QA_OPENAPI_URL": "https://api.example.com/openapi.json"
}

Variables de entorno

VariableRequeridaPredeterminadoQué hace
QA_OPENAPI_URLURL de OpenAPI. http(s)://... para esquemas en vivo, file://... para archivos locales. No se aceptan rutas de sistema de archivos simples — necesitan el prefijo file://.
QA_SCHEMATHESIS_CHECKSnoallSubconjunto separado por comas: response_schema_conformance,status_code_conformance,not_a_server_error,content_type_conformance,response_headers_conformance.
QA_SCHEMATHESIS_AUTHnoValor del encabezado de autorización. Se envía como -H "Authorization: <value>". Nunca se registra; se redacta de los informes archivados.
QA_SCHEMATHESIS_MAX_EXAMPLESno20Ejemplos de Hypothesis por operación. Más alto = fuzz más profundo, ejecución más lenta.
QA_SCHEMATHESIS_DRY_RUNno0Establécelo en 1 para planificar sin HTTP — útil para una vista previa de seguridad contra producción, o un smoke de CI contra un artefacto solo de esquema.
QA_NO_REDACTno0Desactiva la redacción de secretos en los informes archivados. Por defecto redacta Authorization: Bearer …, "password": …, "token" / "api_key" / "secret" / "access_token" / "refresh_token": ….

El QA_TIMEOUT_SECONDS estándar sigue aplicándose (600s por defecto).

Pruebas de API (QA_RUNNER=newman)

Apunta el runner a cualquier colección Postman 2.x exportada y Newman 6.x reproduce cada petición, ejecuta las aserciones pm.test(...) integradas y devuelve una "prueba" mk-qa-master por aserción. Los resultados fluyen por el mismo pipeline de report.json / historial / flake / optimizador que los runners de Schemathesis y UI.

Prerrequisito del sistema: Newman se distribuye vía npm, no pip. Instala una vez:

npm install -g newman

No hay extra pip install 'mk-qa-master[postman]' — el runner simplemente invoca el binario newman en PATH. Si falta, el runner lanza un ImportError claro que apunta a la línea de instalación de npm.

La misma API de Biblioteca de 3 endpoints a la que apunta la muestra de OpenAPI se distribuye como colección de Postman en examples/sample_api_project/postman-collection.json — combínala con prism mock examples/sample_api_project/openapi.yaml para un bucle de desarrollo totalmente autocontenido, o apunta a tu propio servidor de staging.

Configuración de 5 líneas

"env": {
  "QA_RUNNER": "newman",
  "QA_POSTMAN_COLLECTION": "/absolute/path/to/your-collection.json"
}

Variables de entorno

VariableRequeridaPredeterminadoQué hace
QA_POSTMAN_COLLECTIONRuta de sistema de archivos simple a un JSON de colección Postman 2.x. Sin prefijo file:// — Newman no necesita desambiguación de esquema ya que las colecciones son siempre artefactos locales.
QA_POSTMAN_ENVIRONMENTnoRuta simple a un archivo de entorno de Postman (-e <path>). Proporciona valores para los placeholders {{var_name}} en la colección.
QA_POSTMAN_GLOBALSnoRuta simple a un archivo de globales de Postman (-g <path>). Misma forma que el entorno, con alcance global.
QA_POSTMAN_ITERATIONSno1Reproduce toda la colección N veces (-n <N>). Útil para pruebas de resistencia y detección de flakes.
QA_POSTMAN_FOLDERnoCSV de nombres de carpetas de Postman para restringir la ejecución (banderas --folder repetidas). run_failed también usa el alcance por carpetas cuando los fallos se agrupan en carpetas conocidas.
QA_POSTMAN_TIMEOUT_REQUEST_MSno30000Tiempo de espera HTTP por petición en milisegundos (--timeout-request). Distinto de QA_TIMEOUT_SECONDS, que limita todo el subproceso.
QA_NO_REDACTno0Misma política de redacción que el runner de Schemathesis — desactívala solo para sesiones de depuración cortas.

El QA_TIMEOUT_SECONDS estándar sigue aplicándose (600s por defecto).

Solucionador de Desafíos Visuales con IA (v0.7.0)

Cuando el bypass del backend no es una opción: Claude mira el CAPTCHA, mk-qa-master hace los clics.

Compatible con reCAPTCHA v2 (desde v0.7.0) y hCaptcha (desde v0.7.1).

La primera capacidad de la familia donde la visión del cliente de IA es estructural, no opcional. Dos nuevas herramientas MCP (inspect_visual_challenge + solve_visual_challenge) detectan un desafío de cuadrícula de imágenes reCAPTCHA v2 o hCaptcha en la página activa de Playwright, la capturan para el cliente de IA multimodal, aceptan la selección de fichas que la IA devuelve y ejecutan la cadena de clics. El runner es los ojos y las manos; el cliente de IA (Claude / Cursor / Gemini / GPT-4o) es el solucionador real.

Cuándo usar esto — Nivel 1 vs Nivel 3

La capa de conocimiento QA integrada (get_qa_context section="CAPTCHA") codifica tres niveles. Recurre a ellos en orden:

NivelEnfoqueCuándo
1 — bypassClaves de prueba reCAPTCHA, feature flags, lista blanca de IP, encabezados de modo de pruebaPredeterminado. Cubre ~90% de los casos.
2 — degradarMarcar como external_dependency, omitir aserciones posterioresCuando no puedes cambiar el backend pero la prueba no trata sobre el CAPTCHA en sí.
3 — juicio visual con IAEsta función.Solo cuando 1 + 2 no encajan (sitios de clientes con autorización pero sin acceso al backend, staging que refleja el CAPTCHA de producción, webviews móviles donde la lista blanca de IP no es accesible).

Puerta de consentimiento

El solucionador no hace nada hasta que te suscribes explícitamente. Dos variables de entorno lo controlan:

VariableRequeridoPredeterminadoQué hace
QA_VISUAL_CHALLENGE_CONSENTfalseDebe establecerse en true para que cualquiera de las herramientas funcione. Sin él, ambas herramientas devuelven un error consent_required que incluye el aviso legal completo (el cliente de IA lo muestra al usuario).
QA_VISUAL_CHALLENGE_AUTHORIZED_DOMAINSno (recomendado)Lista de dominios permitidos separados por comas donde la herramienta puede operar. Cuando está ESTABLECIDO, rechaza cualquier otro dominio. Cuando NO ESTÁ ESTABLECIDO, solo advierte: continúa pero sella la respuesta con una advertencia indicándote que establezcas uno. Recomendado para entornos de CI compartidos / multi-tenant.
QA_VISUAL_CHALLENGE_TIMEOUTno120Presupuesto de tiempo real en segundos para el ciclo inspeccionar→resolver. Respeta QA_TIMEOUT_SECONDS como límite máximo.

Inicio rápido

"env": {
  "QA_RUNNER": "pytest",
  "QA_PROJECT_ROOT": "/path/to/project",
  "QA_VISUAL_CHALLENGE_CONSENT": "true",
  "QA_VISUAL_CHALLENGE_AUTHORIZED_DOMAINS": "client-staging.example.com"
}

Luego, cuando una llamada run_tests revela un fallo external_dependency que apunta a un CAPTCHA, el cliente de IA puede escalar:

mk-qa-master.inspect_visual_challenge()  # screenshot + tile grid
→ AI vision picks tiles [0, 4, 7]
mk-qa-master.solve_visual_challenge(
    challenge_id="...", selected_tile_indices=[0, 4, 7], confirm=true,
)
→ status: "passed", token: "...", hint: "CAPTCHA verified. Resume your test."

El tutorial completo está en docs/walkthrough-visual-challenge.md. PRD: docs/prd-v0.7-visual-challenge.md.

Dominios de bloqueo estricto

Independientemente del consentimiento o la lista de permitidos, el solucionador se niega a operar en proveedores de identidad de terceros conocidos (accounts.google.com, login.microsoftonline.com, id.apple.com, facebook.com, login.live.com, etc.). Ningún escenario legítimo de QA justifica un solucionador de CAPTCHA contra el portal de inicio de sesión de otra persona.

Privacidad

Sin retención de capturas de pantalla más allá del ciclo activo de inspección→resolución. La telemetría registra solo el resultado booleano: nunca la captura de pantalla, nunca el texto del desafío, nunca la selección de mosaicos. La caché LRU de 5 minutos mantiene como máximo 10 desafíos pendientes por proceso y nunca toca el disco.

Advertencia sobre la tasa de éxito

El modelo de visión del cliente de IA es el que realmente juzga: Claude Sonnet 4, GPT-4o y Gemini 2.5 incluyen visión nativa, pero su precisión en un reCAPTCHA de 3x3 varía. Planifica al menos un reintento por desafío (reCAPTCHA te da tres antes de bloquear). get_telemetry eventualmente mostrará la tasa de aprobación agregada para que puedas dimensionar esa expectativa por cliente.

Alcance: solo reCAPTCHA v2 de cuadrícula de imágenes en v0.7.0. hCaptcha llega en v0.7.1. reCAPTCHA v3 / Cloudflare Turnstile están permanentemente fuera de alcance: no muestran un desafío visible para inspeccionar.

Escaneo de seguridad de API OWASP (v0.8.0)

Schemathesis detecta la deriva de corrección. v0.8.0 añade la capa que detecta la deriva de seguridad oculta detrás de un esquema que pasa.

v0.8.0 incluye un escáner basado en reglas OWASP API Security Top 10 (2023) como nueva herramienta MCP: run_api_security_scan. Carga una especificación OpenAPI 3.x, recorre cada (ruta × método) y despacha cinco reglas puramente observables por HTTP:

OWASP #ReglaSeveridad cuando se activa
API1BOLA / IDOR — el token de alice lee el objeto de bob mediante manipulación de ID de rutaCRITICAL
API2Autenticación rota — el servidor acepta JWTs alg:none, malformados o con firma incorrectaMEDIUM / HIGH / CRITICAL según la sonda
API3Asignación masiva — el servidor persiste campos extra peligrosos como role: admin, is_verified: trueHIGH
API5Autorización a nivel de función — un usuario no administrador accede a endpoints con forma de administradorHIGH
API8Configuración de seguridad incorrecta — faltan cabeceras HSTS/CSP/X-Frame, CORS comodín con credencialesLOW / MEDIUM / HIGH

API4 (riesgo de DoS por límite de tasa), API6 (modelado de flujo de negocio), API7 (infraestructura de callback SSRF), API9 (reconocimiento de producción), API10 (APIs ascendentes) están diferidos — ver docs/prd-v0.8-api-security.md §3.

Puertas de consentimiento + autorización

Refleja el modelo de consentimiento de desafío visual de v0.7:

VariableRequeridoQué hace
QA_API_SECURITY_CONSENTDebe ser true. Sin él, devuelve consent_required.
QA_API_SECURITY_AUTHORIZED_DOMAINSsí para hosts externosLista de permitidos separada por comas. Localhost / 127.0.0.1 están autorizados implícitamente.

La regla mass_assignment muta el estado del servidor: está excluida de las categorías predeterminadas. Los llamadores deben optar por participar: categories=["headers", "broken_auth", "bola", "function_authz", "mass_assignment"].

Inicio rápido

"env": {
  "QA_RUNNER": "pytest",
  "QA_PROJECT_ROOT": "/path/to/project",
  "QA_API_SECURITY_CONSENT": "true",
  "QA_API_SECURITY_AUTHORIZED_DOMAINS": "api.staging.example.com"
}

Luego pide al cliente de IA que escanee:

mk-qa-master.run_api_security_scan(
    spec_url="https://api.staging.example.com/openapi.yaml",
    auth={
        "token": "alice's bearer token",
        "alt_user_token": "bob's bearer token",
        "bola_test_ids": {"user_a": [101, 103], "user_b": [202]}
    },
    severity_threshold="medium"
)

Devuelve el bloque de informe de seguridad v0.8:

{
  "scan_id": "a3f8d1c9b7e2",
  "spec_url": "...",
  "base_url": "https://api.staging.example.com",
  "categories_run": ["headers", "broken_auth", "bola", "function_authz"],
  "rules_ran": ["OWASP-API8-Headers", "OWASP-API2-BrokenAuth", ...],
  "ops_scanned": 23,
  "severity_threshold": "medium",
  "findings": [
    {
      "rule_id": "OWASP-API1-BOLA-CrossUserDataExposure",
      "severity": "critical",
      "endpoint": "GET /orders/{id}",
      "title": "user_a can read user_b's object id=202 — missing object-level authorization check",
      "evidence": {"actor": "user_a", "target_owner": "user_b", "target_id": 202, "probed_path": "/orders/202", "status_code": 200, ...},
      "remediation_hint": "Compare the caller's identity to the object's owner before returning..."
    },
    ...
  ],
  "summary": {"total": 7, "by_severity": {"critical": 2, "high": 4, "medium": 1, "low": 0, "info": 0}}
}

La verdad fundamental del Nivel 1

examples/sample_vulnerable_api/ incluye una aplicación Flask deliberadamente vulnerable donde cada categoría OWASP en alcance tiene un par de endpoints vulnerable/seguro. Ejecútala localmente para ver cómo se ve cada regla en acción:

cd examples/sample_vulnerable_api
pip install -r requirements.txt
python app.py  # binds 127.0.0.1:5099
# Then from another shell, point run_api_security_scan at
# http://127.0.0.1:5099 + the bundled openapi.yaml

El escáner encuentra las 5 categorías en /vuln/* y produce cero falsos positivos en /safe/*. Esa propiedad se aplica mediante las pruebas dogfood del Nivel 1 en cada PR.

Nota de seguridad

El escáner ejecuta casos de prueba adversariales. No lo apuntes a sistemas de producción que no poseas, y no lo apuntes a ningún sistema donde no tengas autorización. Las dos variables de entorno anteriores son el contrato.

PRD: docs/prd-v0.8-api-security.md. El intento móvil anterior de v0.8 se aparcó: ver docs/v0.8-mobile-postmortem.md para lo que aprendimos y cómo moldeó las puertas de prueba del PRD de seguridad de API.

Uso como habilidad de Claude Code / Codex / Hermes / OpenClaw (v0.9.0)

La misma carpeta de habilidad se carga en cuatro hosts de agentes diferentes mediante la convención agentskills.io.

v0.9.0 empaqueta mk-qa-master como una habilidad de agente entre hosts además de su forma de servidor MCP. La carpeta skills/mk-qa-master/ es la única fuente de verdad: los mismos SKILL.md, comandos de barra y documentos de referencia se cargan en:

  • Claude Code — vía .claude-plugin/plugin.json (este repositorio es un mercado de plugins).
  • OpenAI Codex — vía .codex-plugin/plugin.json (Codex lee mercados estilo Claude).
  • OpenClaw — instala desde el checkout local: openclaw plugins install /path/to/mk-qa-master.
  • Hermes Agent — enlaza simbólicamente la carpeta de habilidad en ~/.hermes/skills/.

Instalación rápida (Claude Code)

# Inside Claude Code:
/plugin marketplace add kao273183/mk-qa-master
/plugin install mk-qa-master@mk-qa-master

Reinicia Claude Code para que la habilidad se registre. Luego, cualquier indicación de pruebas de QA activa automáticamente la habilidad, o invoca explícitamente un comando de barra:

/mk-qa-master:run-tests login
/mk-qa-master:generate https://staging.example.com
/mk-qa-master:api-security https://api.staging.example.com/openapi.yaml

Qué hace la habilidad

La habilidad es un contrato operativo de un solo archivo que enseña al host cómo manejar las 22 herramientas MCP de mk-qa-master de manera coherente. Codifica:

  • Cuándo auto-activarse — frases como "ejecuta mis pruebas", "por qué falló esta prueba", "escanea esta API para problemas OWASP" lo activan.
  • Cinco flujos — ejecutar pruebas / generar pruebas / depurar fallos / resolver CAPTCHAs / escanear APIs.
  • Reglas estrictas — mostrar errores de consentimiento textualmente, no re-ejecutar silenciosamente con filtros relajados, confirmar antes de ejecuciones destructivas.

Referencia completa en skills/mk-qa-master/SKILL.md.

¿Por qué una habilidad sobre un servidor MCP?

El servidor MCP hace que las 22 herramientas sean invocables por cualquier cliente. La habilidad las hace descubribles + gobernadas: le da al enrutador de habilidades del host suficiente contexto para decidir cuándo usar las herramientas y qué flujo seguir. Inspirado en microsoft/Webwright, que usa el mismo patrón.

Promesa de estabilidad (v1.0.0)

22 herramientas. Esquema congelado. Deriva versionada. Fija y listo.

mk-qa-master lanzó v1.0.0 el 2026-06-02. La superficie de herramientas MCP está bloqueada: 22 herramientas, las variables de entorno de la puerta de consentimiento, las formas de plan / marcadores y las listas negras de bloqueo estricto no cambian sin un ciclo de deprecación.

Qué significa esto para los llamadores

Si fijas…Qué obtienes
mk-qa-master==1.0.*Solo versiones de parche (correcciones de errores; sin cambio de superficie)
mk-qa-master==1.*Versiones menores (solo aditivas: nuevas herramientas, nuevos argumentos opcionales, nuevos campos)
mk-qa-master>=1,<2Igual que arriba

Los cambios disruptivos requieren un salto a v2.0. Las deprecaciones reciben ≥ 1 versión menor de advertencia con DeprecationWarning elevado en tiempo de ejecución, "Deprecated:" en la descripción de la herramienta MCP y una entrada en docs/MIGRATION-1.x-to-2.0.md (creada cuando se abre el trabajo de v2.0).

Cómo se aplica la promesa

Una prueba de instantánea de CI (tests/test_v1_schema_snapshot.py) congela la superficie de 22 herramientas en tests/snapshots/v1/tool_surface.json. Cualquier deriva falla en CI a menos que el PR establezca BREAKING_CHANGE_ACK=true Y existan tanto docs/MIGRATION-0.x-to-1.0.md como docs/DEPRECATION-POLICY.md. El acuse por sí solo no es un pase libre: los documentos deben estar en su lugar.

Una segunda prueba (tests/test_v1_doc_sync.py) escanea cada documento público en busca de afirmaciones sobre el número de herramientas y falla si alguna no coincide con el servidor en vivo.

Lee el contrato

Plan de evolución de licencia (anuncio v1.2.1)

MIT hoy. Apache 2.0 en v2.0.

mk-qa-master anuncia que relicenciará de MIT a Apache 2.0 en v2.0.0. Este parche (v1.2.1) es el anuncio formal y comienza el reloj de deprecación.

Qué cambia para ti

Si fijas...Qué obtienes
mk-qa-master==1.0.* / ==1.1.* / ==1.2.* etc.MIT para siempre — cada versión v1.x permanece con licencia MIT
mk-qa-master>=1,<2MIT mientras permanezcas en v1.x
mk-qa-master>=2,<3 (cuando v2.0 se lance)Apache 2.0

Apache 2.0 otorga estrictamente más derechos que MIT (concesión explícita de patentes + protección de marcas) manteniendo el mismo permiso de uso comercial. Ningún escenario reduce tus derechos de uso.

Cronograma

  • v1.2.1 (esta versión): solo anuncio. Sin cambios de código.
  • v1.3.x en adelante: todavía MIT. Mantener el ciclo durante al menos una versión menor antes de que llegue v2.0.
  • v2.0.0 (TBD): relicenciamiento real. Archivo LICENSE Apache 2.0, archivo NOTICE, barrido de cabeceras de código fuente, sincronización de manifiesto.

Además, un compromiso de mantener versiones de corrección de errores v1.x durante ≥ 6 meses después del lanzamiento de v2.0.0. Si tu empresa no puede mudarse a Apache 2.0 de inmediato, tienes un margen.

Por qué

Sostenibilidad a largo plazo: paz de patentes, protección de marcas, falta de ambigüedad en la propiedad intelectual de los contribuyentes, mayor compatibilidad con adquisiciones corporativas. Ver docs/RELICENSING.md para la justificación completa + lista de verificación mecánica de v2.0.

Ejecutor de IA en el borde (v1.1.0+)

Flujo RTSP + inferencia YOLO + aserciones pytest en un solo indicador QA_RUNNER=edge.

v1.1.0 añade un Ejecutor de Inferencia de IA en el borde que se integra en el mismo bucle analyze → generate → run que ya usan los ejecutores web y móviles. La nueva herramienta MCP analyze_stream (herramienta #22) sondea la geometría RTSP y emite casos de prueba candidatos por etiqueta detectada.

Instalación rápida

pip install "mk-qa-master[edge]"   # opencv-python + ultralytics + requests

# Plus the binary deps the runner shells out to:
brew install ffmpeg mediamtx       # macOS
# or: sudo apt install ffmpeg + download mediamtx from https://github.com/bluenviron/mediamtx

Recorrido de extremo a extremo

El fixture de muestra incluido en examples/sample_edge_fixture/ ejercita el bucle completo. Probado contra mk-qa-master==1.1.0 (Edge AI), mk-qa-master==1.1.1 (mantenimiento) y 1.1.2 (este parche de documentación).

1. Configura el ejecutor. Tres variables de entorno son suficientes para la ruta de escritorio:

export QA_RUNNER=edge
export QA_RTSP_SOURCE="$(pwd)/examples/sample_edge_fixture/factory.mp4"
export QA_MODEL_PATH=yolov8n.pt    # ultralytics auto-downloads on first use

Ajuste opcional (valores predeterminados entre paréntesis): QA_MIN_FPS (25), QA_LATENCY_SLA_MS (40), QA_IOU_THRESHOLD (0.5).

2. Pide a Claude / Cursor / cualquier host MCP. Con mk-qa-master conectado como servidor MCP (ver Conectar a Claude Desktop), indica:

"analiza el flujo en examples/sample_edge_fixture/factory.mp4 con el sidecar de anotaciones incluido, luego genera pruebas de detección para cada etiqueta."

Claude llama a analyze_stream → obtiene {width: 320, height: 240, fps: 5, labels: ["forklift", "person"], candidate_tcs: [...]} → llama a generate_test por etiqueta → escribe test_edge_factory_person.py y test_edge_factory_forklift.py en PROJECT_ROOT/tests/.

3. Ejecuta. El ejecutor levanta mediamtx + ffmpeg local (la fuente de archivo recorre RTSP), exporta las variables de entorno EDGE_* desde el QA_* que configuraste e invoca pytest. Cada prueba generada:

  • Lee fotogramas mediante cv2.VideoCapture(EDGE_RTSP_URL)
  • Pasa cada fotograma por el backend YOLO
  • Rastrea la latencia por fotograma en un LatencyTracker
  • Afirma que la detección por etiqueta aparece dentro del umbral IoU para al menos un fotograma en la ventana de verdad fundamental
  • Afirma que la latencia p95 ≤ EDGE_LATENCY_SLA_MS
  • Afirma que el rendimiento sostenido ≥ EDGE_MIN_FPS en una ventana de 150 fotogramas

El informe se guarda en PROJECT_ROOT/report.json + junit.xml, se archiva bajo test-results/history/ y activa get_optimization_plan como cualquier otro ejecutor.

Predeterminado de seguridad del host del proveedor

analyze_stream rechaza por defecto las URLs RTSP de dominios conocidos de cámaras de vigilancia / IoT (Dahua, Hikvision, Ezviz, Axis, Amcrest, Lorex, Swann, Reolink). Esto evita el sondeo accidental de transmisiones de cámaras públicas fuera de la ruta predeterminada. Establece QA_EDGE_ALLOW_VENDOR_HOSTS=true para optar por pruebas con tus propias cámaras.

Inyección de resiliencia (v1.3.0)

v1.3.0 añade un mecanismo opcional de degradación de red para ejecuciones Edge. Pasa resilience_mode="netem" a generate_test y el pytest generado utiliza tc qdisc de Linux (a través de mk_qa_master.edge.resilience.apply_netem) para inyectar 200 ms de latencia + 5 % de pérdida de paquetes en la interfaz de loopback, verifica que el ejecutor se mantenga dentro del SLA bajo degradación y luego limpia el qdisc al finalizar.

Doble protección por seguridad:

  • apply_netem lanza RuntimeError en sistemas que no sean Linux (hosts macOS / Windows → las pruebas pytest.skip automáticamente).
  • Incluso en Linux se niega a ejecutarse hasta que QA_EDGE_NETEM_ENABLED=true — consentimiento explícito para el impacto en loopback.

El mismo módulo también incluye tres ayudantes complementarios: clear_netem (limpieza idempotente), kill_ffmpeg_subprocess (escenario de pérdida de procesos) y build_corrupted_gop_fixture (inyección de ruido de bitstream impulsada por ffmpeg). Consulta src/mk_qa_master/edge/resilience.py y el PRD de v1.3.0 para el menú completo.

Cuando las pruebas se ejecutan en modo resiliencia, el informe generado incluye un bloque aditivo edge_metrics por prueba (caídas de fotogramas, tiempo de recuperación, etc.). get_optimization_plan lo lee para mostrar 4 señales de flakiness específicas de Edge (tasa de fotogramas corruptos, desviación del tiempo de recuperación, ráfagas de caídas, violaciones sostenidas de latencia) junto con su combinación habitual de señales.

Estado de fases

FaseQuéEstado
1Ejecutor YOLO de escritorio + gestión de fuentes RTSP + métricas✅ v1.1.0
2Herramienta MCP analyze_stream + plantilla generate_test de edge✅ v1.1.0
mantenimientoFixture de muestra + CI edge-sample + sección de conocimiento Edge EN/zh-TW✅ v1.1.1
docsRecorrido del README + solución de problemas (esta sección)✅ v1.1.2
3Inferencia remota (RemoteHTTP.infer() + sonda real QA_JETSON_HOST)✅ v1.2.0
4Inyección de resiliencia + señales de flakiness Edge + escenarios de degradación✅ v1.3.0

Solución de problemas

SíntomaCausa probableSolución
Could not open RTSP stream: rtsp://localhost:8554/camffmpeg o mediamtx no están en PATH; la sonda de preparación agotó el tiempo de espera a los 10 sVerifica which ffmpeg mediamtx; si mediamtx está en otro lugar, establece QA_MEDIAMTX_BIN=/full/path/to/mediamtx; primera ejecución lenta en Apple Silicon — vuelve a ejecutar después del primer arranque de mediamtx
[edge] setup failed: ConnectionErrorEl puerto 8554 ya está en uso por otro mediamtx / servidor RTSPEstablece QA_RTSP_PORT=8555 (o cualquier puerto libre); la prueba generada lee EDGE_RTSP_URL por lo que no se necesita editar la prueba
{ "error": "missing_extras", "hint": ... } de analyze_streamInstalación base sin extras de [edge]pip install "mk-qa-master[edge]" (o ejecuta mk-qa-master doctor para auditar la instalación completa)
{ "error": "forbidden_vendor_host", "blocked_host": "..." }Lista negra activada por defecto (Dahua / Hikvision / etc.)Si es tu propia cámara: export QA_EDGE_ALLOW_VENDOR_HOSTS=true. Si no lo es: deja el bloqueo en su lugar
NotImplementedError: RemoteHTTP backend lands in v1.2 (Phase 3 of theme G)Estableciste QA_JETSON_HOST o QA_INFERENCE_ENDPOINT contra v1.1.xv1.1 solo incluye LocalYolo. Desactiva las variables de entorno remotas para volver al YOLO de escritorio. La Fase 3 llega en v1.2
ultralytics tarda muchísimo en instalarsePrimera descarga de torch (~700 MB)Costo único. Almacena en caché pip install en CI; localmente usa pip install --no-deps una vez que torch esté en su lugar
La prueba generada verifica hit, "label X not detected" pero el fixture de muestra es solo testsrcEl patrón de prueba sintético no contiene personas / montacargas realesEsperado para el fixture incluido (es solo verificación de plomería). Sustituye con metraje real + anotaciones reales para aserciones de detección reales; consulta examples/sample_edge_fixture/README.md
La aserción de latencia p95 se dispara en CPU pero pasa en GPUEl QA_LATENCY_SLA_MS=40 predeterminado asume inferencia en GPUAumenta QA_LATENCY_SLA_MS para ejecuciones en CPU (yolov8n típico en CPU: 60–120 ms). Consulta la tabla de valores predeterminados de SLA en get_qa_context(section="Edge Vision Inference")
ffmpeg se queja de Stream #0:0: Video: ... at 5/1 fpsEl fixture de muestra tiene intencionalmente fps bajos (5) para mantener el binario en 75KBEsperado. Para pruebas reales, proporciona tu propia fuente con fps más altos

Migración de v1.0.0 → v1.1.x

v1.0.0 → v1.1.0 es solo aditivo — ninguna herramienta existente cambió de forma. v1.1.0 → v1.1.1 → v1.1.2 son versiones de parche (mantenimiento + docs). v1.2.0 añadió la Fase 3 (inferencia remota). v1.3.0 añadió la Fase 4 (inyección de resiliencia + señales de flakiness Edge). Consulta docs/MIGRATION-1.x.md para el registro de cambios completo + la lista de nuevas variables de entorno QA_* (QA_EDGE_NETEM_ENABLED, …).

PRD completo: docs/prd-v1.1-edge-ai-runner.md.

Libro de cierre universal de plan + verificación (v0.10.0)

Declara el éxito por adelantado, ejecuta el trabajo, recibe una lista de verificación — en cada herramienta significativa, no solo en una.

v0.10.0 generaliza el patrón de libro de cierre de v0.9.4 (que vivía solo en run_api_security_scan) a 5 herramientas principales. Cada una acepta un kwarg opcional plan_id devuelto por qa_plan. Cuando pasas ese plan_id, la respuesta de la herramienta gana un envoltorio plan_verification que verifica automáticamente el trabajo contra los puntos críticos que declaraste — sin necesidad de una llamada separada a verify_plan.

HerramientaForma de evidenciaCP típico
run_testsMatriz tests de pytest-json-report (resultado por prueba)"test_login passes" / "suite duration < 30s"
solve_visual_challengeRegistro único: {kind, status, token_populated, rounds_used, fingerprint, challenge_id}el token crudo NUNCA en la evidencia"captcha solved AND token_populated"
analyze_urlUna fila por módulo descubierto (con kind, selectors, URL de origen)"form module discovered" / "≥1 cta found"
auto_generate_testsUna fila por prueba generada (éxito o fallo)"form module produced ≥1 test" / "no generation errors"
run_api_security_scan (v0.9.4)Una fila por hallazgo de OWASP"BOLA finding on /orders endpoint"
plan = qa_plan(
    task="Smoke the signup flow",
    critical_points=[
        {"id": "CP1", "verification_hint": "test_happy_path passes"},
        {"id": "CP2", "verification_hint": "BOLA-on-orders"},
    ],
)

result = run_tests(plan_id=plan["plan_id"])

# result["plan_verification"]["status"] == "passed" | "incomplete" | "failed"
# result["plan_verification"]["checklist"] tells you per-CP outcomes

Compatibilidad hacia atrás: omitir plan_id mantiene la forma de respuesta de v0.9.x intacta. Consulta docs/prd-v0.10-universal-bookend.md para los contratos de evidencia por herramienta y las decisiones bloqueadas.

Conectar a Claude Desktop (ruta heredada solo MCP)

Si prefieres la conexión de servidor MCP pura (sin capa de plugin/habilidad), copia examples/configs/claude_desktop_config.example.json a:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Dos variables de entorno controlan el tiempo de ejecución:

VariableEjemploQué hace
QA_RUNNERpytest / jest / cypress / go / maestro / schemathesis / newmanSelecciona qué framework de pruebas
QA_PROJECT_ROOT/path/to/your/projectApunta al proyecto bajo prueba
QA_ANDROID_HOST (opcional)127.0.0.1:5555Endpoint ADB remoto para BlueStacks / Genymotion / Nox / Android en la nube. Cuando se establece, el ejecutor Maestro ejecuta automáticamente adb connect <host> antes de cada llamada a prueba / analyze_screen. Requiere adb en PATH.
QA_TIMEOUT_SECONDS (opcional)600 (predeterminado)Límite máximo para cualquier invocación de subproceso individual (pytest / jest / cypress / go test / maestro). Devuelve exit_code=124 con una etiqueta [TIMEOUT…] en stderr cuando se excede, para que el cliente de IA pueda reaccionar limpiamente en lugar de colgar el servidor MCP para siempre.

Fragmento por ejecutor

pytest-playwright:

"env": { "QA_RUNNER": "pytest", "QA_PROJECT_ROOT": "/path/to/python-project" }

Jest:

"env": { "QA_RUNNER": "jest", "QA_PROJECT_ROOT": "/path/to/node-project" }

Cypress:

"env": { "QA_RUNNER": "cypress", "QA_PROJECT_ROOT": "/path/to/cypress-project" }

Go test:

"env": { "QA_RUNNER": "go", "QA_PROJECT_ROOT": "/path/to/go-project" }

Maestro (móvil, desde v0.3.0):

"env": {
  "QA_RUNNER": "maestro",
  "QA_PROJECT_ROOT": "/path/to/maestro-flows",
  "QA_ANDROID_HOST": "127.0.0.1:5555"
}

QA_ANDROID_HOST es opcional — solo establécelo cuando apuntes a BlueStacks / Genymotion / granja de Android en la nube mediante ADB remoto. El simulador de iOS / emulador de Android / dispositivo USB local se auto-descubren.

Schemathesis (API):

"env": {
  "QA_RUNNER": "schemathesis",
  "QA_OPENAPI_URL": "https://api.example.com/openapi.json"
}

Newman (Postman):

"env": {
  "QA_RUNNER": "newman",
  "QA_POSTMAN_COLLECTION": "/absolute/path/to/collection.json"
}

Edge AI (RTSP + YOLO, desde v1.1.0):

"env": {
  "QA_RUNNER": "edge",
  "QA_RTSP_SOURCE": "/absolute/path/to/factory.mp4",
  "QA_MODEL_PATH": "yolov8n.pt"
}

Requiere pip install "mk-qa-master[edge]" + ffmpeg + mediamtx en PATH. Consulta el recorrido del ejecutor Edge AI para la tabla completa de variables de entorno y la solución de problemas.


Otros clientes MCP

MCP es un protocolo abierto — este servidor no es exclusivo de Claude. El mismo proceso de Python habla con cualquier cliente MCP a través de JSON-RPC stdio. Lo que difiere entre clientes es (1) el formato del archivo de configuración y (2) cuán confiablemente el modelo subyacente encadena automáticamente las llamadas a herramientas.

ClienteConfigFormatoModeloCalidad de cadena de herramientas
Claude Desktop / Cursor~/Library/Application Support/Claude/...json · ~/.cursor/mcp.jsonJSONClaude Opus / SonnetMejor probado
Codex CLI~/.codex/config.tomlTOMLFamilia GPT-5Fuerte (bien entrenado en encadenamiento de herramientas)
Gemini CLI~/.gemini/settings.jsonJSONGemini 3.1 Pro / FlashFunciona; prefiere indicaciones explícitas ("primero analiza, luego escribe")
Cline / Continue / Zedcada uno tiene su propia ranura de configuración MCPvaríavaríadepende del modelo configurado

Los ejemplos de configuración se incluyen en el repositorio: codex-config.example.toml · gemini-config.example.json · claude_desktop_config.example.json.

Codex (TOML):

[mcp_servers.mk-qa-master]
command = "/path/to/.venv/bin/python"
args = ["-m", "mk_qa_master.server"]
cwd = "/path/to/mk-qa-master"
[mcp_servers.mk-qa-master.env]
QA_RUNNER = "pytest"
QA_PROJECT_ROOT = "/path/to/your-test-project"

Gemini (JSON, misma forma que Claude Desktop):

{
  "mcpServers": {
    "mk-qa-master": {
      "command": "/path/to/.venv/bin/python",
      "args": ["-m", "mk_qa_master.server"],
      "cwd": "/path/to/mk-qa-master",
      "env": {
        "QA_RUNNER": "pytest",
        "QA_PROJECT_ROOT": "/path/to/your-test-project"
      }
    }
  }
}

Las descripciones de herramientas ya sugieren las cadenas recomendadas (analyze_url → generate_test, get_qa_context antes de generar pruebas de dominio). Los clientes con selección de herramientas más débil se benefician más de indicaciones explícitas que nombren los pasos.


Superficie de herramientas

Compartido en todos los ejecutores (algunas herramientas se degradan con elegancia en ejecutores que no son pytest):

HerramientaPropósito
get_runner_infoQué ejecutor está activo + todos los disponibles
list_testsEnumerar pruebas en el proyecto
run_testsEjecutar pruebas (filtro / con ventana / navegador; los dos últimos solo pytest-playwright)
run_failedRe-ejecutar últimos fallos (pytest --lf)
get_test_reportResumen (aprobado / fallido / omitido / duración / flaky-en-ejecución)
get_failure_detailsMensaje por fallo + rutas de captura de pantalla / traza / video
generate_testEsqueleto de prueba; con module de analyze_url/analyze_screen, uno ejecutable (Playwright .py o Maestro .yaml)
auto_generate_testsDe una sola vez: analizar URL → generar una prueba por módulo descubierto
codegenLanzar codegen de Playwright (web) / sugerencia a maestro studio (móvil)
generate_html_reportRenderizar la última ejecución como HTML autocontenido
get_test_historyResúmenes de las últimas N ejecuciones archivadas (para depuración de tendencias / flakiness)
analyze_urlWeb: sonda DOM → módulos + selectores + casos de prueba candidatos + endpoints de API + advertencias de desbordamiento de diseño
analyze_screenMóvil: maestro hierarchy → módulos de formulario / cta / tab_bar + casos de prueba candidatos (filtrados por ruido)
init_qa_knowledge / get_qa_contextCrear + leer la capa de conocimiento de QA del proyecto (metodología + dominio). Bilingüe desde v0.6.2 — la metodología se envía en inglés por defecto (QA_LANG=en) o chino tradicional (QA_LANG=zh-tw); las mismas 13 secciones en ambos, las cuatro más nuevas cubren metodología de pruebas de API, taxonomía de causa raíz de flakiness, dobles de prueba (mock / stub / fake / spy) y gestión de datos de prueba. Ejemplo de dominio: docs/qa-knowledge-en.example.md (zh-TW: docs/qa-knowledge.example.md).
get_optimization_planEntrenador de auto-mejora de tres capas (suite / MCP / estrategia de IA)
inspect_visual_challenge / solve_visual_challengev0.7.0 Solucionador de desafíos visuales de IA — detectar un desafío de cuadrícula de imágenes reCAPTCHA v2, capturarlo, aceptar la selección de mosaicos del cliente de IA, ejecutar la cadena de clics. Controlado por QA_VISUAL_CHALLENGE_CONSENT=true + confirm=true por llamada. Consulta la sección dedicada arriba.
run_api_security_scanv0.8.0 Escáner basado en reglas de OWASP API Security Top 10 (2023) — cargar una especificación OpenAPI 3.x, recorrer ruta × método, despachar 5 reglas en alcance (API1 BOLA, API2 Broken Auth, API3 Mass Assignment, API5 Function-Level Authz, API8 Misconfig). Controlado por QA_API_SECURITY_CONSENT=true + QA_API_SECURITY_AUTHORIZED_DOMAINS. Consulta la sección dedicada arriba.

Recursos

URIQué
report://htmlInforme HTML renderizado en vivo (modo oscuro, autocontenido)
report://jsonJSON crudo de pytest-json-report
report://optimizationÚltimo optimization-plan.md

Bucle de auto-mejora

Después de cada ejecución, _archive_report() toma instantáneas de report.json en test-results/history/ y escribe un nuevo optimization-plan.md que cubre:

  1. Calidad del conjunto — cadena de resultados por prueba (PFPFP); transiciones → puntuación de flakiness; 3+ fallos con firma idéntica → roto; repetición aprobada → flaky en la ejecución
  2. Usabilidad de MCP — herramientas principales, tasas de error, patrones de argumentos repetidos, cadenas comunes A→B (de los registros JSONL de telemetría)
  3. Estrategia de IA — tasa de adopción de las salidas de generate_test, brechas de cobertura de los módulos analyze_url sin archivos de prueba coincidentes

El plan emite acciones priorizadas (high / medium / low) cada una con objetivo + evidencia + sugerencia + auto_action_hint opcional que el cliente MCP puede encadenar en la siguiente llamada de herramienta.


Estructura del proyecto

mk-qa-master/
├── pyproject.toml
├── src/mk_qa_master/
│   ├── server.py            # MCP entry (tool routing + telemetry wrap)
│   ├── config.py            # Paths + env vars
│   ├── runners/             # Per-framework plugins
│   │   ├── base.py          # TestRunner abstract interface
│   │   ├── pytest_playwright.py
│   │   ├── jest.py
│   │   ├── cypress.py
│   │   └── go_test.py
│   ├── reporters/
│   │   └── html.py          # Self-contained HTML render
│   └── tools/               # Thin shims + analyzer + optimizer + telemetry
└── tests_project/           # Example project under test

Añadir un runner

  1. Crea src/mk_qa_master/runners/your_runner.py, subclase de TestRunner, implementa los métodos abstractos
  2. Registra el nombre en el REGISTRY de runners/__init__.py
  3. Listo

Flujo de trabajo de extremo a extremo

La tubería prevista — desde una URL hasta "¿qué debería mejorar la próxima vez?":

flowchart LR
    URL[URL] -->|analyze_url| MOD[modules<br/>+ candidate TCs<br/>+ API endpoints]
    MOD -->|generate_test<br/>module=...| TEST[tests/test_*.py<br/>runnable skeleton]
    TEST -->|run_tests| RES[report.json<br/>+ screenshots<br/>+ trace.zip<br/>+ junit.xml]
    RES -->|auto archive| HIST[history/ snapshot]
    RES -->|generate_html_report| HTML[HTML report<br/>self-contained]
    HIST -->|auto write| PLAN[optimization-plan.md]
    PLAN -.->|next session reads| URL

El bucle es el punto: cada ejecución alimenta al optimizador, el optimizador apunta al eslabón más débil, la siguiente ejecución golpea ese eslabón primero.

Recorrido — probar una página de inicio de sesión

En una sesión de Claude / Cursor:

: Analiza https://shop.example/login, ayúdame a escribir las pruebas correspondientes

Claude: [analyze_url] Encontré 1 formulario (email_password_form_0) + 3 endpoints de API. 5 TCs candidatos. [generate_test con el módulo de formulario] Escribí tests/test_login.py — ejecutable con selectores concretos, sin stubs de # TODO.

: Ejecuta

Claude: [run_tests] 23 aprobadas, 0 fallidas en 31s. Capturas de pantalla + trazas de pasos capturadas para cada prueba.

: ¿Qué debería hacer a continuación?

Claude: [abre report://optimization] Principal: tests/test_login.py::test_invalid_credentials es flaky (flake_score=0.4, outcomes=PFPFP). Sugerencia: añade wait_for_response('/api/login') antes de afirmar el mensaje de error.

Las tres lentes del optimizador (calidad del conjunto / usabilidad de MCP / efectividad de generación de IA) hacen que cada respuesta de "¿qué sigue?" esté basada en datos, no en intuición.

Recorrido — probar una aplicación móvil (Maestro)

Misma forma, runner diferente. Requiere Maestro CLI instalado + simulador/emulador iniciado + tu aplicación lanzada (o pasa launch_app=true con app_id):

: Analiza el botón de código de barras en la página de inicio de tu aplicación móvil, escribe las pruebas correspondientes

Claude: [analyze_screen(app_id="com.example.app", launch_app=true)] Encontré 15 elementos interactivos; coincidí con barcode_button (text="條碼", resource_id="barcodeButton") + TCs candidatos. [generate_test con el módulo cta] Escribí maestro-flows/test_barcode.yamltapOn: { id: barcodeButton } + waitForAnimationToEnd + takeScreenshot, listo para maestro test.

: Ejecuta

Claude: [run_tests] 5 flujos pasan, el reintento no se disparó. Capturas de pantalla incrustadas en el informe HTML.

: Este botón a veces falla, ¿por qué?

Claude: [get_optimization_plan] barcode_button::barcode_button marcó flaky (flake_score=0.4, outcomes=PFPFP, rerun_count=1). Sugerencia: añade waitForAnimationToEnd o extendedWaitUntil espera a que la animación se estabilice antes de tocar.

Notas específicas para móviles:

  • El mismo qa-knowledge.md (metodología integrada + tu dominio) alimenta tanto las ejecuciones web como móviles — escribe tus reglas de negocio una vez.
  • analyze_screen filtra la barra de estado de iOS (señal / wifi / batería) y las etiquetas de nombres de activos (bg_*, *_filled); el resultado es rico en señales.
  • La directiva takeScreenshot: <name> de Maestro controla qué pantallas aparecen como imágenes en línea en el informe HTML.

Recetario de prompts

Cada fila muestra una frase que puedes pegar en una sesión de Claude / Cursor y la llamada de herramienta MCP subyacente que debería desencadenar. Úsalo como referencia para "¿cómo hago que la IA haga X sin nombrar la herramienta yo mismo?"

Configuración única

Tú dicesClaude llama
"Inicializa el archivo de conocimiento de QA."init_qa_knowledge → escribe qa-knowledge.md en la raíz de tu proyecto
"Muéstrame el conocimiento de QA actual."get_qa_context → secciones de metodología + tu dominio
"Abre la sección de principios ISTQB."get_qa_context(section="ISTQB")

Pruebas diarias

Tú dicesClaude llama
"Ejecuta todas las pruebas."run_tests
"Ejecuta solo las pruebas relacionadas con el inicio de sesión."run_tests(filter="login")
"Re-ejecuta solo los fallos."run_failed
"Muéstrame el resumen."get_test_report
"¿Cuáles fallaron? Dame capturas de pantalla y traza."get_failure_details
"Genera el informe HTML."generate_html_report

Crear pruebas desde una URL (web)

Tú dicesClaude llama
"Auto-genera pruebas para https://shop.example/."auto_generate_tests(url=...) — de una sola vez
"Analiza https://shop.example/coupon primero, luego escribe una prueba por módulo."analyze_urlgenerate_test × N
"Analiza la página de cupones y escribe una prueba de regresión para nuestro bug de idempotencia pasado."get_qa_context(section="Bug")analyze_urlgenerate_test(business_context=...)
"Solo graba un flujo de checkout como línea base."codegen(url=...)

Crear pruebas desde una pantalla móvil (Maestro)

Requiere QA_RUNNER=maestro, Maestro CLI y un simulador/emulador/dispositivo iniciado.

Tú dicesClaude llama
"Analiza la pantalla actual de tu aplicación móvil y escribe una prueba para el botón de código de barras."analyze_screen(app_id="com.example.app", launch_app=true)generate_test(module=<cta>)
"Prueba el formulario de inicio de sesión en esta aplicación."analyze_screen(launch_app=true) → elige el módulo formgenerate_test
"Cubre la barra de pestañas — escribe un flujo por pestaña."analyze_screen → toma el módulo tab_bargenerate_test
"Usa Maestro Studio para grabar un flujo."codegen(url=...) devuelve una pista apuntando a maestro studio (grabar + guardar manualmente)

BlueStacks / instancias remotas de Android: establece QA_ANDROID_HOST=127.0.0.1:5555 (o el host:puerto que BlueStacks exponga — ver Configuración → Avanzado → Android Debug Bridge). El runner de Maestro hará adb connect antes de cada prueba y analyze_screen, y aumenta el tiempo de espera de hierarchy a 60s para absorber la ruta TCP-ADB más lenta. Genymotion / Nox / LDPlayer / WSA funcionan de la misma manera; cualquier host:port que responda a adb connect es válido.

Mejora continua

Tú dicesClaude llama
"¿Qué debería arreglar a continuación?"get_optimization_plan
"¿Ha estado test_login_invalid flaky últimamente?"get_test_history + búsqueda de plan
"¿Por qué falló? Muéstrame la traza."get_failure_details (devuelve rutas de captura/traza/video)

Consejos — lograr que Claude elija la herramienta correcta

  • Menciona el conocimiento de QA explícitamente — "referencia el conocimiento de QA al probar cupones" empuja a Claude a llamar a get_qa_context primero; decir solo "probar cupones" puede omitirlo.
  • Indica el orden — "analiza primero, luego escribe" fuerza analyze_url antes de generate_test; "solo escribe una prueba para X" omite el análisis.
  • Lote vs preciso — "auto-genera toda la página" → auto_generate_tests; "escribe una prueba por candidate_tc" → cadena manual.
  • Depuración de fallos — Preguntar "¿por qué falló / muéstrame la captura" desencadena de manera confiable get_failure_details (que ahora devuelve rutas de captura + traza + video).

Anti-patrones

  • ❌ "Ejecútalo 5 veces para ver si es flaky" — el runner tiene reintento automático + historial; solo pregunta "¿es flaky?" y deja que get_optimization_plan responda.
  • ❌ "Genera 100 pruebas" — ruido > señal. Usa get_optimization_plan primero para encontrar lo que falta.
  • ❌ "Prueba todos los casos límite" — demasiado vago. Formúlalo como "prueba cada candidate_tc para este formulario" — concreto, acotado, trazable.

Ejemplos de salidas

analyze_url (extracto)

{
  "url": "https://shop.example/login",
  "page_title": "Login",
  "module_count": 3,
  "modules": [
    {
      "kind": "form",
      "name": "email_password_form_0",
      "selectors": {
        "container": "#login",
        "fields": [
          {"label": "Email", "selector": "#email", "type": "email", "required": true},
          {"label": "Password", "selector": "#password", "type": "password", "required": true}
        ],
        "submit": "button[type='submit']"
      },
      "candidate_tcs": [
        "所有必填欄位為空時送出,應顯示必填錯誤",
        "Email 欄位填入格式錯誤的字串(無 @),應顯示格式錯誤",
        "Password 欄位輸入後應預設遮蔽(type=password)",
        "全部填入合法值後送出,應觸發成功流程"
      ]
    }
  ],
  "api_endpoints": [
    {
      "method": "POST",
      "path": "/api/login",
      "status": 401,
      "candidate_tcs": [
        "POST /api/login payload 缺必填欄位應回 400 + 欄位錯誤訊息",
        "POST /api/login 合法 payload 應回 2xx",
        "POST /api/login 缺少 auth header 應回 401/403"
      ]
    }
  ]
}

Salida de generate_test (inteligente, con módulo)

"""
Login happy path

Auto-generated from analyze_url module: email_password_form_0 (kind=form)
"""
from playwright.sync_api import Page, expect


def test_login(page: Page):
    page.goto('https://shop.example/login')
    page.locator('#email').fill('test@example.com')
    page.locator('#password').fill('TestPass123!')
    page.locator("button[type='submit']").click()
    # TC: Email 欄位填入格式錯誤的字串(無 @),應顯示格式錯誤
    # TC: Password 欄位輸入後應預設遮蔽
    # TC: 正確 Email + 正確密碼 → 導向 dashboard
    # TODO: 補上實際斷言,例如:
    # expect(page).to_have_url(...)
    # expect(page.get_by_text("成功")).to_be_visible()

optimization-plan.md (extracto)

# Optimization Plan — 2026-05-12T14:03:40

_Based on 6 archived runs._

## Prioritized Actions

### 1. 🔴 HIGH — flaky
- **Target**: `tests/test_login.py::test_invalid_credentials`
- **Evidence**: flake_score=0.4, outcomes=PFPFP, rerun_count=1
- **Suggestion**: 加 explicit wait(wait_for_response / locator wait)

### 2. 🟡 MEDIUM — coverage_gap
- **Target**: `register_form`
- **Evidence**: 由 analyze_url 偵測但 repo 內找不到對應 test_*.py
- **Suggestion**: `call generate_test(description="...", filename="test_register_form.py")`

Informe HTML

Abrir la demo renderizada en vivo → (servido a través de GitHub Pages — hacer clic en el enlace en la interfaz de GitHub a sample_report.html solo mostraría el código fuente).

La demo muestra la cuadrícula de estadísticas, el sparkline de tendencia, tarjetas de fallos con capturas de pantalla incrustadas + listas de pasos, y la sección de Aprobados colapsada.


Integraciones

mk-qa-master no incluye SDKs de terceros — se mantiene como una capa pura de ejecución de pruebas + análisis. Los flujos de trabajo reales de QA se componen ejecutando múltiples servidores MCP lado a lado en la misma configuración de cliente; Claude orquesta la cadena entre servidores. No hay RPC de MCP a MCP — cada servidor es independiente, el cliente de IA es el director.

Los emparejamientos a continuación son los que completan el bucle con más frecuencia:

Emparejar conPor quéCadena de ejemplo
Atlassian MCP (JIRA + Confluence)Abrir tickets de bug automáticamente desde fallos; sincronizar optimization-plan.md a una página de Confluence del equiporun_testsget_failure_detailsatlassian.createJiraIssue (adjunta captura + ruta de traza)
Slack MCPNotificar canales en fallos, compartir el informe HTML renderizado, mencionar al oncall para pruebas flakygenerate_html_reportslack.send_message(channel="#qa-bots", attachments=...)
GitHub MCPLeer la descripción del PR / issues vinculados para contexto de negocio antes de generar pruebas; publicar resultados como comentarios en el PRgithub.get_pull_requestanalyze_urlgenerate_test(business_context=PR body)github.create_issue_comment
Sentry MCPLos errores de producción impulsan la prioridad de regresión: los principales crashes → pruebas de regresión coincidentessentry.list_issues(sort="frequency")generate_test(business_context=stack trace)run_tests
Filesystem MCPLeer un qa-knowledge.md compartido o archivos fuente de TC que viven fuera de QA_PROJECT_ROOT (monorepos, configuraciones multi-proyecto)filesystem.read_file("~/shared/qa-knowledge.md")init_qa_knowledge

Mención honorífica — Google Drive MCP: se empareja con la gestión de TC basada en Google Sheets (leer TCs de una hoja → generate_test → escribir el estado de vuelta).

Componiendo en tu configuración de cliente

Los cinco se ejecutan como procesos separados junto a mk-qa-master:

{
  "mcpServers": {
    "mk-qa-master": { "command": "python", "args": ["-m", "mk_qa_master.server"], "env": { "QA_RUNNER": "maestro" } },
    "atlassian":       { "command": "npx", "args": ["-y", "@atlassian/mcp"] },
    "slack":           { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-slack"] },
    "github":          { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"] }
  }
}

Luego un solo prompt recorre la cadena:

"Ejecuta la suite de checkout. Para cada fallo, abre un JIRA en el proyecto QA con el formato RIDER y la captura adjunta. Publica el informe HTML en #qa-bots cuando termines."

Por qué esto importa: mk-qa-master se mantiene enfocado en el bucle de pruebas (analizar → generar → ejecutar → entrenar). JIRA / Slack / Sentry son dominios completos con sus propios servidores dedicados — integrarlos en este diluiría el alcance, duplicaría el manejo de autenticación y obligaría a cada usuario a heredar dependencias que quizás no quiera.

Este repo no incluye ningún SDK de terceros — mantiene la responsabilidad única de «ejecución de pruebas + análisis». En la práctica, el flujo de trabajo de QA se logra con múltiples servidores MCP coexistiendo, con Claude orquestando la cadena de herramientas entre servidores. Ejemplos de emparejamientos: JIRA / Slack / GitHub / Sentry / Filesystem cada uno como servidor MCP independiente, junto con mk-qa-master para armar el pipeline completo de pruebas.


Publicación (solo mantenedores)

Los lanzamientos se publican en PyPI mediante Trusted Publishing — no se almacenan tokens de API en el repo. El flujo:

  1. Incrementa version = "x.y.z" en pyproject.toml (mediante un PR normal — main está protegido por rama).
  2. Después del merge, etiqueta main y haz push:
    git tag -a vX.Y.Z -m "vX.Y.Z — short summary"
    git push origin vX.Y.Z
    
  3. Crea un GitHub Release para esa etiqueta (gh release create vX.Y.Z ...).
  4. El evento de release dispara .github/workflows/publish.yml → construye sdist + wheel → sube a PyPI.

Configuración única de PyPI (debe hacerse una vez antes de que funcione la primera publicación):

  • Inicia sesión en https://pypi.org → habilita 2FA.
  • Página del proyecto → Configuración → Publicación → añade un editor pendiente con:
    • Propietario: kao273183
    • Repositorio: mk-qa-master
    • Nombre del archivo de workflow: publish.yml
    • Nombre del entorno: pypi

Después de la primera ejecución exitosa, PyPI promueve automáticamente el editor pendiente a uno de confianza y los lanzamientos posteriores se autentican mediante OIDC.

El workflow se niega a publicar si la etiqueta del release no coincide con pyproject.version, lo que detecta errores de "etiquetado pero olvidé incrementar" antes de que lleguen a PyPI.


Apoya el proyecto ☕

mk-qa-master está construido y mantenido en solitario por las noches y los fines de semana. Si te ha ahorrado tiempo o ha moldeado cómo tu equipo piensa sobre QA impulsado por IA, un café mantiene las sesiones de depuración de Maestro hasta altas horas:

Buy Me a Coffee Tu apoyo financia: mantener este repo gratuito y activamente mantenido, más variantes de dispositivos para pruebas con Maestro (iPhones reales / tablets Android / BlueStacks), tutoriales grabados para la comunidad de QA, y la próxima caza de bugs a las 2 a. m.

Sin anuncios, sin patrocinios, sin ventas empresariales — solo el trabajo.


Contribuciones

Este repo se mantiene en solitario. Las ideas y los informes de errores son muy bienvenidos — por favor abre un Issue o inicia una Discusión. Leo cada uno e implementaré lo que encaje con la dirección del proyecto.

Las pull requests externas se cierran automáticamente. No porque las contribuciones no se aprecien, sino porque mantener la coherencia del código bajo una sola voz importa más aquí que el rendimiento que aportaría un modelo de múltiples contribuyentes. Si realmente quieres un cambio específico, un Issue que describa el problema te llevará más lejos que un PR.

Este repo lo mantengo yo solo. Las ideas y los informes de errores son bienvenidos a través de Issue / Discussion; los evaluaré e implementaré personalmente. Las PR externas se cierran automáticamente — no es que no se aprecien las contribuciones, sino que quiero mantener la coherencia del estilo y la dirección del código.


Licencia

MIT © 2026 Jack Kao — ver LICENSE (Referencia de traducción al chino: LICENSE.zh-TW.md; la versión en inglés es la autoritativa).

En lenguaje sencillo: puedes usar esto para cualquier cosa (proyectos personales, trabajo comercial, modificaciones, redistribución). Lo único que se pide es que conserves el aviso de copyright + licencia en cualquier copia que distribuyas. No hay garantía — úsalo bajo tu propio riesgo.