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:
Mais de 1500 cursos completamente atualizados, com novos lançamentos todas as semanas, emProgramação, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
Desafios temáticos para você turbinar seu portfólio. Você aprende na prática, com exercícios e projetos que simulam o dia a dia profissional.
Webséries exclusivas com discussões avançadas sobre arquitetura de sistemas com profissionais de grandes corporações e startups.
Emitimos certificados para atestar que você finalizou nossos cursos e formações.
Mais de 1500 cursos completamente atualizados, com novos lançamentos todas as semanas, emProgramação, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
Desafios temáticos para você turbinar seu portfólio. Você aprende na prática, com exercícios e projetos que simulam o dia a dia profissional.
Webséries exclusivas com discussões avançadas sobre arquitetura de sistemas com profissionais de grandes corporações e startups.
Emitimos certificados para atestar que você finalizou nossos cursos e formações.
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com Luri até 100 mensagens por semana.
Estude a língua inglesa com um curso 100% focado em tecnologia e expanda seus horizontes profissionais.
Acesso completo
durante 1 ano
Estude 24h/dia
onde e quando quiser
Novos cursos
todas as semanas