Escritor de Testes Appium Java
Produza testes mobile que pareçam feitos por um SDET experiente: uma única base de código para Android e iOS, segura para execução paralela em múltiplos dispositivos, sem sleeps, gestos que funcionam no java-client 9+ e relatórios Allure que rastreiam IDs de casos manuais. Também lida com migração Python → Java, uma tarefa comum no mundo real e que vale a pena fazer fielmente, em vez de apenas transliterar.
Decida o modo
- Casos manuais → Java: siga o Fluxo A.
- Código Python/Appium → Java: siga o Fluxo B. Leia
references/python-to- java-migration.mdprimeiro. - Estruturar um framework: gere os arquivos em
references/framework-scaffold.md, adaptados ao aplicativo e plataformas do usuário.
Se o usuário compartilhar quaisquer arquivos de framework Java existentes (BaseTest, classe de tela, testng.xml, capabilities), espelhe as convenções deles em vez das referências.
Fluxo A: casos manuais → testes
- Normalize cada caso em: ID, título, prioridade, plataforma(s), pré-condições, dados de teste, passos, resultados esperados. Anote passos específicos da plataforma (botão voltar do Android, alerta de permissão do iOS).
- Telas e componentes: uma classe por tela; widgets reutilizáveis (barra inferior, barra de ferramentas, bottom sheet) como classes de componente compostas nas telas. Métodos de tela expressam a intenção do usuário e carregam
@Step("...")do Allure. Ações de navegação retornam o próximo objeto de tela. - Localizadores — multiplataforma via anotações no mesmo campo:
Prioridade: accessibility id → Android resource-id / iOS name → UiAutomator / predicate ou class chain do iOS → XPath por último (lento no iOS, frágil em toda parte; comente o motivo se usado). Se não houver page source, saída do Appium Inspector ou screenshots fornecidos, marque suposições com@AndroidFindBy(accessibility = "botao-login") @iOSXCUITFindBy(accessibility = "botao-login") private WebElement botaoLogin;// TODO-VERIFY localizador. Se apenas o localizador de uma plataforma for conhecido, escreva aquele e deixe a outra anotação comTODO-VERIFY, em vez de copiá-lo cegamente. - Testes: um
@Testpor caso, método nomeado pelo comportamento,@TmsLinkcom o ID do caso,@Epic/@Feature/@Story/@Severity(P0 → BLOCKER/CRITICAL, P1 → NORMAL, P2+ → MINOR). Variantes de dados →@DataProvidercom o ID do caso como primeira coluna eAllure.link(caseId, "tms", caseId)no corpo. Cada resultado esperado se torna uma asserção. - Estado do dispositivo/aplicativo: destaque casos que precisam de capabilities não padrão (diálogos de permissão precisam de
autoGrantPermissions=false, integração precisa de instalação limpa /noReset=false, recursos exclusivos do emulador como impressão digital) e coloque-os em um grupo separado ou anote a substituição. - Pré-condições: prefira deep links (
driver.get("myapp://carrinho")no Android,mobile: deepLink) ou configuração via API em vez de longas sequências de toques. Pré-condições de login via API/sessão quando possível. - Não automatizável como está (OTP real por SMS, pagamentos reais, biometria sem suporte do simulador, verificações visuais subjetivas): liste em "Não automatizado" com uma alternativa (OTP de teste, pagamento em sandbox,
mobile: enrollBiometric/sendBiometricMatchem simuladores/emuladores, ferramenta de comparação visual).
Fluxo B: migração Python → Java
- Leia
references/python-to-java-migration.md. - Mapeie a estrutura primeiro (fixtures do conftest → BaseTest/factory, módulos de página → classes de tela,
parametrize→@DataProvider), depois traduza o código. - Corrija anti-padrões em vez de portá-los:
time.sleep→ waits explícitos,TouchAction/MultiAction→ Ações W3C ou gestosmobile:, dicionários desired-capabilities →UiAutomator2Options/XCUITestOptions, driver global → ThreadLocal. - Mantenha a intenção do teste e as asserções idênticas. Se o teste Python afirmava algo fraco (ex.:
assert elemento) ou escondia falhas (try/except: pass, asserções dentro de condicionais), corrija e destaque na tabela de migração, porque o teste original pode nunca ter sido capaz de falhar. - Produza uma tabela de migração:
Arquivo/função Python | Classe/método Java | Alterações além da tradução.
Waits: explícitos e baseados em condições
- Wait implícito é 0. Misturar waits implícitos e explícitos causa timeouts imprevisíveis.
- Nunca use
Thread.sleep. UseWebDriverWaitcomExpectedConditions(visibilityOf,elementToBeClickable,invisibilityOf,textToBePresentInElement,attributeToBe) através de helpers emBaseScreen. - Aguarde o desaparecimento de loaders/spinners em vez de esperar o tempo passar.
- Timeouts vêm da configuração, não de números inline.
- Após uma ação que re-renderiza uma lista ou carrossel, aguarde um sinal que seja sempre verdadeiro depois (sheet fechado, loader sumiu, lista presente, contagem igual à esperada). Não espere por "texto do primeiro item mudou": o valor esperado pode já estar no lugar e o wait expira. O wait do BaseScreen ignora
StaleElementReferenceException, então faça uma nova consulta dentro da condição.
Gestos
java-client 9 removeu TouchAction/MultiAction. Use:
- Rolar até o elemento: Android
AppiumBy.androidUIAutomator("new UiScrollable(...).scrollIntoView(...)"); iOSmobile: scrollcompredicateString. - Deslizar/arrastar/pressionar longo: gestos
mobile:da plataforma (Androidmobile: swipeGesture,longClickGesture; iOSmobile: swipe,touchAndHold) ou uma sequência W3CPointerInputemBaseScreenpara uso multiplataforma. Vejareferences/framework-scaffold.md→ Gestos.
Segurança paralela
O driver vive em um ThreadLocal<AppiumDriver> criado por teste (ou por classe se o usuário pedir velocidade), sempre remove()ado após quit(). Cada dispositivo paralelo precisa do seu próprio udid e um systemPort (Android) / wdaLocalPort (iOS) únicos, definidos nos parâmetros do testng.xml. Sem drivers estáticos ou estado de elemento estático.
Formato de saída
- Arquivos: arquivos completos e compiláveis com imports, cada um sob seu cabeçalho de caminho. Se mais de ~3 arquivos ou o usuário quiser baixar, também escreva-os em disco como uma pasta de projeto.
- Tabela de rastreabilidade (Fluxo A) ou tabela de migração (Fluxo B).
- Não automatizado / lacunas.
- Precisa de verificação: conte e liste localizadores
TODO-VERIFY, capabilities assumidas (caminho do app, package/activity, bundle id), passos específicos de plataforma.
Mantenha o texto curto; o código é a entrega.
Confidencialidade
Para trabalho público/portfólio, use o pacote com.exemplo (ou o do usuário), um aplicativo de demonstração público, e substitua quaisquer nomes de empresa, IDs internos de aplicativos, URLs internos, números de telefone/e-mails reais ou nomes de eventos proprietários por neutros. Mencione a substituição em uma linha.
Arquivos de referência
references/framework-scaffold.md: pom.xml, config, DriverFactory com ThreadLocal + classes Options, BaseTest com screenshot/page-source do Allure em caso de falha, BaseScreen com helpers de wait e gestos, testng.xml para dispositivos paralelos.references/python-to-java-migration.md: mapeamento lado a lado de expressões Python Appium/pytest para Java/TestNG, além de uma migração trabalhada.references/example-swaglabs.md: casos manuais → telas → testes no aplicativo público Sauce Labs Sample App.