Pular para o conteúdo
CrossFly é 100% open sourceSiga no GitHub
CrossFlyCrossFly
Começar

Testes automatizados de UI

O framework de testes do CrossFly não é JUnit. Cada TestCase roda dentro do runtime gráfico (paint thread, EventsProcessor, pipeline GL), e a asserção principal é a comparação visual de screenshots contra imagens-referência (golden images). Portal para o Capítulo 31.

Anatomia de um TestCase

public class LoginTest extends TestCase {
   @Override protected void load() throws Exception {
      new LoginScreen().show();        // monta a tela sob teste
   }
   @Override public void runTests() throws Exception {
      waitWindow(LoginScreen.class);
      type(0, TextField.class, "[email protected]");   // digita no 1º TextField
      type(1, TextField.class, "senha123");
      click("Entrar");                 // clica no botão com esse texto
      shot();                          // captura e compara com o golden
      waitWindow(HomeScreen.class);
      shot();
   }
   @Override protected void unload() { /* limpa estado */ }
}

Interação: click(...), type(...), enter(), penDown/penUp/penDrag(...), setText(...). Descoberta: find(index, Classe) / find(texto, Classe). Sincronização: waitWindow(...), waitAnimation(), waitUIidle(...).

Agrupar e rodar — TestSuite

TestSuite suite = new TestSuite();
suite.startTests(new TestCase[]{ new LoginTest(), new CadastroTest() });

A suite roda cada teste, compara os shot() com os goldens e reporta (success/fail/log).

⚠️ Determinismo é pré-requisito: DeviceConfig.isTesting

A comparação pixel-a-pixel só casa se a renderização for determinística. Ligue DeviceConfig.isTesting = true — isso fixa o cursor, remove timestamps e torna TimePicker/relógio estáveis. Sem isso, o golden nunca bate (cursor piscando, hora atual, etc. mudam a imagem).

Sem UI: WindowlessTestCase

Para lógica que não precisa de tela (repository, formatação), estenda WindowlessTestCase — roda no runtime, mas sem montar UI.

Gerar as imagens da doc

Os mesmos screenshots de teste servem para gerar as imagens da documentação/loja: Main.getScreenShot(true).toPng("prefixo_").

Boas práticas

  • Sempre DeviceConfig.isTesting = true na bateria de testes.
  • Use waitWindow(...)/waitAnimation() antes de shot() — capture um frame estável.
  • Um golden por estado visual relevante; regenere ao mudar a UI de propósito.

Erros comuns

  • Golden que “some vez sim, vez não” → faltou isTesting/waitAnimation (frame instável).
  • shot() antes da janela estar totalmente visível.
Esta página foi útil?