Implementando Cobertura de Testes em Dart e Flutter
Conteúdo
- Fundamentos de Testes
- Diretivas de Cobertura
- Fluxo: Configuração e Geração de Relatórios de Cobertura
- Fluxo: Coleta Manual Avançada de Cobertura
- Exemplos
Fundamentos de Testes
Estruture suas suítes de teste usando os paradigmas padrão de teste do Dart. Use package:test para projetos Dart e flutter_test para projetos Flutter.
- Testes Unitários: Verificam funções, métodos ou classes individuais.
- Testes de Componente/Widget: Verificam comportamento, layout e interação de componentes usando objetos mock (
package:mockito). - Testes de Integração: Verificam fluxos completos do aplicativo em dispositivos simulados ou reais.
Diretivas de Cobertura
Exclua linhas, blocos ou arquivos inteiros das métricas de cobertura usando comentários inline. Passe a flag --check-ignore durante a formatação para aplicar essas diretivas.
- Ignorar uma linha:
// coverage:ignore-line - Ignorar um bloco de código:
// coverage:ignore-starte// coverage:ignore-end - Ignorar um arquivo inteiro:
// coverage:ignore-file
Fluxo: Configuração e Geração de Relatórios de Cobertura
Siga este fluxo sequencial para adicionar o pacote de cobertura, executar testes e gerar um relatório LCOV.
Lista de Tarefas:
- 1. Adicionar
coveragecomodev_dependency. - 2. Executar o script de cobertura automatizado.
- 3. Validar a saída LCOV.
1. Adicionar Dependências
Adicione o pacote coverage como dev_dependency ao seu projeto. Não o adicione às dependências padrão.
Se estiver trabalhando em um projeto Dart padrão:
dart pub add dev:coverage
Se estiver trabalhando em um projeto Flutter:
flutter pub add dev:coverage
2. Coletar Cobertura e Gerar LCOV
Use o script integrado test_with_coverage. Este script executa automaticamente todos os testes, coleta os dados JSON de cobertura da VM Dart e os formata em um relatório LCOV.
dart run coverage:test_with_coverage
Nota: Se estiver trabalhando em um workspace Dart (monorepo), especifique os diretórios de teste explicitamente (ex.: dart run coverage:test_with_coverage -- pkgs/foo/test pkgs/bar/test).
3. Feedback Loop: Validar Saída
Executar validador -> revisar erros -> corrigir:
- Verifique se o diretório
coverage/foi criado na raiz do projeto. - Certifique-se de que
coverage/coverage.json(dados brutos) ecoverage/lcov.info(relatório formatado) existem. - Se a cobertura estiver faltando para arquivos específicos, certifique-se de que eles sejam importados e executados pelos seus arquivos de teste, ou adicione
// coverage:ignore-filese forem intencionalmente excluídos.
Fluxo: Coleta Manual Avançada de Cobertura
Se você precisar de controle granular sobre o serviço VM, pausa de isolados ou cobertura em nível de ramificação/função, use o fluxo de coleta manual.
Lista de Tarefas:
- 1. Executar testes com o serviço VM habilitado.
- 2. Coletar cobertura JSON bruta.
- 3. Formatar JSON para LCOV.
1. Executar Testes com Serviço VM
Execute os testes enquanto pausa os isolados na saída e expõe o serviço VM em uma porta específica (ex.: 8181).
dart run --pause-isolates-on-exit --disable-service-auth-codes --enable-vm-service=8181 test &
2. Coletar Cobertura Bruta
Extraia os dados de cobertura do serviço VM em execução e envie-os para um arquivo JSON.
dart run coverage:collect_coverage --wait-paused --uri=http://127.0.0.1:8181/ -o coverage/coverage.json --resume-isolates
Opcional: Anexe --function-coverage e --branch-coverage para coletar métricas mais profundas (requer Dart VM 2.17.0+).
3. Formatar para LCOV
Converta os dados JSON brutos para o formato LCOV padrão.
dart run coverage:format_coverage --packages=.dart_tool/package_config.json --lcov -i coverage/coverage.json -o coverage/lcov.info --check-ignore
Exemplos
Exemplo: Configuração pubspec.yaml
Certifique-se de que seu pubspec.yaml reflita o pacote coverage estritamente sob dev_dependencies.
name: my_dart_app
environment:
sdk: ^3.0.0
dependencies:
path: ^1.8.0
dev_dependencies:
test: ^1.24.0
coverage: ^1.15.0
Exemplo: Aplicando Diretivas de Ignorar
Use diretivas de ignorar para evitar que código gerado ou casos de borda não testáveis reduzam as pontuações de cobertura.
// coverage:ignore-file
import 'package:meta/meta.dart';
class SystemConfig {
final String env;
SystemConfig(this.env);
// coverage:ignore-start
void legacyInit() {
print('Deprecated initialization');
}
// coverage:ignore-end
bool isProduction() {
if (env == 'prod') return true;
return false; // coverage:ignore-line
}
}