Code Coverage no desenvolvimento mobile: o que é, métricas e como medir

Autor: IT Sectr Publicado: 2026-04-09 Tempo de leitura: 9 min

Code Coverage (cobertura de código) é uma métrica que mostra qual porcentagem do código-fonte do aplicativo é executada durante os testes. Ela ajuda a determinar a qualidade dos testes, identificar áreas não verificadas e priorizar a escrita de novos testes. De acordo com a Atlassian, 2025, o nível ideal de cobertura é de 70–80% — acima desse limite, os custos dos testes começam a superar os benefícios.

Principais conclusões

  • Code Coverage — métrica que mede a porcentagem de código executado pelos testes
  • Métricas de cobertura incluem linha (line), ramo (branch), funções, condições e caminhos
  • Ferramentas: JaCoCo para Android, XCCov para iOS, SonarQube para análise de código
  • Cobertura alvo 70–80% — equilíbrio entre qualidade e custo dos testes
  • Integração CI/CD permite bloquear builds quando a cobertura cai abaixo do limite

O que é Code Coverage

Code Coverage (cobertura de código) é uma métrica quantitativa que determina qual parte do código-fonte do aplicativo foi executada durante os testes. É expressa em porcentagem e calculada como a razão entre linhas/ramos executados e o total. Alta cobertura não garante ausência de bugs, mas reduz o risco de erros não detectados.

Por que medir a cobertura

A cobertura de código ajuda a equipe a: encontrar áreas não testadas do código, tomar decisões sobre prioridades de escrita de testes e acompanhar a dinâmica da qualidade dos testes em CI/CD. No desenvolvimento mobile, a cobertura é especialmente importante para a lógica de negócios, modelos de dados e repositórios — camadas onde a probabilidade de erros é maior.

Mitos sobre Code Coverage

Um mito comum: “100% de cobertura = qualidade perfeita”. Na prática, 100% de cobertura é extremamente raro e muitas vezes alcançado à custa de testes superficiais. Cobertura eficaz não é uma corrida por porcentagem, mas uma cobertura estratégica de caminhos críticos e condições de fronteira. A cobertura não diz nada sobre a qualidade dos próprios testes: um teste pode passar mas não verificar a correção do resultado.

Métricas de cobertura de código

Existem várias métricas de Code Coverage, cada uma medindo diferentes aspectos dos testes. Line coverage (cobertura de linha) é a métrica mais simples, mostrando a porcentagem de linhas de código executadas. Branch coverage (cobertura de ramo) mede quais ramificações if-else e switch foram testadas.

Cobertura de linha (Line Coverage)

Line coverage conta cada linha de código-fonte como executada ou não. Se uma linha contém um operador condicional ou loop, a linha é considerada executada se o controle a alcançou, mesmo que nem todos os ramos tenham sido processados. Esta é a métrica menos rigorosa, mas a mais compreensível para avaliação visual.

Cobertura de ramo (Branch Coverage)

Branch coverage avalia se todos os possíveis ramos no código foram testados. Para cada if-else, ambos os ramos são considerados: true e false. Para switch, cada case é considerado. Branch coverage é considerada uma métrica mais rigorosa que line coverage e mais frequentemente revela cenários não testados.

MétricaO que medeDificuldade de alcançar
LinePorcentagem de linhas de código executadasBaixa
BranchPorcentagem de ramos executados (if/else, switch)Média
FunctionPorcentagem de funções e métodos chamadosBaixa
ConditionPorcentagem de subexpressões lógicas (&&, ||)Alta

Cobertura de caminho (Path Coverage)

Path coverage é a métrica mais rigorosa, exigindo verificação de todas as possíveis combinações de ramos em uma função. Na prática, path coverage raramente é usado devido ao crescimento exponencial do número de combinações: uma função com 10 ramos tem 1024 caminhos possíveis.

Ferramentas para medir cobertura

No desenvolvimento mobile, várias ferramentas são usadas para medir Code Coverage dependendo da plataforma. Para Android, o padrão é JaCoCo (Java Code Coverage), que se integra com Gradle e suporta tanto testes unitários quanto testes de instrumentação. Para iOS, é usado o XCCov, integrado ao Xcode.

JaCoCo para Android

JaCoCo gera relatórios nos formatos HTML, XML e CSV. O relatório HTML destaca visualmente as linhas: verde — executadas, vermelho — omitidas, amarelo — parcialmente executadas. O relatório XML é compatível com SonarQube e outros sistemas de análise de código. JaCoCo suporta filtragem de classes: código gerado, databinding e BuildConfig podem ser excluídos.

groovy
// build.gradle — configuração do JaCoCo
android {
    buildTypes {
        debug {
            testCoverageEnabled = true
        }
    }
}

// Geração de relatório JaCoCo
task jacocoTestReport(type: JacocoReport) {
    dependsOn 'testDebugUnitTest'
    reports {
        xml.enabled = true
        html.enabled = true
    }
}

XCCov para iOS

XCCov é uma ferramenta integrada do Xcode para medir cobertura de código. É habilitada através de Gather coverage data no esquema de teste. XCCov suporta cobertura para Swift e Objective-C, gera relatórios no formato .xccovreport e se integra com CI via xcodebuild -enableCodeCoverage YES. Os dados são exibidos no console e podem ser exportados em JSON.

SonarQube e Codecov

Para monitoramento centralizado de cobertura, são usadas plataformas como SonarQube (análise de qualidade de código + cobertura), Codecov e Coveralls. Esses serviços agregam dados do JaCoCo e XCCov, mostram tendências, Quality Gate e integração com GitHub/GitLab através de comentários em PR.

Como melhorar a cobertura de código

Melhorar o Code Coverage requer uma abordagem sistemática: não “aumentar porcentagens”, mas cobrir riscos. O primeiro passo é analisar o relatório JaCoCo ou XCCov — identificar classes vermelhas (não cobertas). Prioridade: lógica de negócios → repositórios → ViewModel → componentes de UI.

Estratégia TDD

Test-Driven Development (TDD) garante automaticamente alta cobertura, pois os testes são escritos antes da implementação. O processo: vermelho (escrever um teste que falha) → verde (escrever código mínimo) → refatoração. TDD disciplina o desenvolvedor, forçando-o a cobrir casos limite e situações excepcionais que frequentemente ficam sem teste.

Testes parametrizados

Um teste parametrizado substitui dezenas de testes comuns. JUnit e XCTest suportam parametrização: @ParameterizedTest no JUnit 5, XCTestCase com testPerformanceExample no XCTest. A parametrização permite verificar múltiplos dados de entrada sem duplicação de código, expandindo significativamente a cobertura de ramos e condições.

kotlin
// Teste parametrizado em Kotlin com JUnit 5
@ParameterizedTest
@ValueSource(strings = ["user@test.com", "admin@test.com", "test@example.com"])
fun `validate email returns true for valid addresses`(email: String) {
    val result = EmailValidator.isValid(email)
    Assertions.assertTrue(result)
}

Erros ao trabalhar com Code Coverage

O erro mais comum é perseguir a porcentagem sem analisar a qualidade dos testes. A equipe começa a escrever testes por escrever: verifica getters e setters, duplica cobertura em diferentes níveis, testa métodos triviais. Isso dá uma alta porcentagem mas não melhora a qualidade real.

Falsa sensação de segurança

Um Code Coverage alto pode criar uma falsa sensação de que o aplicativo está bem testado. Um teste pode executar uma linha de código mas não verificar a correção do resultado. Por exemplo: um teste chama um método de cálculo de desconto mas não verifica o valor — a linha é executada, a cobertura cresce, mas o bug não é encontrado.

Ignorar casos limite

Um erro típico é testar apenas o “caminho feliz” (happy path) e ignorar casos limite: listas vazias, valores null, números máximos, formatos incorretos. É precisamente nos limites e exceções que a maioria dos bugs ocorre. Branch coverage ajuda a identificar ramos perdidos, mas não garante a verificação de valores limite.

Mutation Testing — verificação da qualidade dos testes

Mutation Testing é um método para avaliar a qualidade dos testes onde mutações (erros artificiais) são introduzidas no código-fonte e verifica-se se os testes falham. Pitest é uma ferramenta popular de mutation testing para Java e Kotlin. Se os testes não falham em uma mutação, significa que eles não verificam essa condição.

Princípio de funcionamento do Pitest

Pitest cria mutantes — cópias modificadas do código-fonte onde, por exemplo, > é substituído por >=, true por false, ou uma chamada de método é removida. Então, para cada mutante, os testes são executados. Se os testes passam — o mutante sobreviveu, significando que os testes não cobrem esse cenário. Se os testes falham — o mutante foi morto, o teste é válido.

groovy
// build.gradle — configuração do Pitest
plugins {
    id 'info.solidsoft.pitest' version '1.15.0'
}

pitest {
    targetClasses = ['com.example.app.*']
    targetTests = ['com.example.app.*Test']
    threads = 4
    outputFormats = ['HTML', 'XML']
    mutationThreshold = 80
    coverageThreshold = 85
}

Tipos de mutação

Pitest suporta muitos tipos de mutação: alteração de operadores condicionais (== → !=, < → <=), remoção de chamadas de método, substituição de valores de retorno (true → false), alteração de operações aritméticas (+ → -), mutação de incrementos (i++ → i--). Quanto mais tipos de mutação são mortos pelos testes, mais confiável é o conjunto de testes.

Objetivo do Mutation Score

O mutation score alvo é 80% ou mais. Isso significa que 80% dos erros artificiais são detectados pelos testes. Uma cobertura de código (Code Coverage) de 90% não garante que os testes encontrem bugs — o mutation testing fornece uma avaliação mais objetiva. Pitest pode ser integrado ao CI como Quality Gate, bloqueando o build se o mutation score cair abaixo do limite.

Integração do Code Coverage em CI/CD

Para controle automático do Code Coverage em CI/CD, são usados Quality Gates — valores limite que, quando violados, marcam o build como instável ou o rejeitam. SonarQube permite configurar um Quality Gate baseado em uma combinação de métricas: cobertura (≥80%), número de bugs, vulnerabilidades e código duplicado.

Configuração do Quality Gate no GitHub Actions

No GitHub Actions, o Code Coverage é integrado através de etapas de ação: executar testes com cobertura → enviar relatório para Codecov → verificar limite. Codecov automaticamente comenta nos PRs com o diff de cobertura, mostrando quais linhas mudaram e como isso afetou a porcentagem geral. Se a cobertura caiu, o PR é bloqueado até que testes adicionais sejam escritos.

yaml
# GitHub Actions — envio de cobertura para Codecov
- name: Run Tests with Coverage
  run: ./gradlew testDebugUnitTest jacocoTestReport

- name: Upload to Codecov
  uses: codecov/codecov-action@v4
  with:
    files: ./app/build/reports/jacoco/jacocoTestReport.xml
    flags: unittests
    fail_ci_if_error: true

- name: Check Coverage Threshold
  run: |
    coverage=$(grep -oP 'branchCoverage="\K[0-9.]+' report.xml)
    if (( $(echo "$coverage < 80" | bc -l) )); then
      echo "Coverage $coverage% is below 80% threshold"
      exit 1
    fi

Relatórios e visualização

Relatórios HTML do JaCoCo e XCCov contêm destaque visual de cobertura: verde — linhas executadas, vermelho — não executadas. SonarQube adicionalmente mostra cobertura no nível de arquivo, classe, método e linha, bem como o histórico de alteração de cobertura por sprints. Isso ajuda a tomar decisões sobre refatoração e adição de testes.

Perguntas frequentes

Qual porcentagem de Code Coverage é considerada boa?

Para projetos mobile, cobertura de 70–80% para lógica de negócios e 50–60% para componentes de UI é considerada boa. Acima de 80%, os custos de teste começam a superar os benefícios. É importante lembrar que a porcentagem não é um objetivo, mas um indicador, e diferentes módulos podem ter diferentes níveis alvo.

Qual a diferença entre Line e Branch Coverage?

Line Coverage mostra quantas linhas de código foram executadas. Branch Coverage mostra quantas ramificações (if-else, switch) foram testadas. Uma linha com if pode ser executada, mas apenas o ramo true pode ter sido testado, e não o false. Branch Coverage é mais rigorosa e revela mais cenários perdidos.

Como integrar Code Coverage em CI/CD?

Em CI/CD, a cobertura é integrada através de um Quality Gate: o build é bloqueado se a cobertura estiver abaixo do limite. Para Android, usa-se JaCoCo + SonarQube; para iOS — xcodebuild -enableCodeCoverage com análise de .xccovreport. GitHub Actions tem ações prontas para Codecov.

Pode-se medir cobertura para Jetpack Compose?

Sim, JaCoCo suporta Jetpack Compose através do mecanismo padrão de cobertura JVM. No entanto, o código Compose contém muitas expressões lambda geradas que o JaCoCo pode não cobrir completamente. Recomenda-se excluir o código Compose gerado do relatório através de filtros.

Como evitar cobertura falsa?

Cobertura falsa ocorre quando um teste executa código mas não verifica o resultado. Solução: escrever asserções para cada cenário importante, usar mutation testing (Pitest) para verificar a qualidade dos testes, analisar não apenas a porcentagem mas também quais ramos estão cobertos.

Resumo

  • Code Coverage — métrica que mostra a porcentagem de código executado pelos testes, mas não garante ausência de bugs
  • Line e Branch coverage — métricas principais; Branch é mais rigorosa e revela ramos não testados
  • JaCoCo — ferramenta padrão para Android, XCCov — para iOS, ambos se integram com Gradle e Xcode
  • Cobertura alvo 70–80% para lógica de negócios — equilíbrio ideal entre qualidade e custo
  • TDD e parametrização — métodos eficazes para aumentar cobertura sem duplicar testes
  • SonarQube e Codecov — plataformas para monitoramento centralizado e Quality Gates em CI/CD
  • Regra principal: não persiga a porcentagem, mas cubra riscos críticos e casos limite

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