AI 測試大師 / mcp-test-runner
AI 測試大師 — Servidor MCP que executa pytest / Jest / Cypress / Go / Maestro. Analisa, gera, executa, aconselha. Web + Mobile (iOS/Android/BlueStacks).
Documentação
MK QA Master
AI 測試大師 — seu loop de QA com IA, da análise ao aconselhamento.
English · 繁體中文
Servidor MCP universal para executar testes em pytest / Jest / Cypress / Go, com analisador de DOM integrado, histórico de execuções e um coach de autoaperfeiçoamento. Estável desde v1.0.0 (2026-06-02) — veja Promessa de estabilidade abaixo.
Um servidor Model Context Protocol que permite ao Claude Desktop / Cursor / qualquer cliente MCP conduzir sua suíte de testes de ponta a ponta: executar testes, inspecionar falhas (captura de tela + vídeo + trace), analisar uma URL ao vivo para rascunhar casos de teste e — após cada execução — produzir um plano de ação priorizado dizendo exatamente o que corrigir ou escrever em seguida.
QA_RUNNER | Framework | Linguagem | Alvo |
|---|---|---|---|
pytest / pytest-playwright / playwright | pytest + Playwright | Python | Web |
jest | Jest | JavaScript | Web |
cypress | Cypress | JavaScript | Web |
go / go-test | go test | Go | Backend |
maestro / mobile | Maestro | YAML | iOS + Android |
schemathesis / api | Schemathesis | OpenAPI 3.x / Swagger 2.0 | API (desde v0.6.0) |
newman / postman | Newman | Postman collection v2.x | API (desde v0.6.1) |
Notas de design completas: docs/framework.md.
O que está incluso
-
Executar testes em vários frameworks (web + mobile + API) por meio de uma única superfície MCP
-
Mobile via Maestro (desde v0.3.0): mesmas ferramentas MCP, iOS Simulator / Android Emulator / dispositivo real; fluxos YAML; multiplataforma sem reescritas
-
Teste de API nativo — dois runners (desde v0.6.0 / v0.6.1): dois pares agora compartilham o slot de teste de API, cada um alimentado pelo artefato que sua equipe já mantém.
- Schemathesis (
QA_RUNNER=schemathesis, desde v0.6.0): aponte para um URL OpenAPI 3.x / Swagger 2.0 ou schemafile://e obtenha testes baseados em propriedades com fuzzing cobrindo códigos de status, schemas de resposta, tipos de conteúdo e violações de5xx-em-fuzz. - Newman (
QA_RUNNER=newman, desde v0.6.1): aponte para uma collection Postman 2.x exportada (mais arquivos opcionais de environment / globals) e o Newman reproduz cada requisição, executa as asserçõespm.test(...)incorporadas e retorna um nodeid mk-qa-master por asserção. Newman é um pré-requisito de sistema (npm install -g newman) — é um pacote npm, não pip, então não acompanha um extra Python.
Ambos se integram à mesma superfície de ferramentas MCP que os runners web / mobile, e ambos alimentam o mesmo pipeline de
report.json/ histórico / flake / otimizador. Testes de API existentes escritos em pytest+httpx, Jest+supertest, Cypresscy.request()ou Gonet/http/httptestcontinuam usando seus runners existentes — sem necessidade de migração. A verificação de provedor Pact permanece no roadmap condicional v0.7.0. - Schemathesis (
-
Artefatos de falha: captura de tela (embutida em base64), vídeo, Playwright trace.zip / gravações Maestro
-
Histórico de execuções: cada execução é capturada; o relatório HTML mostra uma tendência sparkline
-
Analisador de DOM / tela —
analyze_urlpara web (formulários / navegação / diálogos / CTAs + os endpoints de API que a página acessa) eanalyze_screenpara mobile (maestro hierarchy→ módulos form / cta / tab_bar) -
Geração inteligente de testes (
generate_test): forneça um módulo de analisador e ele escreve um Playwright.pyou Maestro.yamlexecutável com seletores concretos, não stubs# TODO -
Nova tentativa automática de flakes — lado pytest via
pytest-rerunfailures; lado Maestro via wrapper de nova tentativa personalizado (sem--rerunsnativo); testes instáveis são exibidos separadamente de falhas reais -
Coach de autoaperfeiçoamento (
get_optimization_plan): análise pós-execução em três lentes — qualidade da suíte, usabilidade do MCP, eficácia da geração de IA -
Saída JUnit XML para integrações de CI (GitHub Actions / Jenkins / GitLab)
Instalação
Dois caminhos — escolha o que corresponde a como você usará.
A. Executar via uvx (zero instalação, recomendado para usuários finais)
Adicione mk-qa-master à configuração do seu cliente sem instalar nada globalmente; uv baixa e executa em um ambiente efêmero por sessão:
{
"mcpServers": {
"mk-qa-master": {
"command": "uvx",
"args": ["mk-qa-master"],
"env": { "QA_RUNNER": "pytest", "QA_PROJECT_ROOT": "/path/to/your-test-project" }
}
}
}
Essa é toda a configuração. A primeira chamada baixa o pacote; chamadas subsequentes são armazenadas em cache. Alternar versões: uvx mk-qa-master@0.4.1 ....
B. Instalar em um venv de projeto (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
Em seguida, aponte a configuração do seu cliente para o mesmo interpretador Python:
"command": "/path/to/.venv/bin/python",
"args": ["-m", "mk_qa_master.server"]
Verificar a instalação (v1.4+)
mk-qa-master doctor # human-readable check report
mk-qa-master doctor --json # for CI gates / host-LLM consumption
Verifica a versão do Python, ffmpeg + mediamtx no PATH, dependências principais, extras [edge], registro de runners e a superfície de ferramentas MCP. Sai com 0 quando nada crítico está faltando (avisos sobre recursos não utilizados não falham), 1 quando o mk-qa-master não consegue executar corretamente. Execute após uma instalação nova ou quando uma ferramenta MCP retornar missing_extras.
Pré-requisitos específicos do runner
QA_RUNNER | Você também precisa |
|---|---|
pytest / pytest-playwright | pip install pytest-playwright + playwright install chromium |
jest | Um projeto Node com jest instalado (npm i -D jest) |
cypress | Um projeto Node com cypress instalado (npm i -D cypress) |
go | Toolchain Go no PATH |
maestro | CLI Maestro + um simulador / emulador / dispositivo iniciado (ou BlueStacks acessível via adb connect) |
schemathesis / api | pip install 'mk-qa-master[api]' (inclui schemathesis>=3.0,<4) |
newman / postman | npm install -g newman (Newman é um pacote npm, não pip — nenhum extra para instalar) |
Teste de API (QA_RUNNER=schemathesis)
Aponte o runner para qualquer schema OpenAPI 3.x / Swagger 2.0 e o Schemathesis
gera casos de teste baseados em propriedades por operação — cobrindo
conformidade de schema de resposta, conformidade de código de status, verificações de tipo de conteúdo e
5xx-em-fuzz. Os resultados fluem pelo mesmo pipeline de report.json / histórico /
flake / otimizador que seus testes de UI.
O passo a passo completo está em docs/walkthrough-api.md;
uma amostra autossuficiente de 3 endpoints está em
examples/sample_api_project/.
Configuração em 5 linhas
"env": {
"QA_RUNNER": "schemathesis",
"QA_OPENAPI_URL": "https://api.example.com/openapi.json"
}
Variáveis de ambiente
| Variável | Obrigatória | Padrão | O que faz |
|---|---|---|---|
QA_OPENAPI_URL | sim | — | URL OpenAPI. http(s)://... para schemas ao vivo, file://... para arquivos locais. Caminhos de sistema de arquivos simples não são aceitos — eles precisam do prefixo file://. |
QA_SCHEMATHESIS_CHECKS | não | all | Subconjunto separado por vírgulas: response_schema_conformance,status_code_conformance,not_a_server_error,content_type_conformance,response_headers_conformance. |
QA_SCHEMATHESIS_AUTH | não | — | Valor do cabeçalho de autorização. Enviado como -H "Authorization: <value>". Nunca registrado; redigido em relatórios arquivados. |
QA_SCHEMATHESIS_MAX_EXAMPLES | não | 20 | Exemplos de Hypothesis por operação. Maior = fuzz mais profundo, execução mais lenta. |
QA_SCHEMATHESIS_DRY_RUN | não | 0 | Defina como 1 para planejar-sem-HTTP — útil para pré-visualização de segurança contra produção, ou fumaça de CI contra um artefato somente de schema. |
QA_NO_REDACT | não | 0 | Desativa a redação de segredos em relatórios arquivados. O padrão redige Authorization: Bearer …, "password": …, "token" / "api_key" / "secret" / "access_token" / "refresh_token": …. |
O QA_TIMEOUT_SECONDS padrão ainda se aplica (padrão 600s).
Teste de API (QA_RUNNER=newman)
Aponte o runner para qualquer collection Postman 2.x exportada e o Newman 6.x
reproduz cada requisição, executa as asserções pm.test(...) incorporadas e
retorna um "teste" mk-qa-master por asserção. Os resultados fluem pelo
mesmo pipeline de report.json / histórico / flake / otimizador que os
runners Schemathesis e UI.
Pré-requisito de sistema: Newman é distribuído via npm, não pip. Instale uma vez:
npm install -g newman
Não há extra pip install 'mk-qa-master[postman]' — o runner
apenas chama o binário newman no PATH. Se estiver ausente, o
runner gera um ImportError claro apontando para a linha de instalação npm.
A mesma API de Biblioteca de 3 endpoints que a amostra OpenAPI usa
é distribuída como uma collection Postman em
examples/sample_api_project/postman-collection.json —
combine-a com prism mock examples/sample_api_project/openapi.yaml para
um loop de desenvolvimento totalmente autossuficiente, ou aponte para seu próprio servidor de staging.
Configuração em 5 linhas
"env": {
"QA_RUNNER": "newman",
"QA_POSTMAN_COLLECTION": "/absolute/path/to/your-collection.json"
}
Variáveis de ambiente
| Variável | Obrigatória | Padrão | O que faz |
|---|---|---|---|
QA_POSTMAN_COLLECTION | sim | — | Caminho de sistema de arquivos simples para um JSON de collection Postman 2.x. Sem prefixo file:// — Newman não precisa de desambiguação de esquema, pois collections são sempre artefatos locais. |
QA_POSTMAN_ENVIRONMENT | não | — | Caminho simples para um arquivo de environment Postman (-e <path>). Fornece valores para placeholders {{var_name}} na collection. |
QA_POSTMAN_GLOBALS | não | — | Caminho simples para um arquivo de globals Postman (-g <path>). Mesma forma do environment, com escopo global. |
QA_POSTMAN_ITERATIONS | não | 1 | Reproduz a collection inteira N vezes (-n <N>). Útil para testes de imersão e detecção de flakes. |
QA_POSTMAN_FOLDER | não | — | CSV de nomes de pastas Postman para restringir a execução (flags --folder repetidas). run_failed também usa escopo de pasta quando falhas se concentram em pastas conhecidas. |
QA_POSTMAN_TIMEOUT_REQUEST_MS | não | 30000 | Timeout HTTP por requisição em milissegundos (--timeout-request). Distinto de QA_TIMEOUT_SECONDS, que limita todo o subprocesso. |
QA_NO_REDACT | não | 0 | Mesma política de redação que o runner Schemathesis — desative apenas para sessões curtas de depuração. |
O QA_TIMEOUT_SECONDS padrão ainda se aplica (padrão 600s).
Solucionador Visual de Desafios de IA (v0.7.0)
Quando o bypass de backend não é uma opção: Claude olha o CAPTCHA, mk-qa-master faz os cliques.
Suporta reCAPTCHA v2 (desde v0.7.0) e hCaptcha (desde v0.7.1).
A primeira capacidade da família onde a visão do cliente de IA é
essencial, não opcional. Duas novas ferramentas MCP
(inspect_visual_challenge + solve_visual_challenge) detectam um
desafio de grade de imagens reCAPTCHA v2 ou hCaptcha na página Playwright
ativa, capturam a tela para o cliente de IA multimodal, aceitam a
seleção de blocos que a IA retorna e executam a cadeia de cliques. O
runner é os olhos e as mãos; o cliente de IA (Claude / Cursor / Gemini
/ GPT-4o) é o solucionador real.
Quando usar isso — Nível 1 vs Nível 3
A camada de conhecimento de QA integrada (get_qa_context section="CAPTCHA")
codifica três níveis. Use-os em ordem:
| Nível | Abordagem | Quando |
|---|---|---|
| 1 — bypass | Chaves de teste reCAPTCHA, feature flags, allowlist de IP, cabeçalhos de modo de teste | Padrão. Cobre ~90% dos casos. |
| 2 — degradar | Marcar como external_dependency, pular asserções downstream | Quando você não pode alterar o backend, mas o teste não é sobre o CAPTCHA em si. |
| 3 — julgamento visual de IA | Este recurso. | Somente quando 1 + 2 não se aplicam (sites de clientes com autorização, mas sem acesso ao backend, staging que espelha o CAPTCHA de produção, webviews mobile onde o allowlist de IP não é acessível). |
Portão de consentimento
O solucionador não faz nada até que você opte explicitamente. Duas variáveis de ambiente o controlam:
| Variável | Obrigatória | Padrão | O que faz |
|---|---|---|---|
QA_VISUAL_CHALLENGE_CONSENT | sim | false | Deve ser definida como true para que qualquer uma das ferramentas funcione. Sem ela, ambas as ferramentas retornam um erro consent_required com o aviso legal completo (o cliente de IA exibe isso ao usuário). |
QA_VISUAL_CHALLENGE_AUTHORIZED_DOMAINS | não (recomendado) | — | Lista de permissões separada por vírgulas de domínios onde a ferramenta pode operar. Quando DEFINIDA, recusa qualquer outro domínio. Quando NÃO DEFINIDA, apenas avisa — prossegue, mas carimba a resposta com um aviso dizendo para você definir uma. Recomendado para ambientes de CI compartilhados / multi-tenant. |
QA_VISUAL_CHALLENGE_TIMEOUT | não | 120 | Orçamento de tempo real em segundos para o ciclo inspecionar→resolver. Respeita QA_TIMEOUT_SECONDS como teto rígido. |
Início 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"
}
Então, quando uma chamada run_tests apresentar uma falha external_dependency
que aponte para um CAPTCHA, o cliente de IA pode 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."
O passo a passo completo está em docs/walkthrough-visual-challenge.md.
PRD: docs/prd-v0.7-visual-challenge.md.
Domínios com bloqueio rígido
Independentemente de consentimento ou lista de permissões, o solucionador se recusa a operar em
provedores de identidade de terceiros conhecidos (accounts.google.com,
login.microsoftonline.com, id.apple.com, facebook.com,
login.live.com, etc.). Nenhum cenário legítimo de QA justifica um
solucionador de CAPTCHA contra o portal de login de outra pessoa.
Privacidade
Nenhuma retenção de capturas de tela além do ciclo ativo inspecionar→resolver. A telemetria registra apenas o resultado booleano — nunca a captura de tela, nunca o texto do desafio, nunca a seleção de blocos. O cache LRU de 5 minutos armazena no máximo 10 desafios pendentes por processo e nunca toca o disco.
Ressalva sobre a taxa de sucesso
O modelo de visão do cliente de IA faz o julgamento real — Claude Sonnet
4, GPT-4o e Gemini 2.5 todos têm visão nativa, mas sua
precisão em um reCAPTCHA 3x3 varia. Planeje pelo menos uma nova tentativa por
desafio (o reCAPTCHA dá três antes de bloquear). get_telemetry
eventualmente apresentará a taxa de aprovação agregada para que você possa dimensionar essa
expectativa por cliente.
Escopo: apenas grade de imagens reCAPTCHA v2 na v0.7.0. hCaptcha chega na v0.7.1. reCAPTCHA v3 / Cloudflare Turnstile estão permanentemente fora de escopo — eles não apresentam um desafio visível para inspecionar.
Varredura de Segurança de API OWASP (v0.8.0)
Schemathesis detecta desvios de correção. A v0.8.0 adiciona a camada que detecta o desvio de segurança escondido atrás de um esquema que passa.
A v0.8.0 traz um scanner baseado em regras OWASP API Security Top 10 (2023)
como uma nova ferramenta MCP: run_api_security_scan. Ele carrega uma especificação OpenAPI 3.x,
percorre cada (caminho × método) e despacha cinco regras puramente observáveis por HTTP:
| OWASP # | Regra | Gravidade quando acionada |
|---|---|---|
| API1 | BOLA / IDOR — o token da alice lê o objeto do bob via adulteração de id no caminho | CRÍTICA |
| API2 | Autenticação Quebrada — o servidor aceita JWTs alg:none, malformados ou com assinatura errada | MÉDIA / ALTA / CRÍTICA por sonda |
| API3 | Atribuição em Massa — o servidor persiste campos extras perigosos como role: admin, is_verified: true | ALTA |
| API5 | Autorização em Nível de Função — usuário não-admin acessa endpoints com formato de admin | ALTA |
| API8 | Configuração de Segurança Incorreta — cabeçalhos HSTS/CSP/X-Frame ausentes, CORS curinga com credenciais | BAIXA / MÉDIA / ALTA |
API4 (risco de DoS por limite de taxa), API6 (modelagem de fluxo de negócios), API7
(infraestrutura de callback SSRF), API9 (reconhecimento de produção), API10 (APIs upstream) estão
adiadas — veja docs/prd-v0.8-api-security.md §3.
Portões de consentimento + autorização
Espelha o modelo de consentimento de desafio visual da v0.7:
| Variável | Obrigatória | O que faz |
|---|---|---|
QA_API_SECURITY_CONSENT | sim | Deve ser true. Sem ela, retorna consent_required. |
QA_API_SECURITY_AUTHORIZED_DOMAINS | sim para hosts externos | Lista de permissões separada por vírgulas. Localhost / 127.0.0.1 são implicitamente autorizados. |
A regra mass_assignment muta o estado do servidor — está excluída das
categorias padrão. Os chamadores devem optar por participar:
categories=["headers", "broken_auth", "bola", "function_authz", "mass_assignment"].
Início 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"
}
Então peça ao cliente de IA para escanear:
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"
)
Retorna o bloco de relatório de segurança da 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}}
}
A verdade fundamental do Nível 1
examples/sample_vulnerable_api/ traz um aplicativo Flask deliberadamente vulnerável
onde cada categoria OWASP no escopo tem um par de endpoint vulnerável/seguro.
Execute-o localmente para ver como cada regra se parece na
prática:
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
O scanner encontra todas as 5 categorias em /vuln/* e produz zero
falsos positivos em /safe/*. Essa propriedade é garantida pelos
testes dogfood do Nível 1 em
cada PR.
Nota de segurança
O scanner executa casos de teste adversariais. Não o aponte para sistemas de produção que você não possui, e não o aponte para qualquer sistema onde você não tenha autorização. As duas variáveis de ambiente acima são o contrato.
PRD: docs/prd-v0.8-api-security.md.
A tentativa móvel anterior da v0.8 foi arquivada — veja
docs/v0.8-mobile-postmortem.md para
o que aprendemos e como isso moldou os portões de teste do PRD de segurança de API.
Uso como habilidade Claude Code / Codex / Hermes / OpenClaw (v0.9.0)
A mesma pasta de habilidade carrega em quatro hosts de agente diferentes via convenção agentskills.io.
A v0.9.0 empacota o mk-qa-master como uma habilidade de agente entre hosts além
da sua forma de servidor MCP. A pasta skills/mk-qa-master/ é a única fonte
de verdade — os mesmos SKILL.md, comandos de barra e documentos de referência
carregam em:
- Claude Code — via
.claude-plugin/plugin.json(este repositório é um marketplace de plugins). - OpenAI Codex — via
.codex-plugin/plugin.json(Codex lê marketplaces no estilo Claude). - OpenClaw — instale a partir do checkout local:
openclaw plugins install /path/to/mk-qa-master. - Hermes Agent — crie um link simbólico da pasta de habilidade em
~/.hermes/skills/.
Instalação rápida (Claude Code)
# Inside Claude Code:
/plugin marketplace add kao273183/mk-qa-master
/plugin install mk-qa-master@mk-qa-master
Reinicie o Claude Code para que a habilidade seja registrada. Então qualquer prompt de teste de QA ativa automaticamente a habilidade — ou invoque explicitamente um 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
O que a habilidade faz
A habilidade é um contrato operacional de arquivo único que ensina o host a conduzir as 22 ferramentas MCP do mk-qa-master de forma coerente. Ela codifica:
- Quando ativar automaticamente — frases como "execute meus testes", "por que este teste falhou", "escaneie esta API para problemas OWASP" a acionam.
- Cinco fluxos — executar testes / gerar testes / depurar falhas / resolver CAPTCHAs / escanear APIs.
- Regras rígidas — apresentar erros de consentimento textualmente, não re-executar silenciosamente com filtros relaxados, confirmar antes de execuções destrutivas.
Referência completa em skills/mk-qa-master/SKILL.md.
Por que uma habilidade além de um servidor MCP?
O servidor MCP torna as 22 ferramentas chamáveis por qualquer cliente. A habilidade as torna descobríveis + governadas: ela dá ao roteador de habilidades do host contexto suficiente para decidir quando usar as ferramentas e qual fluxo seguir. Inspirado por microsoft/Webwright, que usa o mesmo padrão.
Promessa de estabilidade (v1.0.0)
22 ferramentas. Esquema congelado. Desvio versionado. Fixe e vá.
O mk-qa-master lançou a v1.0.0 em 2026-06-02. A superfície de ferramentas MCP está bloqueada: 22 ferramentas, as variáveis de ambiente do portão de consentimento, as formas de plano / bookend e as listas negras de bloqueio rígido não mudam sem um ciclo de depreciação.
O que isso significa para os chamadores
| Se você fixar… | O que você obtém |
|---|---|
mk-qa-master==1.0.* | Apenas releases de correção (correções de bugs; sem mudança de superfície) |
mk-qa-master==1.* | Releases menores (apenas aditivos: novas ferramentas, novos argumentos opcionais, novos campos) |
mk-qa-master>=1,<2 | O mesmo que acima |
Mudanças que quebram exigem um aumento para v2.0. Depreciações recebem ≥ 1 menor de aviso com DeprecationWarning levantado em tempo de execução, "Deprecated:" na descrição da ferramenta MCP e uma entrada em docs/MIGRATION-1.x-to-2.0.md (criada quando o trabalho da v2.0 abre).
Como a promessa é aplicada
Um teste de snapshot de CI (tests/test_v1_schema_snapshot.py) congela a superfície de 22 ferramentas em tests/snapshots/v1/tool_surface.json. Qualquer desvio falha no CI, a menos que o PR defina BREAKING_CHANGE_ACK=true E ambos docs/MIGRATION-0.x-to-1.0.md e docs/DEPRECATION-POLICY.md existam. O reconhecimento sozinho não é um passe livre — a documentação deve estar no lugar.
Um segundo teste (tests/test_v1_doc_sync.py) escaneia todos os documentos públicos em busca de alegações de contagem de ferramentas e falha se algum discordar do servidor ativo.
Leia o contrato
docs/MIGRATION-0.x-to-1.0.md— cada mudança aditiva de forma v0.7 → v1.0 enumerada. Resumo: v0.10 → v1.0 é um no-op.docs/DEPRECATION-POLICY.md— ciclo formal. patch = correção de bug, minor = aditivo, major = remoção (apenas após depreciação).docs/prd-v1.0-stability-lock.md— PRD bloqueado.
Plano de evolução de licença (anúncio v1.2.1)
MIT hoje. Apache 2.0 na v2.0.
O mk-qa-master está anunciando que relicenciará de MIT para Apache 2.0 na v2.0.0. Este patch (v1.2.1) é o anúncio formal e inicia o relógio de depreciação.
O que muda para você
| Se você fixar... | O que você obtém |
|---|---|
mk-qa-master==1.0.* / ==1.1.* / ==1.2.* etc. | MIT para sempre — cada release v1.x permanece licenciado sob MIT |
mk-qa-master>=1,<2 | MIT enquanto você permanecer na v1.x |
mk-qa-master>=2,<3 (quando a v2.0 for lançada) | Apache 2.0 |
O Apache 2.0 concede estritamente mais direitos que o MIT (concessão explícita de patentes + proteção de marca registrada) mantendo a mesma permissão de uso comercial. Nenhum cenário reduz seus direitos de uso.
Cronograma
- v1.2.1 (este release): apenas anúncio. Nenhuma mudança de código.
- v1.3.x em diante: ainda MIT. Ciclo de espera por pelo menos um minor antes da v2.0 chegar.
- v2.0.0 (a definir): relicenciamento real. Arquivo LICENSE Apache 2.0, arquivo NOTICE, varredura de cabeçalhos de fonte, sincronização de manifesto.
Além de um compromisso de manter releases de correção v1.x por ≥ 6 meses após a v2.0.0 ser lançada. Se sua empresa não puder migrar para Apache 2.0 imediatamente, você tem uma margem de tempo.
Por quê
Sustentabilidade de longo prazo — paz de patentes, proteção de marca registrada, não ambiguidade de IP do contribuidor, maior compatibilidade de aquisição corporativa. Veja docs/RELICENSING.md para a justificativa completa + checklist mecânico da v2.0.
Runner de IA de borda (v1.1.0+)
Stream RTSP + inferência YOLO + asserções pytest em um único flag
QA_RUNNER=edge.
A v1.1.0 adiciona um Runner de Inferência de IA de Borda que se encaixa no mesmo loop analyze → generate → run que os runners web e mobile já usam. A nova ferramenta MCP analyze_stream (ferramenta #22) testa a geometria RTSP e emite casos de teste candidatos por rótulo detectado.
Instalação 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
Passo a passo de ponta a ponta
A fixture de amostra incluída em examples/sample_edge_fixture/ exercita o loop completo. Testada contra mk-qa-master==1.1.0 (Edge AI), mk-qa-master==1.1.1 (housekeeping) e 1.1.2 (este patch de documento).
1. Configure o runner. Três variáveis de ambiente são suficientes para o caminho desktop:
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 (padrões entre parênteses): QA_MIN_FPS (25), QA_LATENCY_SLA_MS (40), QA_IOU_THRESHOLD (0.5).
2. Peça ao Claude / Cursor / qualquer host MCP. Com o mk-qa-master conectado como servidor MCP (veja Conecte ao Claude Desktop), solicite:
"analise o stream em
examples/sample_edge_fixture/factory.mp4com o sidecar de anotações incluído, então gere testes de detecção para cada rótulo."
O Claude chama analyze_stream → obtém {width: 320, height: 240, fps: 5, labels: ["forklift", "person"], candidate_tcs: [...]} → chama generate_test por rótulo → escreve test_edge_factory_person.py e test_edge_factory_forklift.py em PROJECT_ROOT/tests/.
3. Execute. O runner inicia mediamtx + ffmpeg locais (a fonte de arquivo faz loop sobre RTSP), exporta as variáveis de ambiente EDGE_* do QA_* que você definiu e invoca o pytest. Cada teste gerado:
- Lê frames via
cv2.VideoCapture(EDGE_RTSP_URL) - Envia cada frame pelo backend YOLO
- Rastreia a latência por frame em um
LatencyTracker - Afirma que a detecção por rótulo aparece dentro do limite IoU para pelo menos um frame na janela de verdade fundamental
- Afirma que a latência p95 ≤
EDGE_LATENCY_SLA_MS - Afirma que a taxa de transferência sustentada ≥
EDGE_MIN_FPSem uma janela de 150 frames
O relatório chega em PROJECT_ROOT/report.json + junit.xml, é arquivado em test-results/history/ e aciona get_optimization_plan como qualquer outro runner.
Padrão de segurança do host do fornecedor
analyze_stream recusa URLs RTSP em domínios conhecidos de fornecedores de câmeras de vigilância / IoT (Dahua, Hikvision, Ezviz, Axis, Amcrest, Lorex, Swann, Reolink) por padrão. Mantém a sondagem acidental de feeds de câmeras públicas fora do caminho padrão. Defina QA_EDGE_ALLOW_VENDOR_HOSTS=true para optar por testes com suas próprias câmeras.
Injeção de resiliência (v1.3.0)
v1.3.0 adiciona um harness opcional de degradação de rede para execuções Edge. Passe resilience_mode="netem" para generate_test e o pytest emitido usa Linux tc qdisc (via mk_qa_master.edge.resilience.apply_netem) para injetar 200 ms de latência + 5 % de perda de pacotes na interface loopback, verifica se o runner permanece dentro do SLA sob degradação e, em seguida, limpa o qdisc no teardown.
Duplamente protegido por segurança:
apply_netemlançaRuntimeErrorem não-Linux (hosts macOS / Windows → testespytest.skipautomaticamente).- Mesmo no Linux, ele se recusa a executar até
QA_EDGE_NETEM_ENABLED=true— consentimento explícito para o impacto no loopback.
O mesmo módulo também inclui três helpers complementares: clear_netem (teardown idempotente), kill_ffmpeg_subprocess (cenário de perda de processo) e build_corrupted_gop_fixture (injeção de ruído de bitstream via ffmpeg). Consulte src/mk_qa_master/edge/resilience.py e o PRD v1.3.0 para o menu completo.
Quando os testes são executados em modo de resiliência, o relatório emitido carrega um bloco edge_metrics aditivo por teste (quedas de frame, tempo de recuperação, etc.). get_optimization_plan o lê para expor 4 sinais de flake específicos do Edge (taxa de frames corrompidos, desvio de tempo de recuperação, rajadas de queda, violações sustentadas de latência) junto com sua mistura usual de sinais.
Status das fases
| Fase | O quê | Status |
|---|---|---|
| 1 | Runner YOLO desktop + gerenciamento de fontes RTSP + métricas | ✅ v1.1.0 |
| 2 | Ferramenta MCP analyze_stream + template generate_test de edge | ✅ v1.1.0 |
| housekeeping | Fixture de exemplo + CI edge-sample + seção de conhecimento Edge EN/zh-TW | ✅ v1.1.1 |
| docs | Passo a passo do README + solução de problemas (esta seção) | ✅ v1.1.2 |
| 3 | Inferência remota (RemoteHTTP.infer() + sonda real QA_JETSON_HOST) | ✅ v1.2.0 |
| 4 | Injeção de resiliência + sinais de flake Edge + cenários de degradação | ✅ v1.3.0 |
Solução de problemas
| Sintoma | Causa provável | Correção |
|---|---|---|
Could not open RTSP stream: rtsp://localhost:8554/cam | ffmpeg ou mediamtx não está no PATH; a sonda de prontidão expirou em 10 s | Verifique which ffmpeg mediamtx; se o mediamtx estiver em outro lugar, defina QA_MEDIAMTX_BIN=/full/path/to/mediamtx; primeira execução lenta no Apple Silicon — execute novamente após o primeiro boot do mediamtx |
[edge] setup failed: ConnectionError | Porta 8554 já em uso por outro servidor mediamtx / RTSP | Defina QA_RTSP_PORT=8555 (ou qualquer porta livre); o teste gerado lê EDGE_RTSP_URL, então nenhuma edição de teste é necessária |
{ "error": "missing_extras", "hint": ... } de analyze_stream | Instalação base sem extras [edge] | pip install "mk-qa-master[edge]" (ou execute mk-qa-master doctor para auditar a instalação completa) |
{ "error": "forbidden_vendor_host", "blocked_host": "..." } | Blacklist ativada por padrão (Dahua / Hikvision / etc.) | Se for sua própria câmera: export QA_EDGE_ALLOW_VENDOR_HOSTS=true. Se não for: deixe o bloqueio no lugar |
NotImplementedError: RemoteHTTP backend lands in v1.2 (Phase 3 of theme G) | Você definiu QA_JETSON_HOST ou QA_INFERENCE_ENDPOINT contra v1.1.x | v1.1 inclui apenas LocalYolo. Remova as env vars remotas para voltar ao YOLO desktop. A Fase 3 vem na v1.2 |
ultralytics demorando para instalar | Download inicial do torch (~700 MB) | Custo único. Armazene em cache pip install no CI; localmente use pip install --no-deps depois que o torch estiver instalado |
O teste gerado verifica hit, "label X not detected", mas a fixture de exemplo é apenas testsrc | O padrão de teste sintético não contém pessoas / empilhadeiras reais | Esperado para a fixture incluída (é apenas verificação de encanamento). Substitua por filmagens reais + anotações reais para asserções de detecção reais; veja examples/sample_edge_fixture/README.md |
| A asserção de latência p95 dispara na CPU, mas passa na GPU | O QA_LATENCY_SLA_MS=40 padrão assume inferência em GPU | Aumente QA_LATENCY_SLA_MS para execuções em CPU (yolov8n típico em CPU: 60–120 ms). Consulte a tabela de padrões de SLA em get_qa_context(section="Edge Vision Inference") |
ffmpeg reclama sobre Stream #0:0: Video: ... at 5/1 fps | A fixture de exemplo tem fps intencionalmente baixo (5) para manter o binário em 75KB | Esperado. Para testes reais, forneça sua própria fonte com fps mais alto |
Migração de v1.0.0 → v1.1.x
v1.0.0 → v1.1.0 é apenas aditivo — nenhuma ferramenta existente mudou de forma. v1.1.0 → v1.1.1 → v1.1.2 são releases de patch (manutenção + docs). v1.2.0 adicionou a Fase 3 (inferência remota). v1.3.0 adicionou a Fase 4 (injeção de resiliência + sinais de flake Edge). Consulte docs/MIGRATION-1.x.md para o changelog completo + a lista de novas env vars QA_* (QA_EDGE_NETEM_ENABLED, …).
PRD completo: docs/prd-v1.1-edge-ai-runner.md.
Plano universal + bookend de verificação (v0.10.0)
Declare o sucesso antecipadamente, execute o trabalho, receba um checklist de volta — em toda ferramenta significativa, não apenas uma.
v0.10.0 generaliza o padrão de bookend da v0.9.4 (que existia apenas em
run_api_security_scan) para 5 ferramentas principais. Cada uma aceita um
kwarg opcional plan_id retornado por qa_plan. Quando você passa esse
plan_id, a resposta da ferramenta ganha um envelope plan_verification
que verifica automaticamente o trabalho contra os pontos críticos que você
declarou — sem necessidade de chamada separada de verify_plan.
| Ferramenta | Formato da evidência | CP típico |
|---|---|---|
run_tests | array tests do pytest-json-report (resultado por teste) | "test_login passes" / "suite duration < 30s" |
solve_visual_challenge | Registro único: {kind, status, token_populated, rounds_used, fingerprint, challenge_id} — token bruto NUNCA em evidência | "captcha solved AND token_populated" |
analyze_url | Uma linha por módulo descoberto (com kind, selectors, URL da fonte) | "form module discovered" / "≥1 cta found" |
auto_generate_tests | Uma linha por teste gerado (sucesso ou falha) | "form module produced ≥1 test" / "no generation errors" |
run_api_security_scan (v0.9.4) | Uma linha por achado 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
Compatibilidade retroativa: omitir plan_id mantém o formato de resposta v0.9.x
intacto. Consulte docs/prd-v0.10-universal-bookend.md
para os contratos de evidência por ferramenta e as decisões travadas.
Integrar ao Claude Desktop (caminho legado apenas MCP)
Se você preferir a conexão direta do servidor MCP (sem camada de plugin/skill), copie
examples/configs/claude_desktop_config.example.json para:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Duas variáveis de ambiente controlam o runtime:
| Variável | Exemplo | O que faz |
|---|---|---|
QA_RUNNER | pytest / jest / cypress / go / maestro / schemathesis / newman | Seleciona qual framework de teste |
QA_PROJECT_ROOT | /path/to/your/project | Aponta para o projeto em teste |
QA_ANDROID_HOST (opcional) | 127.0.0.1:5555 | Endpoint Remote-ADB para BlueStacks / Genymotion / Nox / Android em nuvem. Quando definido, o runner Maestro executa automaticamente adb connect <host> antes de cada chamada de teste / analyze_screen. Requer adb no PATH. |
QA_TIMEOUT_SECONDS (opcional) | 600 (padrão) | Teto rígido em qualquer invocação única de subprocesso (pytest / jest / cypress / go test / maestro). Retorna exit_code=124 com uma tag [TIMEOUT…] no stderr quando excedido, para que o cliente de IA possa reagir de forma limpa em vez de travar o servidor MCP para sempre. |
Trecho por runner
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 (mobile, 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 é opcional — defina apenas ao usar BlueStacks / Genymotion / farm Android em nuvem via ADB remoto. iOS Simulator / Android Emulator / dispositivo USB local são descobertos automaticamente.
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"
}
Requer pip install "mk-qa-master[edge]" + ffmpeg + mediamtx no PATH. Consulte o passo a passo do Edge AI Runner para a tabela completa de env vars e solução de problemas.
Outros clientes MCP
MCP é um protocolo aberto — este servidor não é exclusivo do Claude. O mesmo processo Python conversa com qualquer cliente MCP via JSON-RPC stdio. O que difere entre clientes é (1) o formato do arquivo de configuração e (2) a confiabilidade com que o modelo subjacente encadeia automaticamente chamadas de ferramentas.
| Cliente | Config | Formato | Modelo | Qualidade de encadeamento de ferramentas |
|---|---|---|---|---|
| Claude Desktop / Cursor | ~/Library/Application Support/Claude/...json · ~/.cursor/mcp.json | JSON | Claude Opus / Sonnet | Mais testado |
| Codex CLI | ~/.codex/config.toml | TOML | Família GPT-5 | Forte (bem treinado em encadeamento de ferramentas) |
| Gemini CLI | ~/.gemini/settings.json | JSON | Gemini 3.1 Pro / Flash | Funciona; prefere prompts explícitos ("primeiro analise, depois escreva") |
| Cline / Continue / Zed | cada um tem seu próprio slot de configuração MCP | varia | varia | depende do modelo configurado |
Exemplos de configuração acompanham o repositório:
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, mesmo formato do 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"
}
}
}
}
As descrições de ferramentas já sugerem as cadeias recomendadas
(analyze_url → generate_test, get_qa_context antes de gerar
testes de domínio). Clientes com seleção de ferramentas mais fraca se beneficiam mais de
prompts explícitos que nomeiam as etapas.
Superfície de ferramentas
Compartilhada entre todos os runners (algumas ferramentas degradam graciosamente em runners não-pytest):
| Ferramenta | Finalidade |
|---|---|
get_runner_info | Qual runner está ativo + todos os disponíveis |
list_tests | Enumera testes no projeto |
run_tests | Executa testes (filtro / headed / browser; os dois últimos apenas pytest-playwright) |
run_failed | Reexecuta as últimas falhas (pytest --lf) |
get_test_report | Resumo (passou / falhou / pulado / duração / flaky na execução) |
get_failure_details | Mensagem por falha + caminhos de screenshot / trace / vídeo |
generate_test | Esqueleto de teste; com module de analyze_url/analyze_screen, um executável (Playwright .py ou Maestro .yaml) |
auto_generate_tests | One-shot: analisa URL → gera um teste por módulo descoberto |
codegen | Inicia o codegen do Playwright (web) / dica para maestro studio (mobile) |
generate_html_report | Renderiza a última execução como HTML autocontido |
get_test_history | Resumos das últimas N execuções arquivadas (para depuração de tendência / flake) |
analyze_url | Web: sonda DOM → módulos + seletores + TCs candidatos + endpoints de API + avisos de overflow de layout |
analyze_screen | Mobile: maestro hierarchy → módulos form / cta / tab_bar + TCs candidatos (filtrados por ruído) |
init_qa_knowledge / get_qa_context | Scaffold + leitura da camada de conhecimento de QA do projeto (metodologia + domínio). Bilíngue desde v0.6.2 — a metodologia é fornecida em inglês por padrão (QA_LANG=en) ou chinês tradicional (QA_LANG=zh-tw); as mesmas 13 seções em ambos, as quatro mais recentes cobrem metodologia de teste de API, taxonomia de causa raiz de flakiness, test doubles (mock / stub / fake / spy) e gerenciamento de dados de teste. Exemplo de domínio: docs/qa-knowledge-en.example.md (zh-TW: docs/qa-knowledge.example.md). |
get_optimization_plan | Coach de autoaperfeiçoamento em três camadas (suíte / MCP / estratégia de IA) |
inspect_visual_challenge / solve_visual_challenge | v0.7.0 AI Visual Challenge Solver — detecta um desafio de grade de imagens reCAPTCHA v2, captura a tela, aceita a seleção de tiles do cliente de IA, executa a cadeia de cliques. Controlado por QA_VISUAL_CHALLENGE_CONSENT=true + confirm=true por chamada. Consulte a seção dedicada acima. |
run_api_security_scan | v0.8.0 Scanner baseado em regras OWASP API Security Top 10 (2023) — carrega uma spec OpenAPI 3.x, percorre path × method, despacha 5 regras no escopo (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. Consulte a seção dedicada acima. |
Recursos
| URI | O quê |
|---|---|
report://html | Relatório HTML renderizado ao vivo (modo escuro, autocontido) |
report://json | JSON bruto do pytest-json-report |
report://optimization | Último optimization-plan.md |
Loop de autoaperfeiçoamento
Após cada execução, _archive_report() captura report.json em
test-results/history/ e grava um novo optimization-plan.md cobrindo:
- Qualidade da suíte — string de resultados por teste (
PFPFP); transições → pontuação de flakiness; 3+ falhas com assinatura idêntica → quebrado; passou no rerun → flaky-na-execução - Usabilidade do MCP — principais ferramentas, taxas de erro, padrões de argumentos repetidos, cadeias comuns A→B (a partir dos logs JSONL de telemetria)
- Estratégia de IA — taxa de adoção das saídas de
generate_test, lacunas de cobertura de módulosanalyze_urlsem arquivos de teste correspondentes
O plano emite ações priorizadas (high / medium / low), cada uma com
alvo + evidência + sugestão + auto_action_hint opcional que o cliente MCP
pode encadear na próxima chamada de ferramenta.
Estrutura do projeto
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
Adicionando um runner
- Crie
src/mk_qa_master/runners/your_runner.py, subclassifiqueTestRunner, implemente os métodos abstratos - Registre o nome em
runners/__init__.py'sREGISTRY - Pronto
Fluxo de trabalho ponta a ponta
O pipeline pretendido — de uma URL a "o que devo melhorar na 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
O loop é o ponto central: cada execução alimenta o otimizador, o otimizador aponta para o elo mais fraco, a próxima execução atinge esse elo primeiro.
Passo a passo — testando uma página de login
Em uma sessão do Claude / Cursor:
Você: 分析
https://shop.example/login,幫我寫對應測試Claude: [
analyze_url] Encontrei 1 formulário (email_password_form_0) + 3 endpoints de API. 5 TCs candidatos. [generate_testcom o módulo do formulário] Escrevitests/test_login.py— executável com seletores concretos, sem stubs de# TODO.
Você: 跑
Claude: [
run_tests] 23 passaram, 0 falharam em 31s. Capturas de tela + rastreios de etapas gravados para cada teste.
Você: 下一步該做什麼?
Claude: [abre
report://optimization] Principal:tests/test_login.py::test_invalid_credentialsestá flaky (flake_score=0.4, resultados=PFPFP). Sugestão: adicionewait_for_response('/api/login')antes de afirmar a mensagem de erro.
As três lentes do otimizador (qualidade da suíte / usabilidade do MCP / eficácia da geração de IA) tornam cada resposta de "下一步" baseada em dados, não em intuição.
Passo a passo — testando um aplicativo móvel (Maestro)
Mesma forma, runner diferente. Requer CLI do Maestro instalado +
simulador/emulador iniciado + seu aplicativo aberto (ou passe launch_app=true
com app_id):
Você: 分析 your mobile app 首頁的條碼按鈕、寫對應測試
Claude: [
analyze_screen(app_id="com.example.app", launch_app=true)] Encontrei 15 elementos interativos; correspondi abarcode_button(texto="條碼", resource_id="barcodeButton") + TCs candidatos. [generate_testcom o módulo cta] Escrevimaestro-flows/test_barcode.yaml—tapOn: { id: barcodeButton }+ waitForAnimationToEnd + takeScreenshot, pronto paramaestro test.
Você: 跑
Claude: [
run_tests] 5 fluxos passam, retry não disparou. Capturas de tela incorporadas no relatório HTML.
Você: 上面這個按鈕有時候會 fail、為什麼?
Claude: [
get_optimization_plan]barcode_button::barcode_buttonsinalizou flaky (flake_score=0.4, resultados=PFPFP, rerun_count=1). Sugestão: adicionewaitForAnimationToEndouextendedWaitUntile aguarde a animação estabilizar antes de tocar.
Notas específicas para mobile:
- O mesmo
qa-knowledge.md(metodologia integrada + seu domínio) alimenta execuções web e mobile — escreva suas regras de negócio uma única vez. analyze_screenfiltra a barra de status do iOS (sinal / wifi / bateria) e rótulos de nomes de assets (bg_*,*_filled); o resultado é rico em sinal.- A diretiva
takeScreenshot: <name>do Maestro controla quais telas aparecem como imagens inline no relatório HTML.
Livro de receitas de prompts
Cada linha mostra uma frase que você pode colar em uma sessão do Claude / Cursor e a chamada de ferramenta MCP subjacente que ela deve acionar. Use como referência para "como faço a IA fazer X sem nomear a ferramenta eu mesmo".
Configuração única
| Você diz | Claude chama |
|---|---|
| "Inicialize o arquivo de conhecimento de QA." | init_qa_knowledge → grava qa-knowledge.md na raiz do seu projeto |
| "Mostre-me o conhecimento de QA atual." | get_qa_context → seções de metodologia + seu domínio |
| "Abra a seção de princípios do ISTQB." | get_qa_context(section="ISTQB") |
Testes do dia a dia
| Você diz | Claude chama |
|---|---|
| "Execute todos os testes." | run_tests |
| "Execute apenas os testes relacionados a login." | run_tests(filter="login") |
| "Re-execute apenas as falhas." | run_failed |
| "Mostre-me o resumo." | get_test_report |
| "Quais falharam? Me dê capturas de tela e rastreio." | get_failure_details |
| "Gere o relatório HTML." | generate_html_report |
Criando testes a partir de uma URL (web)
| Você diz | Claude chama |
|---|---|
"Gere testes automaticamente para https://shop.example/." | auto_generate_tests(url=...) — execução única |
"Analise https://shop.example/coupon primeiro, depois escreva um teste por módulo." | analyze_url → generate_test × N |
| "Analise a página de cupom e escreva um teste de regressão para nosso bug de idempotência passado." | get_qa_context(section="Bug") → analyze_url → generate_test(business_context=...) |
| "Apenas grave um fluxo de checkout como linha de base." | codegen(url=...) |
Criando testes a partir de uma tela mobile (Maestro)
Requer QA_RUNNER=maestro, CLI do Maestro e um simulador/emulador/dispositivo iniciado.
| Você diz | Claude chama |
|---|---|
| "Analise a tela atual do your mobile app e escreva um teste para o botão de código de barras." | analyze_screen(app_id="com.example.app", launch_app=true) → generate_test(module=<cta>) |
| "Teste o formulário de login neste aplicativo." | analyze_screen(launch_app=true) → escolha o módulo form → generate_test |
| "Cubra a barra de abas — escreva um fluxo por aba." | analyze_screen → pegue o módulo tab_bar → generate_test |
| "Use o Maestro Studio para gravar um fluxo." | codegen(url=...) retorna uma dica apontando para maestro studio (grave e salve manualmente) |
Instâncias BlueStacks / Android remoto: defina QA_ANDROID_HOST=127.0.0.1:5555
(ou qualquer host:porta que o BlueStacks exponha — veja Configurações → Avançado → Android
Debug Bridge). O runner do Maestro fará adb connect antes de cada teste e
analyze_screen, e aumenta o timeout de hierarchy para 60s para absorver o
caminho TCP-ADB mais lento. Genymotion / Nox / LDPlayer / WSA funcionam da mesma forma;
qualquer host:port que responda a adb connect é suficiente.
Melhoria contínua
| Você diz | Claude chama |
|---|---|
| "O que devo corrigir a seguir?" | get_optimization_plan |
"test_login_invalid está flaky ultimamente?" | get_test_history + consulta ao plano |
| "Por que falhou? Mostre-me o rastreio." | get_failure_details (retorna caminhos de captura de tela/rastreio/vídeo) |
Dicas — fazendo o Claude escolher a ferramenta certa
- Mencione o conhecimento de QA explicitamente — "referencie o conhecimento de QA ao testar cupom" incentiva o Claude a chamar
get_qa_contextprimeiro; dizer apenas "teste cupom" pode pular isso. - Declare a ordem — "analise primeiro, depois escreva" força
analyze_urlantes degenerate_test; "apenas escreva um teste para X" pula a análise. - Lote vs. preciso — "gere automaticamente a página inteira" →
auto_generate_tests; "escreva um teste por candidate_tc" → cadeia manual. - Depuração de falhas — Perguntar "por que falhou / mostre-me a captura de tela" aciona de forma confiável
get_failure_details(que agora retorna caminhos de captura de tela + rastreio + vídeo).
Anti-padrões
- ❌ "Execute 5 vezes para ver se está flaky" — o runner tem retry automático + histórico; apenas pergunte "está flaky" e deixe
get_optimization_planresponder. - ❌ "Gere 100 testes" — ruído > sinal. Use
get_optimization_planprimeiro para descobrir o que está faltando. - ❌ "Teste todos os casos de borda" — vago demais. Formule como "teste cada
candidate_tcpara este formulário" — concreto, limitado, rastreável.
Exemplos de saídas
analyze_url (trecho)
{
"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"
]
}
]
}
Saída de generate_test (inteligente, com 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 (trecho)
# 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")`
Relatório HTML
Abra a demonstração renderizada ao vivo →
(servida via GitHub Pages — clicar no link na interface do GitHub para
sample_report.html mostraria apenas o código-fonte).
A demonstração mostra a grade de estatísticas, sparkline de tendência, cartões de falha com capturas de tela incorporadas + listas de etapas, e a seção Passed recolhida.
Integrações
mk-qa-master não inclui SDKs de terceiros — permanece uma camada pura de
execução de testes + análise. Fluxos de trabalho reais de QA são compostos
executando vários servidores MCP lado a lado na mesma configuração de cliente;
o Claude orquestra a cadeia entre servidores. Não há RPC MCP-para-MCP
— cada servidor é independente, o cliente de IA é o maestro.
Os pares abaixo são os que completam o loop com mais frequência:
| Parear com | Por quê | Exemplo de cadeia |
|---|---|---|
| Atlassian MCP (JIRA + Confluence) | Abrir tickets de bug automaticamente a partir de falhas; sincronizar optimization-plan.md para uma página do Confluence da equipe | run_tests → get_failure_details → atlassian.createJiraIssue (anexa captura de tela + caminho do rastreio) |
| Slack MCP | Notificar canais em caso de falha, compartilhar o relatório HTML renderizado, mencionar oncall para testes flaky | generate_html_report → slack.send_message(channel="#qa-bots", attachments=...) |
| GitHub MCP | Ler descrição de PR / issues vinculadas para contexto de negócio antes de gerar testes; publicar resultados de volta como comentários no PR | github.get_pull_request → analyze_url → generate_test(business_context=PR body) → github.create_issue_comment |
| Sentry MCP | Erros de produção direcionam a prioridade de regressão: principais crashes → testes de regressão correspondentes | sentry.list_issues(sort="frequency") → generate_test(business_context=stack trace) → run_tests |
| Filesystem MCP | Ler um qa-knowledge.md compartilhado ou arquivos-fonte de TC que vivem fora de QA_PROJECT_ROOT (monorepos, configurações multiprojeto) | filesystem.read_file("~/shared/qa-knowledge.md") → init_qa_knowledge |
Menção honrosa — Google Drive MCP: combina com gerenciamento de TC baseado em Google Sheets (ler TCs de uma planilha → generate_test → gravar status de volta).
Compondo na configuração do seu cliente
Todos os cinco rodam como processos separados junto com 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"] }
}
}
Então um único prompt percorre a cadeia:
"Execute a suíte de checkout. Para cada falha, abra um JIRA no projeto QA com o formato RIDER e a captura de tela anexada. Publique o relatório HTML em #qa-bots quando terminar."
Por que isso importa: mk-qa-master permanece focado no loop de testes
(analisar → gerar → executar → orientar). JIRA / Slack / Sentry são domínios
inteiros com seus próprios servidores dedicados — incorporá-los aqui
diluiria o escopo, duplicaria o tratamento de autenticação e forçaria cada usuário
a herdar dependências que talvez não queira.
Este repositório não empacota nenhum SDK de terceiros — mantém a responsabilidade única de "execução de testes + análise". Na prática, os fluxos de trabalho de QA são alcançados com vários servidores MCP coexistindo, com o Claude orquestrando a cadeia de ferramentas entre servidores. Exemplos de combinações: JIRA / Slack / GitHub / Sentry / Filesystem, cada um com seu próprio servidor MCP independente, junto com mk-qa-master para montar o pipeline de testes completo.
Publicação (somente mantenedores)
As versões são enviadas ao PyPI via Trusted Publishing — sem tokens de API armazenados no repositório. O fluxo:
- Aumente
version = "x.y.z"empyproject.toml(via um PR normal — main é protegido por branch). - Após o merge, crie a tag em main e envie:
git tag -a vX.Y.Z -m "vX.Y.Z — short summary" git push origin vX.Y.Z - Crie uma Release no GitHub para essa tag (
gh release create vX.Y.Z ...). - O evento de release dispara
.github/workflows/publish.yml→ compila sdist + wheel → envia para o PyPI.
Configuração única do PyPI (deve ser feita uma vez antes da primeira publicação funcionar):
- Entre em https://pypi.org → ative a 2FA.
- Página do projeto → Settings → Publishing → adicione um pending publisher com:
- Owner:
kao273183 - Repository:
mk-qa-master - Workflow filename:
publish.yml - Environment name:
pypi
- Owner:
Após a primeira execução bem-sucedida, o PyPI promove automaticamente o pending publisher para trusted e as versões subsequentes autenticam via OIDC.
O workflow se recusa a publicar se a tag da release não corresponder a pyproject.version, o que detecta erros de "taggei mas esqueci de aumentar a versão" antes de chegarem ao PyPI.
Apoie o projeto ☕
mk-qa-master é construído e mantido por uma única pessoa, em noites e fins de semana. Se economizou seu tempo ou moldou como sua equipe pensa sobre QA orientado por IA, um café mantém as sessões de depuração noturnas do Maestro funcionando:
Seu apoio financia: manter este repositório gratuito e ativamente mantido, mais variantes de dispositivos para testes com Maestro (iPhones reais / tablets Android / BlueStacks), tutoriais gravados para a comunidade de QA e a próxima caçada a bugs às 2h da manhã.
Sem anúncios, sem patrocínios, sem venda casada empresarial — apenas o trabalho.
Contribuindo
Este repositório é mantido por uma única pessoa. Ideias e relatórios de bugs são muito bem-vindos — por favor, abra uma Issue ou inicie uma Discussão. Eu leio cada um e implementarei o que se adequar à direção do projeto.
Pull requests externos são fechados automaticamente. Não porque contribuições não sejam apreciadas, mas porque manter a coerência do código sob uma única voz importa mais aqui do que a produtividade que um modelo multi-colaborador traria. Se você realmente quer uma mudança específica, uma Issue descrevendo o problema te leva mais longe do que um PR.
Este repositório é mantido por mim. Sinta-se à vontade para enviar ideias ou relatar problemas via Issue / Discussão; avaliarei e implementarei pessoalmente. PRs externos são fechados automaticamente — não é que contribuições não sejam bem-vindas, mas sim para manter o estilo e a direção do código consistentes.
Licença
MIT © 2026 Jack Kao — veja LICENSE
(tradução em chinês: LICENSE.zh-TW.md; a versão em inglês é a autoritativa).
Em termos simples: você pode usar isto para qualquer coisa (projetos pessoais, trabalho comercial, modificações, redistribuição). O único pedido é que você mantenha o aviso de copyright + licença em qualquer cópia que distribuir. Não há garantia — use por sua conta e risco.