Logo Passei Direto
Buscar
Material

Prévia do material em texto

TESTES DE APLICATIVOS 
MÓVEIS 
AULA 3 
 
 
 
 
 
 
 
 
 
 
Prof. Felipe Pedroti Raymundo 
 
 
 
2 
CONVERSA INICIAL 
 Até agora tivemos contato com uma parte superficial do ponto de vista dos 
testes, principalmente para podermos ter uma base teórica boa e forte, para que 
os próximos conceitos possam ser aplicados de maneira fluida e simples. 
 Vimos que os testes existem das mais diversas maneiras e de vários tipos, 
cada um deles com sua devida importância dentro de um processo de 
desenvolvimento, independentemente do tipo de processo. Vimos também que 
testes podem ser aplicados não somente ao software propriamente dito, mas 
também às fases de design e construção conceitual do projeto, validando as 
informações levantadas pela equipe de análise. 
 Também vimos quem juntamente aos tipos e processos de testes 
existentes, podemos utilizar algumas ferramentas, os frameworks para que eles 
nos auxiliem nessa tarefa. 
 Nesta etapa, vamos aprofundar um pouco mais no que, ou melhor 
dizendo, o quanto podemos fazer utilizando esses frameworks, para iniciarmos 
a aplicá-los em nossas soluções. 
 
Crédito: Oleksiy Mark/Shutterstock. 
 
 
 
3 
TEMA 1 – VOLTANDO AOS TESTES UNITÁRIOS 
Se puxarmos na memória, vimos que existem várias fases de testes, com 
diversos tipos. Voltando aos processos de software, podemos notar que a 
estruturação dos nossos projetos em camadas é uma das soluções mais 
adotadas hoje, seja para diminuir o acoplamento entre artefatos de software, seja 
para facilitar a manutenção de uma interface de usuário, por exemplo, sem que 
esta afete diretamente as regras de negócio do software. 
Essa abordagem também vai facilitar (e muito), a vida do projetista de 
testes, principalmente porque ele vai poder escrever testes unitários para essas 
camadas, podendo, na maioria dos casos, automatizar os processos de 
publicação do software, passando por rotinas de testes para garantia da 
qualidade, o que deve ser muito reforçado nos times de desenvolvimento, apesar 
da negligência destes na maioria dos casos. 
Reforçando o conceito: testes unitários são pequenos trechos de código 
para testar o comportamento de outros trechos de código e estão dentro do nível 
de teste mais inferior, sendo um dos testes menos custosos para todo o projeto. 
Devem ser utilizados para verificar situações em que temos que validar, por 
exemplo, lógica, operações e resultados. 
Nabil (2022, tradução nossa) afirma que “muitos desenvolvedores 
subestimam a importância de escrever testes unitários”. Vamos observar 
algumas vantagens de utilizar testes unitários: 
1. Reduz o custo efetivo do teste, pois os defeitos já são identificados em 
fases iniciais do projeto (principalmente quando o conceito de TDD é 
aplicado); 
2. Gera de certa forma uma documentação do software, pois por eles temos 
uma visão geral do funcionamento de tudo; 
3. Reduz a complexidade de código (aqui o TDD é bem mais visível e 
aplicado, principalmente na sua fase 3 onde refatoramos o código-fonte 
escrito); 
4. Reduz a quantidade de bugs as realizar mudanças no código-fonte, pois 
se o teste estava passando, e agora não está o desenvolvedor tem um 
norte por onde começar. 
 
 
4 
5. Melhora não somente a estrutura, mas também permite que fique um 
código-fonte mais limpo devido a refatoração (novamente aplicando aqui 
o conceito da fase 3 do TDD). 
Um outro conceito que conseguimos obter (e como um próximo passo 
obter leituras e relatórios) é o da cobertura de código. Com testes unitários, 
podemos obter uma noção de quanto do nosso código temos testados e 
conseguimos saber onde e o que está ficando de fora dos testes. 
Analisando tudo isso, o que nos faz criar testes unitários eficientes? Ou o 
que determina que um teste unitário é bom ou ruim? Nabil (2022) enumera quatro 
pontos de atenção, sobre o que faz um teste unitário bom ou ruim: 
1. Testes devem ser executados de forma rápida; 
2. Testes devem ser totalmente automatizados, e a saída deve ser sempre 
binária, passou ou não passou; 
3. Testes unitários são unitários, não devem compartilhar estado nem 
informações com outros testes, ou seja, independentes e isolados; 
4. Devemos usar sempre TDD, escrevendo os testes antes de escrever 
código de produção. 
Figura 1 – Fluxo das fases do TDD 
 
 
 
 
 
5 
TEMA 2 – TESTES UNITÁRIOS EM APLICATIVOS HÍBRIDOS – XAMARIN 
Relembrando o que vimos no módulo de desenvolvimento híbrido, o 
Xamarin é um dos frameworks para desenvolvimento híbrido disponível no 
mercado. Ele vem de forma nativa durante a instalação do Visual Studio, e com 
ele podemos escrever um único código em que, independentemente do 
ambiente em que rode, o mesmo software com a mesma lógica será executado, 
e na maioria dos casos com a mesma interface. 
Um dos paradigmas mais fortes no desenvolvimento híbrido com Xamarin 
é a separação entre as camadas, utilizando um padrão de projeto conhecido 
como Model-View-ViewModel, ou MVVM. Esse conceito cai como uma luva para 
os times de teste, pois este é um padrão de projeto que visa separar a camada 
lógica da aplicação, da camada de apresentação, diminuindo o acoplamento 
entre elas. 
Vamos imaginar que temos uma base de código compartilhada, e 
precisamos criar testes para validar que a parte lógica do modelo esteja 
funcional. Em conjunto com o .NET, a Microsoft disponibilizou um framework 
para criação e escrita de testes de software, chamado de MSTest. Vamos 
observar a imagem a seguir para obter um norte sobre como está nossa base de 
código compartilhada. Neste exemplo usaremos um projeto do tipo class library, 
baseado no .NET Framework 4.8, conforme Figura 2. 
 
 
 
 
 
 
 
 
 
 
 
6 
Figura 2 – Classe calculadora e projeto 
 
A intenção aqui é saber como podemos testar se essas operações estão 
corretas, e fazendo o que é preciso fazer de verdade (somar e diminuir). Para 
isso, vamos adicionar um novo projeto a nossa solução de exemplo, do tipo Unit 
Test Project (.NET Framework). Ao adicionar o projeto, vamos ver que ele já vai 
ser criado com uma classe, contendo algumas instruções e atributos que vamos 
ver abaixo. 
O atributo (TestClass) fala para o framework que essa classe contém 
testes unitários. A anotação (TestMethod) indica que o método abaixo a ela é 
um método que será considerado como um teste. Para continuarmos, vamos 
adicionar o nosso projeto como referência ao projeto de teste e implementar de 
forma propriamente dita o nosso teste: 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7 
Figura 3 – Teste implementado 
 
Ao clicarmos com o botão direito do mouse sobre o nome do método de 
teste, podemos ver que uma opção vai surgir chamada Run Test. Ao selecionar 
essa opção, vamos ver que uma janela chamada Test Explorer surgiu na IDE, 
onde ela vai listar a nossa classe de teste e o método que executamos. 
Entretanto, vamos notar que o teste inicialmente não passou, e a mensagem 
mostrou que os resultados não são iguais. Isso ocorreu porque, 
intencionalmente, fizemos uma operação de soma de dois valores, porém o 
método está multiplicando dois valores. Vamos refatorar o código, e realizar a 
correção para ver o que o Test Explorer vai nos mostrar: 
Figura 4 – Janela de resultados do Test Explorer 
 
 
 
 
 
 
 
 
8 
Figura 5 – Método corrigido 
 
Figura 6 – Test explorer mostrando sucesso no teste 
 
Parece muito simples escrever testes unitários, porém, isso dá um poder 
para a equipe de desenvolvimento muito grande, principalmente quando 
estamos falando de muitas pessoas trabalhando num mesmo projeto. 
Neste exemplo, observamos uma instrução que vai garantir que os 
princípios para um bom teste unitário sejam garantidos. Ele executou 
rapidamente, testou um único pedaço de código sem compartilhar estado 
(isolado), deu um resultado único e booleano e passou (ou não passou, como na 
primeira execução). 
A garantia de automatizaçãodos testes unitários criados com o MSTest é 
dada pelas classes do tipo Assert. Entre alguns dos métodos mais comuns dessa 
classe, podemos citar os seguintes: 
• AreEqual e suas sobrecargas – método que compara tipos garantindo que 
sejam iguais; 
• AreNotEqual e suas sobrecargas – método que ao contrário do AreEqual, 
valida se os tipos comparados são diferentes; 
• AreSame e AreNotSame – métodos que comparam objetos e se são os 
mesmos; 
• Fail – método que lança uma exceção do tipo AssertFailedException; 
• IsFalse e IsTrue – métodos que comparam uma condição booleana; 
• IsNull e IsNotNull – métodos que validam se o objeto especificado é nulo 
ou não nulo. 
 
 
9 
É possível utilizarmos esse mesmo conceito para testar todas as camadas 
de um aplicativo Xamarin utilizando MVVM. Vale lembrar que a arquitetura facilita 
a aplicação do conceito, mas não é uma obrigatoriedade para que utilizemos 
testes no projeto. 
Figura 7 – Test explorer mostrando todos os testes na classe CalculadoraTest 
 
TEMA 3 – TESTES UNITÁRIOS EM APLICATIVOS HÍBRIDOS – OUTRAS 
PLATAFORMAS 
Sabemos que o Xamarin não é a única tecnologia para desenvolvimento 
de aplicativos híbridos disponível hoje no mercado. Muitas outras tecnologias, 
como o Flutter e o React, fazem esse trabalho com excelência também. Aqui fica 
a dúvida: existe a possibilidade de testar esses aplicativos com testes unitários? 
E a resposta é simples: sim. 
3.1 Flutter 
Vamos, inicialmente, abordar o Flutter. 
Assim como o Xamarin, no Flutter é possível criar classes e bibliotecas 
que podem ser reaproveitadas, e essas bibliotecas podem ser testadas sem 
problema nenhum. O Flutter, assim como o .NET, tem um pacote que permite 
que escrevamos testes unitários para nossa biblioteca, assim como o pacote 
flutter_test permite que escrevamos testes que validem o comportamento dos 
widgets. Vamos exemplificar a criação de testes em Flutter (o objetivo aqui é 
mostrar os recursos da plataforma para execução e criação de testes, não fazer 
uma visão geral de toda a plataforma e de como programar em Flutter). 
Nas classes a seguir, replicamos a mesma lógica que fizemos e a mesma 
classe calculadora abordada no segundo tópico. 
 
 
 
 
 
10 
Figura 8 – Classe Flutter calculadora 
 
Figura 9 – Classe Flutter calculadora_test 
 
Nessa situação, criamos uma classe de teste em que pedimos para que 
o método expect faça a comparação entre os resultados e valide se são o mesmo 
ou não. No Flutter, para agruparmos testes unitários de uma classe em uma 
execução utilizamos a instrução group: 
 
 
 
 
 
 
11 
Figura 10 – Agrupando testes unitários em Flutter 
 
As asserções dos testes escritos em Flutter são feitas utilizando o 
“expect()”. Esse método em específico pode utilizar qualquer combinação do 
pacote matcher do Flutter, para criar combinações complexas de validações. 
3.2 React Native 
Avançando nas tecnologias híbridas para a escrita de aplicativos, temos 
outro framework amplamente utilizado hoje para esse fim: o React. 
Testes em React são escritos utilizando uma biblioteca chamada Jest, que 
inclusive já vem habilitada quando criamos um projeto React Native seguindo o 
template padrão. 
Para criarmos um teste, vamos observar o exemplo a seguir, retirado da 
própria documentação do projeto. 
 
 
 
 
 
 
12 
Figura 11 – Unit test escrito em React com Jest. Reprodução 
 
A descrição do teste é data pela instrução it, e a string passada como 
primeiro parâmetro. Em seguida, passamos uma função, com as comparações 
que iremos fazer, em que a asserção do resultado vai ser feita pela função 
expect. A documentação recomenda que devemos sempre pensar em três 
pontos principais para escrever testes no React, também conhecido como AAA 
(Arrange, Act, Assert): 
1. Dada uma pré-condição; 
2. Quando a execução do que estamos testando esteja concluída; 
3. Então teremos o resultado esperado. 
Para que possamos agrupar a execução de testes no React, utilizamos a 
função describe, para que todos os testes de uma dada funcionalidade sejam 
executados juntos. 
TEMA 4 – TESTES UNITÁRIOS EM APLICATIVOS NATIVOS – ANDROID 
Nem somente de tecnologias de desenvolvimento híbridas sobrevive o 
mercado de aplicativos. Ainda muitos aplicativos que utilizamos no dia a dia são 
escritos utilizando as linguagens nativas de desenvolvimento. 
Neste tópico, vamos falar um pouco sobre como podemos aplicar TDD e 
testes unitários em um projeto nativo Android. 
Vamos, primeiramente, olhar como é a estrutura dos testes dentro de um 
projeto nativo (lembrando novamente que o objetivo aqui é mostrar como aplicar 
testes unitários dentro dos projetos, não dar uma visão geral sobre a plataforma 
e como codificar para ela). Aqui, o framework que está sendo utilizado é o JUnit, 
que já vem padrão com o template. 
 
 
 
 
 
 
13 
Figura 12 – Estrutura inicial de um projeto Android 
 
Nos projetos Android, temos duas pastas importantes quando tratamos de 
testes: androidTest, diretório que vai armazenar os testes que serão executados 
em dispositivos, geralmente testes de integração, ou de fim a fim; e test, que vai 
conter os testes que executaremos no ambiente local de desenvolvimento, como 
os testes unitários. 
Se observarmos com atenção, perceberemos que o template padrão de 
aplicativos Android até cria um arquivo de exemplo mostrando como os testes 
devem ser criados e executados. 
 
 
 
 
 
 
 
 
 
14 
Figura 13 – Teste padrão criado no aplicativo nativo Android 
 
A documentação do Android fala que as recomendações em relação aos 
tipos de teste unitários essenciais para que as boas práticas de programação 
sejam preservadas são as seguintes: 
• Criar testes unitários para ViewModels ou classes presenters; 
• Criar testes unitários para a camada de dados, especialmente 
repositórios; 
• Criar testes para outras camadas que não dependam da plataforma, como 
a camada de Domínio; 
• Criar testes para classes utilitárias. 
Vamos avançar um pouco e replicar nossa lógica da calculadora, criando 
uma classe que vai conter os métodos, e depois vamos criar uma nova classe 
de teste dentro do pacote test. 
 
 
 
 
 
 
 
 
15 
Figura 14 – Classe calculadora em Java 
 
Feito isso, se clicarmos no nome da classe e utilizarmos a combinação no 
teclado Alt + Insert, vamos ver que uma das opções é que criemos os testes para 
a classe em questão. Selecionada a opção, abre uma janela em que podemos 
configurar essa classe e selecionar quais métodos vamos testar nela. 
Figura 15 – Toolbox para criação de testes 
 
 
 
 
 
 
 
 
 
 
 
 
16 
Figura 16 – Classe de teste pronta para ser codificada 
 
A anotação “@Test” sobre os métodos da classe indica cada um dos 
testes unitários que serão executados dentro do ambiente. Vamos avançar o 
código para a implementação dos testes. Neste exemplo, podemos observar que 
a instrução asserEquals do JUnit é a responsável por validar se os resultados 
estão condizentes. Aqui um ponto de atenção é que, diferentemente das outas 
linguagens, o JUnit tem um valor de delta, que precisamos informar para poder 
calcular com que precisão a função vai trabalhar para definir que os resultados 
são iguais. 
 
 
 
 
 
 
 
 
 
 
 
 
17 
Figura 17 – Calculadora Test.java 
 
Ao clicarmos com o botão direito na classe e selecionarmos para que a 
IDE execute a classe de teste, ela será compilada e uma janela de execução 
será exibida, mostrando o resultado de todos os testes da classe, como podemos 
ver na Figura 18. 
Figura 18 – Janela do Android Studio mostrando o resultado dos testes 
 
TEMA 5 – TESTES UNITÁRIOS EM APLICATIVOS NATIVOS – IOS 
Para finalizarmos esta etapa, vamos observar como podemos fazer testes 
unitários dentro de um projeto iOS nativo, escrito em Swift. Para isso, a própria 
linguagem possui um framework específico para esse fim, conhecido comoXCTest. Por meio dele podemos escrever não somente testes unitários, mas 
 
 
18 
também como escrever testes que possam interagir com a interface do usuário 
para validar fluxos e/ou interações. 
Para que possamos criar os testes utilizando XCTest, devemos definir 
uma classe que herda de XCTestCase. Dentro destas classes, devemos criar 
métodos que não tenham retorno, parâmetros e que devem começar com o 
prefixo test, desta forma sendo detectados automaticamente pelo framework 
XCTest. Vejamos um exemplo a seguir, reproduzido da própria documentação. 
Figura 19 – Testes unitários em aplicativos nativos 
 
Nesse exemplo, podemos verificar que temos uma classe 
TableValidationTests, subclasse de XCTestCase, como orienta a 
documentação. Feito isso, foi criado um teste chamado 
testEmptyTableRowAndColumnCount(), onde utilizamos duas chamadas de 
asserções XCTAssertEqual, em que passamos os dados e uma mensagem caso 
o teste tenha resultado negativo. Existem inúmeros métodos e formas de 
asserções implementadas na API do XCTest, em que podemos ter uma visão 
geral na documentação do projeto. Além disso, seguindo os parâmetros, 
podemos utilizar uma função da IDE Xcode chamada Test Navigator, além de 
poder gerar relatórios de integração e identificação dos testes. 
 
 
 
 
 
 
 
19 
Figura 20 – Test navigator. Reprodução 
 
FINALIZANDO 
Pudemos verificar o que são testes unitários, bem como por que são 
importantes dentro do processo de desenvolvimento. Também validamos as 
vantagens e desvantagens de termos testes unitários no processo. 
Pudemos entender também o que faz um teste unitário bom ou ruim, e 
também entender que, por meio do TDD, esse processo fica muito mais natural. 
No segundo tópico, pudemos verificar como podemos escrever testes em 
aplicativos híbridos escritos em Xamarin, através do Visual Studio e do 
framework MSTest, visto que o próprio padrão de projeto do Xamarin chamado 
MVVM facilita a aplicação de testes unitários. 
Depois, continuamos vendo os testes unitários em ambientes híbridos, 
apresentando como fazer testes no Flutter e no React, utilizando os frameworks 
nativos de cada plataforma sendo o flutter_test e o Jest. 
Realizamos, então, a aplicação de testes unitários nos projetos nativos, 
sendo que primeiro vimos como escrever testes nos projetos Android, com JUnit, 
framework que já vem habilitado no template padrão de projetos nativos Android. 
Por fim, vimos como escrever testes unitários para projetos iOS escritos 
em Swift, utilizando o XCTest, e como devemos padronizar os testes de acordo 
com o indicado pela documentação. 
Em outra oportunidade, vamos começar a conhecer outra forma de teste 
de aplicativos, de forma que consigamos testar a interface dos nossos 
aplicativos. 
 
 
20 
REFERÊNCIAS 
NABIL, M. What is unit testing in mobile development? Bitrise, 14 jan. 2022. 
Disponível em: <https://blog.bitrise.io/post/what-is-unit-testing-in-mobile-
development>. Acesso em: 31 out. 2022. 
TESTING overview. React, S.d. Disponível em: 
<https://reactjs.org/docs/testing.html>. Acesso em: 31 out. 2022. 
UNIT TESTING C# with MSTest and .NET. Microsoft, 11 mar. 2022. Disponível 
em: <https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-with-
mstest>. Acesso em: 31 out. 2022. 
WHAT TO TEST in Android. Developers, S.d. Disponível em: 
<https://developer.android.com/training/testing/fundamentals/what-to-test>. 
Acesso em: 31 out. 2022. 
XCTEST. Developer, S.d. Disponível em: 
<https://developer.apple.com/documentation/xctest>. Acesso em: 31 out. 2022. 
	Conversa inicial
	FINALIZANDO
	REFERÊNCIAS

Mais conteúdos dessa disciplina