Boas-vindas ao nosso curso de Flutter: Testes de integração! Meu nome é Caio Couto Moreira, mas você pode me chamar de Kako.
Autodescrição: Sou um homem branco com nariz longo e olhos castanhos esverdeados. Meus cabelos são curtos e cacheados e, no momento, estão pintados de vermelho. Ao fundo, há uma parede com iluminação roxa e rosa.
Este curso é para pessoas que:
Antes de continuar, vamos conferir a interface do aplicativo de banco que usaremos ao longo deste curso.
A tela inicial é uma página de clientes em branco. No topo, há uma barra azul com o título "Clientes". No canto esquerdo da barra, há um ícone de menu, que exploraremos em breve.
No canto inferior direito da tela, há um botão flutuante redondo e azul com o símbolo de mais (floating action button). Ao clicar nele, uma caixa de diálogo surgirá no centro da tela com um formulário e podemos preenchê-lo para adicionar um cliente. Como exemplo, vamos adicionar o cliente Kako, informando seu e-mail e o tipo de cliente "Diamond":
- Nome: Kako
- Email: kako@alura.com
- Tipo: Diamond
Clicando no botão "Salvar" no canto inferior direito do formulário, o cliente "Kako (Diamond)" instantanemente será listado na página de clientes.
A seguir, pressionaremos o ícone de menu no canto superior esquerdo, para abrir o Drawer na lateral esquerda da tela. Esse menu facilitará nossa navegação para outras telas do aplicativo. Nele, temos listados:
Vamos navegar até a tela "Tipos de clientes", onde há uma lista padrão de tipos de clientes:
No canto inferior direito, vamos clicar no floating action button para acessar o formulário de adição de um novo tipo de cliente. Usaremos o nome "Bronze" e selecionaremos o ícone de uma pessoa correndo. Ao pressionar o botão "Salvar" no canto inferior direito, o novo tipo será instantaneamente listado na tela "Tipos de cliente".
Este é o nosso aplicativo! Ele não parece complexo, mas o funcionamento dele requer muitos conhecimentos (inclusive, de gerenciamento). Nosso objetivo será testar esse aplicativo de ponta a ponta, usando testes de integração!
A melhor forma de estudar este curso é assistir aos vídeos, fazer as atividades e, depois, tentar replicar os resultados por conta própria, sem acompanhar o material. Caso você tenha dúvidas, então você pode voltar ao vídeo para revisar e descobrir quais pontos esqueceu.
Se tiver dúvidas, você pode nos acionar no fórum ou no Discord! O engajamento com outros alunos te ajudará no seu crescimento profissional e no desenvolvimento de habilidades para o mercado de trabalho.
Vamos mergulhar em novo projeto?
Antes de começar a explorar os testes de integração, é importante revisar conceitos sobre testes de unidade e testes de widget. Eles precisam estar bem frescos na nossa memória para conseguirmos produzir testes de integração e entender a importância deles. Além disso, precisamos contextualizar nosso aprendizado. Vamos usar um exemplo concreto, por meio do storytelling.
Você se lembra da Dandara? Ela é nossa persona que conhecia apenas lógica de programação e se propôs a estudar Dart do início, passando por todos os cursos da Formação de Dart.
Ela foi evoluindo seus conhecimentos e também fez todos os cursos de Flutter. Agora, Dandara começou a se inserir no mercado de trabalho como freelancer — isto é, com trabalhos autônomos. Navegando pela internet, ela encontrou uma pessoa que fez o seguinte pedido:
Eu tenho um aplicativo de banco, pronto, bem simples. Eu quero garantir a qualidade do meu aplicativo, desenvolvendo testes. Só que eu não tenho tempo, então posso te pagar para você fazer esses testes para mim. Pode ser?
Assim, a Dandara conseguiu uma demanda, um freela! Então, nossa missão é realizar testes em um aplicativo que já está pronto. Não precisamos implementar novas funcionalidades, apenas garantir que o que foi implementado continue funcionando com a melhor qualidade possível.
Qual será nosso primeiro passo? Explorar o aplicativo e entender como ele funciona! O download dele está disponível na plataforma.
Vale ressaltar que já estamos em um nível mais intermediário de Flutter. Caso necessário, você pode voltar aos cursos anteriores da Formação de Flutter para revisar alguns conteúdos dos quais falaremos adiante.
Vamos abrir o Android Studio e usar o emulador para explorar o aplicativo. Ele consiste em apenas duas páginas, com alguns diálogos e algumas informações sendo gerenciadas. Vamos analisá-lo em detalhes, a seguir.
A tela inicial é a página de clientes, atualmente vazia, com o fundo branco:
No canto inferior direito, temos um floating action button (ou "FAB") azul para adicionar clientes, com o símbolo de mais. No topo, há uma barra azul com o título "Clientes". No canto superior esquerdo, há um ícone de menu.
Ao clicar no ícone de menu, o widget Drawer será aberto na lateral esquerda do aplicativo. Trata-se de um menu para navegação, onde temos listados:
Clicando em "Gerenciar clientes", voltamos para a página inicial de clientes. Clicando em "Tipos de clientes", somos redirecionados para a página "Tipos de clientes". Ou seja, acontece uma navegação, então é importante termos noções de navegação.
Na tela "Tipos de clientes", temos uma lista padrão de tipos sobre um fundo branco:
No canto inferior direito, há um floating action button (FAB) laranja, para adicionar um novo tipo de cliente. Clicando nesse botão, uma caixa de diálogo (alert dialog) surgirá no centro da tela com um formulário.
Como exemplo, vamos criar um tipo com o nome "Ferro" e selecionar o primeiro ícone — um gift card com um laço na parte superior. Na parte inferior da caixa de diálogo, temos os botões "Salvar" e "Cancelar" Clicando em "Salvar", o tipo "Ferro" será adicionado instantaneamente ao final da lista na tela "Tipos de clientes".
Como a atualização foi instantânea, sabemos que há algum mecanismo que faz nossa tela ser rebuildada quando um tipo de cliente é criado! Ou seja, também é importante termos noções de gerenciamento de estados, mais especificamente, o Provider.
Utilizando o menu lateral, voltaremos para a página de clientes. Atualmente, a tela está vazia, então vamos interagir com o FAB no canto inferior direito para criar um cliente.
Uma caixa de diálogo será aberta no centro da tela, com um formulário para cadastro de novo cliente:
- Nome: Kako
- Email: kako@alura.com.br
- Tipo: Ferro
Na parte inferior do formulário, clicaremos no botão "Salvar" e o cliente "Kako (Ferro)" será adicionado instantaneamente à lista. À direita dele, há um ícone que corresponde ao tipo Ferro.
Por fim, vamos acessar o menu lateral e selecionar a opção "Sair". Como esperado, o aplicativo será fechado.
Assim, conseguimos interagir com o aplicativo, conhecer suas funcionalidades e ter um melhor entendimento do projeto como um todo.
Já checamos como o aplicativo funciona no dispositivo, então o próximo passo é explorar o código! Como estamos em um nível intermediário de conhecimento de Flutter e já temos experiência em análise de códigos, recomendamos que você explore o código por conta própria.
Neste vídeo, vamos conferir rapidamente alguns desses arquivos e indicar alguns pontos para serem avaliados.
Na pasta "lib", vamos abrir o main.dart
. Esse arquivo possui um MultiProvider, então é importante que tenhamos conhecimentos sobre ele.
Temos também as pastas de telas, componentes e modelos. Como essas telas funcionam, como essas páginas navegam entre si? Será que é por rota, pelo Navigator com os métodos push()
e pop()
? É um ponto importante para se avaliar.
Na pasta "models", temos os modelos de clientes — como cada um deles funciona, como são adicionados ou modificados. Na linha 4 do arquivo clients.dart
, reparamos que ele possui um ChangeNotifier
, então é necessário compreender gerenciamento de estados com Provider.
Analisando os arquivos client.dart
e client_type.dart
, notamos que são modelos simples de informações que vamos manipular.
Portanto, recomendamos que você confira todos os arquivos e leia o código para ter uma ideia de como o projeto funciona. Caso não tenha familiaridade com algum elemento, você pode nos perguntar no fórum!
Após essa avaliação, nossa missão (e a da Dandara) será criar testes que garantam que o aplicativo funcione como deve funcionar! Começaremos com os testes mais simples (os testes de unidade) e depois escalaremos até os testes de integração!
Vamos começar com os testes mais fáceis: os testes de unidade.
Além de ser uma boa estratégia começar com o mais e progredir para o mais complexo, os testes de unidade garantem a qualidade da base do aplicativo. Se não garantirmos a base, todo o resto pode desmoronar! Logo, é importante fazer testes de unidade nos modelos do nosso projeto.
Vamos abrir nosso projeto no Android Studio. Na estrutura de arquivos à esquerda, temos uma pasta chamada "models" com quatro modelos:
client.dart
client_type.dart
clients.dart
types.dart
No arquivo client.dart
, temos um modelo simples que recebe um nome, um e-mail e um tipo. Essas informações são obrigatórias.
No arquivo clients.dart
, temos uma lista de clientes. Nós podemos manipulá-la, adicionando ou removendo clientes de algumas posições da lista.
No arquivo client_type.dart
, temos uma classe que recebe um nome e um ícone, correspondente ao tipo do cliente.
No arquivo types.dart
, temos uma lista de tipos que podemos manipular, adicionando ou removendo elementos, conforme seu index.
A seguir, realizaremos testes de unidade nesses modelos. Não vamos fazer o passo a passo desse processo, pois trata-se de um assunto que já estudamos no curso Flutter: aplicando testes de unidade, de Widget e Mocks.
Em vez disso, vamos revisar rapidamente o código já pronto para recapitular como esses testes são estruturados. Na pasta "test", criaremos um arquivo chamado unit_test.dart
com o seguinte conteúdo:
import 'package:client_control/models/client.dart';
import 'package:client_control/models/client_type.dart';
import 'package:client_control/models/clients.dart';
import 'package:client_control/models/types.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
group('Clients Test', () {
final kako = Client(
name: 'Kako',
email: 'kako@alura.com.br',
type: ClientType(name: 'Gold', icon: Icons.star));
test('Clients model should add new client', () {
var clients = Clients(clients: []);
clients.add(kako);
clients.add(kako);
expect(clients.clients, [kako, kako]);
});
test('Clients model should remove old client', () {
var clients = Clients(clients: [kako, kako, kako]);
clients.remove(0);
clients.remove(1);
expect(clients.clients, [kako]);
});
});
group('Types Test', () {
final gold = ClientType(name: 'Gold', icon: Icons.star);
test('Types model should add new type', () {
var types = Types(types: []);
types.add(gold);
types.add(gold);
expect(types.types, [gold, gold]);
});
test('Types model should remove old type ', () {
var types = Types(types: [gold, gold, gold]);
types.remove(0);
types.remove(1);
expect(types.types, [gold]);
});
});
}
A seguir, vamos conferir esse código por partes.
Da linha 1 a 6, temos todos as importações necessárias para que os testes funcionem — todos os clientes, o material.dart
e o flutter_test.dart
:
import 'package:client_control/models/client.dart';
import 'package:client_control/models/client_type.dart';
import 'package:client_control/models/clients.dart';
import 'package:client_control/models/types.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
A partir da linha 8, temos o void main()
, no qual criamos dois grupos de testes:
No primeiro grupo, criamos o cliente kako
. Seu nome é "Kako", seu e-mail é "kako@alura.com.br" e seu tipo é "Gold", com o ícone de uma estrela:
// ...
void main() {
group('Clients Test', () {
final kako = Client(
name: 'Kako',
email: 'kako@alura.com.br',
type: ClientType(name: 'Gold', icon: Icons.star));
// ...
O primeiro teste serve para garantir que é possível adicionar um cliente na lista de clientes. Criamos uma variável chamada clients
, que é uma lista de clientes Clients()
. Inicialmente, a lista está vazia.
Nas linhas 17 e 18, usamos o método add()
para adicionar o cliente kako
duas vezes. Na linha 19, indicamos que o resultado esperado é que a variável clients
tenha dois elementos kako
na lista:
// ...
test('Clients model should add new client', () {
var clients = Clients(clients: []);
clients.add(kako);
clients.add(kako);
expect(clients.clients, [kako, kako]);
});
// ...
O segundo teste serve para garantir que é possível remover clientes. Criamos uma lista de clientes com três clientes kako
. Nas linhas 24 e 25, usamos o método remove()
para remover os clientes das posições 0 e 1. Por fim, indicamos que o resultado esperado é uma lista com apenas um cliente kako
:
// ...
test('Clients model should remove old client', () {
var clients = Clients(clients: [kako, kako, kako]);
clients.remove(0);
clients.remove(1);
expect(clients.clients, [kako]);
});
// ...
Na sequência, temos o grupo de testes de tipo, que têm lógicas semelhantes às que acabamos de conferir. De início, criamos um tipo chamado "Gold", com o ícone de estrela:
// ...
group('Types Test', () {
final gold = ClientType(name: 'Gold', icon: Icons.star);
// ...
O primeiro teste checa se é possível adicionar um novo tipo à lista de tipos. Começamos com uma lista vazia e adicionamos o tipo "gold" duas vezes. Depois, indicamos que o resultado esperado é que a lista de tipos tenha dois elementos "gold":
// ...
test('Types model should add new type', () {
var types = Types(types: []);
types.add(gold);
types.add(gold);
expect(types.types, [gold, gold]);
});
// ...
O segundo teste checa a funcionalidade de remoção de tipos. Criamos uma lista com três tipos "gold"; removemos os elementos das posições 0 e 1; e espera-se que sobre apenas um tipo "gold":
// ...
test('Types model should remove old type ', () {
var types = Types(types: [gold, gold, gold]);
types.remove(0);
types.remove(1);
expect(types.types, [gold]);
});
// ...
Esses são nossos testes de unidade! Nosso objetivo era passar rapidamente pelo código, então sinta-se à vontade para analisá-lo com calma e em detalhes.
A seguir, executaremos os testes para conferir se eles passarão. No canto esquerdo da linha 8, vamos clicar no ícone verde de play e selecionar "Run tests in unit_test.dart". Alternativamente, podemos usar o atalho "Ctrl + Shift + F10". No terminal, após alguns segundos, notaremos que os quatro testes passaram!
Vale lembrar que não vamos alterar o projeto! O projeto não é nosso, somos responsáveis apenas por desenvolver os testes!
Para entender melhor, vamos pensar em um exemplo. Vamos supor que a pessoa responsável pelo projeto decidiu alterar o modelo de cliente e inserir um campo booleano obrigatório para informar se a pessoa cliente é canhota ou destra. Por exemplo:
// CÓDIGO DE EXEMPLO
import 'package:client_control/models/client_type.dart';
class Client {
String name;
String email;
ClientType type;
bool destro;
Client({
required this.name,
required this.email,
required this.type,
required this.destro
});
}
Com essa mudança, os testes que desenvolvemos param de passar. Na linha 10 do arquivo unit_test.dart
, a palavra Client
fica sublinhada em vermelho como indicação de erro, pois o parâmetro destro
é obrigatório, mas não o informamos.
Em outras palavras, caso haja alterações no futuro, os testes nos avisarão se é possível fazer determinadas alterações e garantir que tudo continuará funcionando.
No caso, este foi só um exemplo. Não vamos implementar esse campo no projeto! O arquivo client.dart
continua assim:
import 'package:client_control/models/client_type.dart';
class Client {
String name;
String email;
ClientType type;
Client({
required this.name,
required this.email,
required this.type
});
}
Portanto, realizamos os testes de unidade. O próximo passo é fazer testes de widget para conferir se tudo está funcionando como esperado.
O curso Flutter: implementando testes de integração possui 141 minutos de vídeos, em um total de 41 atividades. Gostou? Conheça nossos outros cursos de Flutter em Mobile, ou leia nossos artigos de Mobile.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.