O sucesso de qualquer aplicativo depende de sua qualidade. Para que os clientes adorem um aplicativo e o divulguem por meio de publicidade boca a boca, ele deve fornecer a mais alta qualidade possível e resistir a condições adversas.
A garantia de qualidade desempenha um papel importante na resolução dos defeitos de um aplicativo antes que ele chegue à produção. Quase todas as equipes de software têm alguma forma de controle de qualidade como parte de seu ciclo de vida de desenvolvimento, mesmo que não haja uma equipe de controle de qualidade dedicada que apenas faça esse trabalho.
É da natureza da engenharia de software que novos recursos sejam construídos sobre a base de código existente. Portanto, o responsável pelo controle de qualidade terá que testar não apenas os novos recursos, mas também os existentes para garantir que o aplicativo funcione bem com os novos recursos integrados.
Agora o problema é: o tempo gasto no controle de qualidade aumentará a cada novo recurso e há uma chance muito real de que nem tudo será bem testado. Bugs podem facilmente cair na mão do usuário.
O teste de automação realmente ajuda aqui, automatizando parte do trabalho que o controle de qualidade faria manualmente. Podemos escrever um teste de automação para os recursos que o controle de qualidade já testou para que a equipe possa se concentrar em testar novos recursos enquanto os antigos são testados automaticamente. Isso economiza muito tempo e traz um nível mais alto de confiança ao enviar o aplicativo para produção.
Neste tutorial, apresentaremos o teste automatizado para Flutter e revisaremos como escrever cada tipo de teste de automação com um exemplo.
Aqui estão os três tipos de teste que abordaremos:
- Testes de unidade
- Testes de widget
- Testes de integração
Revisando nosso aplicativo de exemplo Flutter
Vamos dar uma olhada no aplicativo de amostra que iremos testar:
Para os fins deste tutorial, nosso requisito é que a lista de todos os produtos esteja disponível na página inicial do aplicativo. O usuário pode adicionar o produto ao carrinho clicando no ícone do carrinho ao lado dele. Depois de adicionado, o ícone do carrinho deve ser alterado.
Clicar no texto Carrinho deve abrir uma página do carrinho, que exibe uma lista de todos os produtos adicionados ao carrinho. Os produtos podem ser removidos do carrinho por meio do botão Cancelar ou deslizando para dispensar.
Escrevendo os testes para nosso aplicativo Flutter
Conforme discutido acima, iremos automatizar três tipos de testes para nosso aplicativo Flutter: testes de unidade, testes de widget e testes de integração. Um aplicativo pode ter várias combinações desses três testes, mas cabe a você projetar e implementar os testes de uma forma que forneça mais confiança para seu caso de uso.
Testes de unidade
Vamos começar com o teste de unidade do aplicativo. Isso testa o único método da classe, garantindo que o método forneça o resultado esperado com base na entrada fornecida a ele. Isso ajuda você a escrever um código mais testável e sustentável.
Nosso objetivo é escrever testes de unidade para a classe Carrinho
-para ser mais específico, nos certificaremos de que adicionar e remover métodos de produtos forneça o resultado correto.
Primeiro, adicione a dependência de teste:
dev_dependencies: teste: ^ 1.14.4
Esta é a classe Cart
, que possui métodos para adicionar e remover itens:
import'package: flutter/material.dart'; ///A classe [Cart] contém uma lista de itens do carrinho salvos pelo usuário. class Cart extends ChangeNotifier { Lista final_cartItems=[]; Listar obter itens=> _cartItems; void add (int itemNo) { _cartItems.add (itemNo); notificarListeners (); } void remove (int itemNo) { _cartItems.remove (itemNo); notificarListeners (); } }
A seguir, criaremos um arquivo para escrever casos de teste. Dentro da pasta test
(na raiz do projeto), crie um novo arquivo cart_test.dart
. Deve ser parecido com isto:
Agora adicione o código abaixo dentro dele:
N.B. , certifique-se de fornecer um arquivo de teste denominado como
(classToTest)_test.dart
.
import'package: flutterdemos/testingdemo/models/cart.dart'; import'package: test/test.dart'; void main () { group ('Testing Cart class', () { var cart=Cart (); //Teste 1 test ('Um novo produto deve ser adicionado', () { var product=25; cart.add (produto); esperar (cart.items.contains (produto), verdadeiro); }); //Teste 2 test ('Um produto deve ser removido', () { var product=45; cart.add (produto); esperar (cart.items.contains (produto), verdadeiro); cart.remove (produto); esperar (cart.items.contains (produto), false); }); }); }
Aqui, o Teste 1 verifica se o item adicionado deve existir na lista do carrinho e o Teste 2 verifica se o item removido não existe no carrinho. O método expect ()
é uma forma de validar nossa saída com expectativa.
Agora vamos executar o teste de unidade. Basta clicar no botão Reproduzir no IDE.
Você também pode tentar com o terminal usando o seguinte comando:
teste de vibração/cart_test.dart
Testes de widget
Como o próprio nome sugere, o teste de widget concentra-se em um único widget. Ao contrário do teste de unidade, o teste do widget garante que um widget específico esteja parecendo e se comportando como esperado. Você deve escrever um teste de widget para pelo menos todos os widgets comuns.
Nosso objetivo aqui é escrever um teste de widget para garantir que o página inicial está funcionando conforme o esperado.
Primeiro, adicione mais uma dependência de teste:
dev_dependencies: teste: ^ 1.14.4 # para teste de unidade flutter_test: sdk: flutter
Semelhante ao arquivo cart_test.dart
que criamos na seção anterior, agora criaremos mais um arquivo home_test.dart
dentro do test pasta. Vamos adicionar o código abaixo a ele.
Widget createHomeScreen ()=> ChangeNotifierProvider( criar: (contexto)=> Carrinho (), filho: MaterialApp ( home: HomePage (), ), ); void main () { grupo ('Testes de widget da página inicial', () { //Teste 1 testWidgets ('Título deve ser visível', (testador) async { aguarde tester.pumpWidget (createHomeScreen ()); expect (find.text ('Shopping App Testing'), achadosOneWidget); }); }); }
Os métodos abaixo são os blocos de construção para escrever nosso teste de widget:
-
createHomeScreen ()
-fornece a IU para a tela inicial que normalmente faríamos no arquivomain.dart
-
testWidgets ()
-cria oWidgetTester
que fornece maneiras de interagir com o widget que está sendo testado -
await tester.pumpWidget ()
-renderiza o widget fornecido -
find.text ()
-encontra o widget com o texto fornecido. Às vezes, podemos ter o mesmo texto na IU, entãofind.byKey (Key ('string'))
se torna realmente útil -
expect ()
-pega o widget encontrado e o compara com oMatcher
esperado, que pode serfoundOneWidget
,foundNothing
, etc.
Vejamos alguns outros casos de teste importantes que, de outra forma, teríamos que realizar manualmente. Aqui, testamos se a lista de produtos está visível na página inicial:
testWidgets ('A lista de produtos deve estar visível', (testador) async { aguarde tester.pumpWidget (createHomeScreen ()); expect (find.byType (ListView), findOneWidget); });
E aqui, testamos se o usuário é capaz de rolar a lista de produtos:
testWidgets ('Scroll test', (tester) async { aguarde tester.pumpWidget (createHomeScreen ()); expect (find.text ('Product 0'), findOneWidget); aguarde tester.fling (find.byType (ListView), Offset (0,-200), 3000); aguarde tester.pumpAndSettle (); expect (find.text ('Product 0'), findNothing); });
Uma lista completa pode ser encontrada aqui .
Agora execute o teste.
Testes de integração
Os testes de integração ajudam a realizar testes de ponta a ponta para o aplicativo. Eles nos permitem entender se os usuários são capazes de completar o fluxo completo do aplicativo. É essencialmente como testar um aplicativo real.
Ao contrário dos testes de unidade e de widget, os testes de integração são executados em um dispositivo real, então temos a chance de ver como os testes estão sendo realizados. Em um mundo perfeito, escreveríamos e executaríamos quantos testes precisássemos. Mas se tivermos tempo limitado, devemos absolutamente escrever um teste de integração, no mínimo.
Nosso objetivo aqui é testar se o usuário é capaz de adicionar e remover produtos de e para o carrinho. Esta é a dependência necessária para o teste de integração:
dev_dependencies: teste: ^ 1.14.4 # para teste de unidade flutter_test: # para teste de widget sdk: flutter flutter_driver: sdk: flutter teste_de_integração: ^ 1.0.1
Agora criamos a pasta integration_test
na raiz do projeto e adicionamos um arquivo driver.dart
dentro dela com o seguinte código:
import'package: integration_test/integration_test_driver.dart'; Futuromain ()=> integrationDriver ();
Em seguida, criaremos um arquivo app_test.dart
e adicionaremos o código abaixo:
void main () { group ('Testando fluxo de aplicativo completo', () { IntegrationTestWidgetsFlutterBinding.ensureInitialized (); testWidgets ('Adicionar produto e remover usando o botão Cancelar', (testador) async { aguarde tester.pumpWidget (MyApp ()); //Adicionar aguarde tester.tap (find.byIcon (Icons.shopping_cart_outlined).first); aguarde tester.pumpAndSettle (Duração (segundos: 1)); expect (find.text ('Added to cart.'), findOneWidget); //Mover para a próxima página aguarde tester.tap (find.text ('Cart')); aguarde tester.pumpAndSettle (); //Remover via botão de cancelamento aguarde tester.tap (find.byKey (ValueKey ('remove_icon_0'))); aguarde tester.pumpAndSettle (Duração (segundos: 1)); expect (find.text ('Removido do carrinho.'), findOneWidget); }); }); }
Como podemos ver no código acima, existem instruções para realizar ações e verificar os resultados, da mesma forma que faríamos manualmente:
-
await tester.tap ()
-clica no widget especificado -
await tester.pumpAndSettle ()
-quando os usuários clicam em um elemento de IU, pode haver uma animação. Este método garante que a animação se estabilizou dentro de uma duração especificada (por exemplo, se acharmos que o widget necessário ainda não está disponível), período após o qual estaremos prontos para novas instruções
Também temos uma cláusula para a remoção de produtos por meio de furto. O código para obter esse comportamento vai aqui:
//Remover via furto aguarde tester.drag (find.byType (Dismissible), Offset (500.0, 0.0)); aguarde tester.pumpAndSettle (Duração (segundos: 1)); expect (find.text ('Removido do carrinho.'), findOneWidget);
Finalmente, vamos executar o teste em um dispositivo real. Execute o seguinte comando no terminal:
unidade de vibração-teste de integração do driver/driver.dart-teste de integração de destino/teste do aplicativo.dart
Conclusão
Neste tutorial, apresentamos os testes de automação no Flutter e examinamos os vários tipos de testes que podemos escrever por meio de exemplos. Você pode ver o código-fonte completo com todos os casos de teste em meu GitHub.
A postagem Teste automatizado no Flutter: uma visão geral apareceu primeiro em LogRocket Blog .