Testes de UI em aplicativos móveis: o que são, tipos e como são realizados

Autor: IT Sectr Publicado: 2026-04-07 Tempo de leitura: 8 min

Os testes de UI verificam a corretude da exibição e interação dos elementos da interface do usuário de um aplicativo móvel — botões, campos de texto, listas e componentes de navegação. Diferente dos testes unitários que verificam a lógica de negócios, os testes de UI simulam ações do usuário: toques, deslizes, entrada de texto e verificam a resposta da interface. De acordo com um estudo da Android Developers, 2024, os testes de UI cobrem 70% dos cenários críticos de usuário e permitem detectar defeitos de layout que não são acessíveis para verificações lógicas.

Principais pontos

  • Testes de UI — processo de verificação da interface do usuário do aplicativo através da simulação de ações do usuário: toques, entrada de texto e deslizes.
  • Espresso — framework do Google para testes de UI em aplicativos Android, fornecendo sincronização com a thread de UI e espera automática de animações.
  • XCUITest — framework nativo da Apple para testes de UI em aplicativos iOS, integrado ao Xcode e funcionando através de rótulos de acessibilidade.
  • Appium — ferramenta multiplataforma que permite escrever testes de UI em uma única linguagem para Android e iOS usando o protocolo WebDriver.
  • Testes de snapshot complementam os testes de UI verificando a aparência visual das telas — comparam uma captura do estado de referência com a renderização atual.

O que são testes de UI?

Os testes de UI são um tipo de verificação automatizada onde o código de teste interage com a interface gráfica do aplicativo da mesma forma que um usuário real faria. O teste encontra um elemento na tela — um botão, campo de texto, lista — realiza uma ação sobre ele e verifica a resposta esperada da interface. Por exemplo, após inserir uma senha incorreta, um teste de UI verifica se uma mensagem de erro com o texto correto aparece na tela.

A principal diferença entre os testes de UI e outros tipos de automação é que eles funcionam através da camada de acessibilidade do sistema operacional, não através das APIs internas do aplicativo. Isso significa que os testes de UI veem a interface exatamente como um usuário e um leitor de tela a veriam. Graças a isso, os testes de UI verificam não apenas a funcionalidade, mas também a acessibilidade dos elementos — conformidade com os requisitos WCAG.

De acordo com a pesquisa JetBrains Developer Ecosystem 2023, 58% das equipes móveis usam testes de UI em seu pipeline de CI/CD. A cobertura média de testes de UI em projetos comerciais é de 30–40% das telas do aplicativo. Projetos com testes de UI recebem 25% menos avaliações negativas nas lojas de aplicativos relacionadas a falhas de interface.

Diferença entre testes de UI e testes unitários

A principal diferença entre testes de UI e testes unitários é o nível de abstração. Testes unitários trabalham com classes e funções individuais, isoladas do framework Android ou iOS. Eles são executados na JVM (para Android) sem iniciar um emulador e levam milissegundos. Testes de UI são executados em um dispositivo real ou emulador, interagem com serviços do sistema e levam segundos ou minutos por cenário.

O público-alvo dos testes também difere. Testes de UI verificam cenários completos de usuário — registro, realização de pedidos, busca. Testes unitários cobrem a lógica de negócios: cálculos, validação, transformação de dados. Um teste de UI não verifica a corretude do cálculo de imposto — ele verifica se o valor total é exibido na tela. O cálculo em si é verificado por um teste unitário.

De acordo com o Google Testing Blog (2020), a proporção ideal de testes em um projeto segue a regra da pirâmide de testes: 70% de testes unitários, 20% de integração e 10% de UI. A violação dessa proporção em favor dos testes de UI leva ao aumento do tempo de execução e à fragilidade do conjunto de testes, já que os testes de UI são sensíveis a mudanças no layout das telas.

Frameworks para testes de UI

Para Android, o framework dominante é o Espresso — uma biblioteca do Google incorporada ao AndroidX Test. O Espresso sincroniza automaticamente com a thread de UI, aguardando a conclusão de animações e tarefas em segundo plano antes de executar a próxima verificação. Para Jetpack Compose, é usada a extensão Compose UI Test, que funciona através de nós semânticos em vez dos identificadores de visualização tradicionais.

Para iOS, a ferramenta principal é o XCUITest, que faz parte do Xcode. Os testes são escritos em Swift e usam identificadores de acessibilidade para encontrar elementos. O XCUITest suporta gravação de testes através da função de gravação e integração com sistemas CI via xcodebuild. Para projetos multiplataforma, é usado o Appium, baseado no protocolo WebDriver e que permite executar os mesmos testes no Android e iOS com alterações mínimas de código.

Espresso e Compose UI Test

Espresso funciona com o sistema tradicional de Views através de onView e identificadores de recursos. O Compose UI Test usa uma camada semântica, tornando os testes menos dependentes da hierarquia de views. Por exemplo, encontrar um botão no Espresso: onView(withId(R.id.submit)), no Compose: onNodeWithTag(“submit”). Os testes do Compose lidam automaticamente com a recomposição e não exigem esperas explícitas de estado ocioso.

XCUITest para iOS

XCUITest usa XCUIApplication como ponto de entrada. Cada elemento da interface é encontrado através de propriedades de acessibilidade: accessibilityIdentifier para acesso programático e accessibilityLabel para VoiceOver. O framework suporta gravação de testes através da função de gravação do Xcode — o desenvolvedor realiza ações no simulador e o Xcode gera o código de teste. Os testes prontos são executados via xcodebuild test.

Soluções multiplataforma

Appium é baseado no protocolo WebDriver e suporta qualquer linguagem: Java, Python, JavaScript. As estratégias de busca de elementos incluem id, xpath, class name e accessibility id. O Appium requer instalação do servidor e configuração das Desired Capabilities — platformName, deviceName, appPackage. Uma alternativa é o Maestro, que usa cenários YAML e não requer compilação de código de teste.

  • Espresso — onView(withId(R.id.button)).perform(click()).check(matches(isDisplayed()))
  • XCUITest — app.buttons[“loginButton”].tap(); XCTAssertTrue(app.staticTexts[“welcome”].exists)
  • Appium — driver.findElement(By.id(“com.example:id/button”)).click()
  • Detox — framework da Wix para React Native, que sincroniza com a thread JS
  • Maestro — ferramenta moderna com cenários YAML que não requer escrever código

Exemplos de código para testes de UI

Vamos examinar testes de UI para o mesmo cenário — login no aplicativo — em três frameworks diferentes: Espresso para Android, XCUITest para iOS e Appium para a abordagem multiplataforma. Cenário: inserir login e senha, pressionar o botão de login, verificar a exibição da mensagem de boas-vindas.

Android: Espresso

Um teste no Espresso usa onView para encontrar um elemento pelo seu identificador e perform para executar uma ação. O método check com o matcher isDisplayed confirma que o elemento está visível na tela.

kotlin
@RunWith(AndroidJUnit4::class)
class LoginUiTest {

    @Rule
    @JvmField
    val composeTestRule = createComposeRule()

    @Test
    fun login_withValidCredentials_showsWelcome() {
        composeTestRule
            .onNodeWithTag("emailField")
            .performTextInput("user@example.com")
        composeTestRule
            .onNodeWithTag("passwordField")
            .performTextInput("secret123")
        composeTestRule
            .onNodeWithTag("loginButton")
            .performClick()
        composeTestRule
            .onNodeWithText("Bem-vindo, Usuário!")
            .assertIsDisplayed()
    }
}

iOS: XCUITest

XCUITest usa XCUIApplication para acessar elementos da interface através de identificadores de acessibilidade. Os métodos tap() e exists fornecem interação e verificação.

swift
class LoginUITests: XCTestCase {
    let app = XCUIApplication()

    override func setUp() {
        continueAfterFailure = false
        app.launch()
    }

    func testLogin_withValidCredentials_showsWelcome() {
        app.textFields["emailField"].tap()
        app.textFields["emailField"].typeText("user@example.com")
        app.secureTextFields["passwordField"].tap()
        app.secureTextFields["passwordField"].typeText("secret123")
        app.buttons["loginButton"].tap()
        XCTAssertTrue(app.staticTexts["Welcome, User!"].exists)
    }
}

Melhores práticas de testes de UI

O primeiro princípio — use identificadores de acessibilidade em vez de rótulos de texto para encontrar elementos. O texto de um botão pode mudar durante a localização, enquanto o identificador permanece estável. No Android, esta é a propriedade contentDescription; no iOS — accessibilityIdentifier. Esta abordagem torna os testes independentes do idioma da interface e reduz custos de manutenção ao alterar o copywriting.

Evite sleep() e atrasos fixos — use os mecanismos de espera integrados do framework. O Espresso aguarda automaticamente a conclusão de animações e tarefas em segundo plano. O XCUITest fornece XCTAssertTrue com timeout. Pausas explícitas tornam os testes mais lentos e instáveis, especialmente em dispositivos lentos em ambiente CI.

Agrupe testes por criticidade: testes smoke (3–5 cenários principais) são executados em cada commit, o conjunto completo de testes de UI é executado antes do lançamento. De acordo com o Google Testing Blog (2022), testes de UI que levam mais de 30 minutos no CI reduzem a frequência de execução em 40%, diminuindo sua eficácia como ferramenta de detecção precoce de regressões.

Limitações dos testes de UI e como superá-las

Os testes de UI têm várias limitações. Sensibilidade a mudanças de layout: alterar um identificador, hierarquia ou tipo de elemento quebra o teste mesmo com funcionalidade inalterada. A solução é usar o padrão Page Object, que centraliza os seletores de elementos em classes separadas. Quando o layout muda, apenas um arquivo Page Object é corrigido, não dezenas de testes.

Tempo de execução: a execução em um dispositivo real ou emulador leva de 10 a 50 vezes mais tempo que um teste unitário. A solução é executar testes de UI em paralelo em vários dispositivos através do Firebase Test Lab ou AWS Device Farm. Instabilidade (flakiness) é um problema comum em execuções CI, causado por animações, atrasos de rede ou estado do emulador. Para combater a instabilidade, são usadas repetições automáticas de testes com falha e análise de estabilidade de cada cenário de teste.

Perguntas frequentes

Quantos testes de UI são necessários para uma tela?

Para uma tela média, 3–5 testes de UI são suficientes: happy path, validação de erros, estado vazio, mudança de orientação e verificação de acessibilidade. Telas complexas com múltiplos estados — formulários de pedido, configurações — podem exigir 10–15 testes para cobertura completa dos cenários principais.

Pode-se usar um único framework para Android e iOS?

Sim, Appium e Maestro permitem executar os mesmos cenários em ambas as plataformas. No entanto, os frameworks nativos — Espresso e XCUITest — oferecem melhor estabilidade, velocidade e acesso a recursos específicos da plataforma que não estão disponíveis através de proxies WebDriver.

Como testar UI no Jetpack Compose?

Para Compose, é usada a biblioteca Compose UI Test com correspondentes semânticos: onNodeWithText, onNodeWithTag, onNodeWithContentDescription. A camada semântica do Compose abstrai a hierarquia de views, tornando os testes menos frágeis em comparação com o Espresso tradicional para o sistema de Views.

É necessário testar a UI em dispositivos físicos?

A execução básica de testes de UI é feita em emuladores no CI — é rápido e barato. A verificação final antes do lançamento deve ser feita em dispositivos físicos através do Firebase Test Lab para considerar as características do hardware real: diferentes resoluções, versões do SO e desempenho.

Como reduzir o tempo de execução dos testes de UI?

Use execução paralela em vários dispositivos, desative animações no emulador através das Opções do Desenvolvedor, construa uma arquitetura de testes modular e execute o conjunto smoke em cada commit, com a execução de regressão completa agendada ou antes do lançamento.

Resumo

  • Testes de UI verificam a interface através da simulação de ações do usuário — toques, entrada de texto, deslizes.
  • Espresso e Compose UI Test são os principais frameworks para Android; XCUITest para iOS; Appium para projetos multiplataforma.
  • A pirâmide de testes recomenda a proporção 70/20/10: testes unitários, de integração e de UI respectivamente.
  • Identificadores de acessibilidade tornam os testes de UI resistentes à localização e mudanças de layout.
  • O padrão Page Object centraliza seletores de elementos, reduzindo custos de manutenção ao alterar a interface.
  • Testes smoke (3–5 cenários) executam em cada commit, o conjunto completo antes do lançamento.
  • Execução paralela em emuladores e desativação de animações reduzem o tempo de execução de testes de UI no CI.

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também