paint-brush
Testando recursos nativos em aplicativos Flutter com Patrol e Codemagicpor@codemagic
802 leituras
802 leituras

Testando recursos nativos em aplicativos Flutter com Patrol e Codemagic

por Codemagic CI/CD9m2023/11/06
Read on Terminal Reader

Muito longo; Para ler

Patrol é uma nova ferramenta de teste do LeanCode que permite testar recursos nativos da plataforma em aplicativos Flutter. Agora você pode interagir com fluxos de autenticação do Google e da Apple, visualizações da web, alternar entre os modos claro e escuro, etc. Neste artigo, você também aprenderá como usar o Patrol em seus fluxos de trabalho Codemagic CI/CD.
featured image - Testando recursos nativos em aplicativos Flutter com Patrol e Codemagic
Codemagic CI/CD HackerNoon profile picture
0-item
1-item

"Não adianta! Não consigo fazer um teste ponta a ponta com os testes de integração do Flutter", exclamou um de nossos clientes há cerca de 9 meses. Perguntei qual era o problema e eles explicaram que estavam usando o Google Authentication para fazer login e usaram o pacote google_sign_in , mas não foi possível usar os testes de integração do Flutter para interagir com as telas de login. Eu ainda não entendi muito bem qual era o problema e então cliquei: este plugin usa componentes de UI nativos com os quais os testes de integração não funcionam.


Fiquei bastante desapontado por não poder oferecer uma solução na época e tive que deixar por isso mesmo. No entanto, avançando até hoje, uma nova solução incrível se apresentou, chamada "Patrol" por Código Lean . Vou contar tudo sobre isso, mas antes de começarmos, vamos recapitular por que é importante executar testes, quais ferramentas você tinha disponíveis até agora e depois falar sobre como começar a usar o Patrol.

Afinal, por que testar aplicativos Flutter?

Uma das principais razões pelas quais as equipes de desenvolvimento usam serviços de integração contínua (CI), como Código mágico é obter feedback imediato sobre o código que eles estão comprometendo em seu repositório. Os testes podem ser executados automaticamente como parte do seu pipeline para garantir um nível de qualidade e estabilidade, pois bugs ou problemas podem ser detectados antecipadamente e corrigidos imediatamente. Sempre incentivamos os clientes a implementar testes ao configurar seus fluxos de trabalho, mas não é incomum ouvirmos “Não temos tempo para escrever testes”. Esperamos que você não esteja nesse barco e use os testes como parte de seu ciclo de desenvolvimento de aplicativos para fornecer aplicativos de ótima qualidade e sem bugs!

Quais são as principais formas automatizadas de testar aplicativos Flutter?

Existem quatro métodos principais de teste que podem ser automatizados como parte do seu fluxo de trabalho de CI. O teste é um tópico em si, então serei breve, mas usar uma combinação desses métodos de teste ajudará você a melhorar a qualidade do seu aplicativo e detectar problemas mais cedo ou mais tarde.


Em primeiro lugar, existe o "teste de unidade" , que é comumente usado para testar suas funções e métodos isoladamente para garantir que funcionem conforme o esperado. Testes unitários também podem ser escritos para garantir que sua lógica de negócios funcione em diferentes cenários sem resultados inesperados.


A seguir, temos os "testes de widget" do Flutter, que permitem testar seus componentes de IU e garantir que eles sejam renderizados corretamente e funcionem conforme o esperado.


Depois, há o "teste de integração" , onde você testa se as unidades e componentes do seu aplicativo funcionam juntos conforme o esperado.


Finalmente, há o "teste de UI ponta a ponta" , onde você testa o aplicativo como se estivesse sendo usado por um usuário real. Em um fluxo de trabalho de CI, isso geralmente é automatizado usando simuladores ou emuladores para testar diferentes caminhos em seu aplicativo para garantir que não haja problemas após você fazer alterações em seu código.


É aqui que o cliente de quem falei no início ficou preso porque não conseguiu executar os testes de IU ponta a ponta porque não foi possível fazer login no aplicativo. Na época eles testaram uma versão ‘dev’ que contornava a parte de login.


No entanto, isso não é mais necessário agora que "Patrol" está disponível!

Entre, palco à esquerda, Patrulha!

Então, antes de mais nada, o que é Patrulha? Bem, acho que os documentos dizem melhor:


Patrol é uma estrutura de teste de UI nova e de código aberto para Flutter desenvolvida pela LeanCode. Ele se baseia nas ferramentas de teste existentes do Flutter para permitir que você faça coisas que antes eram impossíveis. Patrol permite acessar recursos nativos da plataforma em que o aplicativo Flutter está sendo executado.


A parte mais importante aqui é que ele permite acessar os recursos nativos da plataforma em que seu aplicativo Flutter está sendo executado.


Isso significa que agora você pode fazer coisas como:


  1. Interaja com as caixas de diálogo de solicitação de permissão para descartar ou aceitar solicitações.
  2. Interaja com WebViews.
  3. Minimize e maximize seu aplicativo.
  4. Interaja com fluxos de autenticação como autenticação Google ou Apple.
  5. Interaja com outros recursos nativos, como abrir a bandeja de Notificações, pressionar o botão Home, ativar ou desativar a conectividade Wi-Fi ou alterar o dispositivo para o modo escuro, etc.


Ok, isso parece ótimo, mas qual é o truque?


Bem, não há um! E mais, não é apenas gratuito , mas também Código aberto !


Além disso, o Patrol também apresenta 'localizadores personalizados' que fornecem uma sintaxe mais concisa para escrever seus testes. Você pode ler mais sobre eles aqui .

Instalando e configurando o Patrol

Para começar a usar o Patrol, você precisará instalar a CLI, adicionar a dependência do Patrol ao seu pubspec.yaml e definir algumas configurações em seus projetos iOS e Android.


LeanCode criou uma ótima documentação aqui que orienta você no processo de cada plataforma que você pode encontrar aqui. O guia passo a passo guiará você pela configuração para iOS e Android .


Se você tiver algum problema, o melhor lugar para obter ajuda é no servidor Patrol Community Discord , no qual você pode ingressar aqui .


Se você encontrar algum bug, poderá levantar um problema aqui .

Instalando e configurando o Patrol

Para começar a usar o Patrol, você precisará instalar a CLI, adicionar a dependência do Patrol ao seu pubspec.yaml e definir algumas configurações em seus projetos iOS e Android.


LeanCode criou uma ótima documentação aqui que orienta você no processo de cada plataforma que você pode encontrar aqui. O guia passo a passo guiará você pela configuração para iOS e Android .


Se você tiver algum problema, o melhor lugar para obter ajuda é no servidor Patrol Community Discord , no qual você pode ingressar aqui .


Se você encontrar algum bug, poderá levantar um problema aqui .

Escrevendo testes de recursos nativos com Patrol

Agora que está tudo pronto, vamos começar a testar alguns recursos nativos. Para experimentar sozinho, configurei um aplicativo Flutter simples com um botão elevado que, quando clicado, abre uma caixa de diálogo de alerta nativa .


Clicar em “OK” ou “Cancelar” simplesmente descarta a caixa de diálogo.


Teste o aplicativo com recursos nativos


Novamente, eu recomendaria usar a documentação do próprio Patrol, que você pode encontrar aqui para adicionar seu primeiro arquivo de teste.


Então, para o meu teste, eu queria clicar no botão elevado que contém o texto "Clique em mim!". É um widget Flutter padrão, portanto pode ser tocado usando o seguinte localizador de patrulha:


 await $('Click me!').tap();


A caixa de diálogo nativa deve então ser exibida, para que possamos começar a interagir com um componente de UI nativo. Então, vamos adicionar o localizador nativo que nos permitirá tocar no botão "OK":


 await $('Click me!').tap(); await $.native.tap(Selector(text: 'OK'));


Essa foi fácil! Também quero testar o botão "Cancelar", então vamos tocar no botão "Clique em mim!" botão novamente e, em seguida, toque no botão "Cancelar" da caixa de diálogo nativa adicionando mais algumas linhas da seguinte maneira:


 await $('Click me!').tap(); await $.native.tap(Selector(text: 'OK')); await $('Click me!').tap(); await $.native.tap(Selector(text: 'Cancel'));


Seu arquivo de teste concluído deve ficar assim:


 import 'package:cmpatrol/main.dart'; import 'package:patrol/patrol.dart'; void main() { patrolTest( 'Native tests', nativeAutomation: true, ($) async { await $.pumpWidgetAndSettle(const MyApp()); await $('Click me!').tap(); await $.native.tap(Selector(text: 'OK')); await $('Click me!').tap(); await $.native.tap(Selector(text: 'Cancel')); await $('Click me!').tap(); await $.native.tap(Selector(text: 'NO')); }, ); }


Agora você deve conseguir executar esse teste em seu emulador ou em um dispositivo real usando o comando para iniciar o teste. Meu arquivo de teste de integração se chamava "button_test" , então iniciei os testes no Terminal da seguinte maneira:


 patrol test -t integration_test/button_test.dart


Você verá se seus testes foram aprovados ou reprovados diretamente no Terminal. Se os testes falharem, você receberá um link para o relatório de teste completo. Como alternativa, se você estiver executando seus testes no Android como eu fiz, você poderá acessar o relatório clicando em index.html no seguinte diretório:


 ./build/app/reports/androidTest/connected 


Índice Gradle.html


Você pode experimentar outros recursos nativos, como abrir a bandeja de notificações, desativar o wifi, ativar o modo escuro, minimizar e maximizar o aplicativo:


 // minimize app await $.native.pressHome(); await $.native.openNotifications(); await $.native.disableWifi(); await $.native.enableDarkMode(); // maximize app await $.native.openApp();


⚠️ Observe que não é possível fechar completamente seu aplicativo e reabri-lo, pois isso encerraria todo o teste e, portanto, faria com que ele falhasse.


Consulte a Patrulha documentação para mais exemplos.

Usando Patrol em seus fluxos de trabalho Codemagic

Para incorporar o Patrol em seus fluxos de trabalho, primeiro você terá que instalar o Patrol CLI na máquina de construção. Isso leva apenas alguns segundos e, uma vez feito isso, você pode executar seu script de teste. Abaixo está um exemplo de como você adicionaria essas etapas à seção "scripts" do seu arquivo de configuração codemagic.yaml . Eu recomendaria executar o script para instalar o Patrol CLI como uma das primeiras etapas do script e então você pode executar seus testes Patrol imediatamente depois disso ou após qualquer outro teste que você também queira executar anteriormente.


Antes de executar os testes do Patrol, você precisará iniciar o emulador, então adicionaremos um script para iniciar o emulador e esperar que ele seja totalmente inicializado. Observe que os emuladores Android não estão disponíveis em máquinas que usam máquinas Apple Silicon M1 ou M2 devido ao Apple Virtualization Framework não oferecer suporte à virtualização aninhada. Portanto, eu recomendaria usar uma instância Linux ao testar aplicativos Android.


A seção de scripts do seu codemagic.yaml deve ser semelhante a esta:


 scripts: ... - name: Install Patrol CLI script: dart pub global activate patrol_cli - name: Launch Android emulator script: | cd $ANDROID_HOME/tools emulator -avd emulator & adb wait-for-device - name: Run tests with Patrol script: patrol test -t integration_test/your_test.dart ignore_failure: true ...


Mostrando resultados do teste Patrol nos logs de construção do Codemagic

Os resultados do teste Patrol também estão disponíveis no formato JUnit XML , o que significa que podem ser exibidos nos logs de construção na tela de visão geral de construção do Codemagic. Você só precisa adicionar a propriedade test_report no caminho para o arquivo JUnit XML que é gerado. Você pode usar a propriedade ignore_failure com um booleano para controlar se deseja que o restante do fluxo de trabalho continue em execução ou não. Se quiser fazer upload de seus resultados para um sistema de gerenciamento de testes conforme descrito na próxima seção, você deve definir isso como true .


Aqui está um exemplo de como seu script deve ser:


 scripts: ... - name: Run tests with Patrol script: | patrol test -t integration_test/your_test.dart test_report: build/app/outputs/androidTest-results/connected/*.xml ignore_failure: true ...


Um teste com falha pode ser algo assim:


Falha no resultado do teste JUnit XML no log de compilação do Codemagic

Reunindo o relatório de teste do Patrol como um artefato de construção

Uma coisa adicional que você pode querer fazer é reunir a saída do relatório de teste como um artefato de construção para poder visualizar o relatório completo caso ocorra algum erro. Isso disponibilizará o relatório para download como um arquivo zip na tela de visão geral da construção, na seção "Artefatos" no lado esquerdo. A maneira mais fácil de fazer isso é copiar o diretório em que os arquivos de relatório estão para o diretório que o Codemagic usa para exportar artefatos. Há uma variável de ambiente integrada chamada $CM_EXPORT_DIR que faz referência a este diretório que você pode usar em seu script.


O script para fazer isso deve ser assim:


 scripts: ... - name: Export Patrol test report script: | cp -r build/app/reports/androidTests/connected $CM_EXPORT_DIR/report ...


Conclusão

O Patrol finalmente superou o problema de execução de testes de UI e integração que envolvem recursos nativos. Agora é possível testar recursos nativos e interagir com fluxos de autenticação, diálogos nativos e até mesmo alternar recursos nativos como wifi, celular, modo escuro e até mesmo minimizar e maximizar seu aplicativo. Além disso, é gratuito e de código aberto e fornece uma solução para um problema real que existe desde o lançamento do Flutter. Além do mais, é fácil adicioná-lo e usá-lo em seus fluxos de trabalho Codemagic. Se você quiser apoiar o excelente trabalho que o LeanCode está fazendo, dê um like no Patrol em pub.dev aqui e dê uma estrela ao repositório Patrol GitHub aqui .




Este artigo foi escrito por Kevin Suhajda, chefe de engenharia de soluções da Código mágico . Você pode encontrar Kevin em X , GitHub , e LinkedIn .


Também publicado aqui .