Prévia do material em texto
TESTES EM APLICATIVOS MÓVEIS AULA 2 Prof. Felipe Pedroti Raymundo 2 CONVERSA INICIAL Já tivemos anteriormente um panorama mais conceitual sobre testes de software, o processo e os tipos que podemos realizar e em que fases são aplicados. Nesta etapa, vamos conhecê-los de forma geral, porém já entrando com o conceito para o mundo mobile. Com o avanço das tecnologias e a crescente presença dos smartphones em nosso dia a dia, é necessário que, ao construirmos qualquer solução para esse tipo de dispositivo, as testemos, assim como faríamos com uma solução tradicional escrita para desktop ou web. Porém, quando falamos sobre mobilidade ou dispositivos móveis, entramos em um mundo no qual inúmeras variáveis podem afetar o comportamento do nosso aplicativo, seja uma tela, seja um recurso de hardware, seja um menu em tela do sistema operacional do smartphone. Dessa forma, vamos recapitular alguns pontos e conceitos sobre smartphones e ver essas nuances que afetam os testes para depois avançar a fim de entender onde os testes de software se encaixam nesse mundo mobile. Créditos: Gorodenkoff/Shutterstock. TEMA 1 – SMARTPHONES: O FUTURO Desde os meados de 2007, com o lançamento do primeiro iPhone® no mercado de smartphones, temos desde comunicadores a players de multimídia e utilidades diárias na palma de nossas mãos. Independentemente da 3 construção, linguagem de programação ou processo, temos coisas que antes eram objetos, como calculadoras ou níveis de construtor, na palma da mão em forma de software, um código binário compilado que nos faz rir ou não perdermos a conta na hora de dividir o almoço entre os amigos. Mas para que isso funcione de forma correta, todas essas ferramentas passaram por um controle de qualidade dentro do processo de criação deles. Estamos falando dos testes, extremamente necessários. Imagine o seguinte cenário: o usuário “x” utiliza o aplicativo em um aparelho com tela de 5 polegadas, porém o usuário “y” o usa em um aparelho de 6,5 polegadas. Como será o comportamento do aplicativo nesses dois dispositivos? Por isso, devemos entender primeiramente quais são as variáveis que devem ser levadas em conta na hora mais importante do processo de teste: seu planejamento. 1.1 Variáveis do mundo mobile Você deve estar se perguntando: por que essas variáveis do mundo mobile têm de ser tão conhecidas pelo time e ser consideradas no planejamento? Vamos pensar, por um lado, onde nós nos encontramos, todos e, sem exceção, o consumidor. Há aparelhos com mais recursos, outros com menos, uma câmera melhor, mais memória, uma tela maior e mais sensível ao toque, tudo isso levando em conta o preço do aparelho, marca etc. Mas assim como um software para desktop, devemos pensar que o usuário vai tentar executar aquele aplicativo nas piores condições possíveis, isso sendo otimista. Por isso, o software, ao ser testado, deve ter em mente algumas variáveis que vamos detalhar a seguir. Primeiro, devemos considerar o sistema operacional onde vamos executar o software. O comportamento, mesmo trabalhando com tecnologias híbridas como o Xamarim (que foi visto anteriormente), pode variar de sistema para sistema. Os dois maiores hoje são o iOS® e o Android®, das fabricantes Apple e Google, respectivamente. Por isso, as características desses sistemas devem ser levadas em consideração. Em segundo lugar, devemos pensar no desempenho do dispositivo. Comparando um pouco com o cenário web, um aplicativo instalado no dispositivo por si só já é mais rápido, porém as operações que ele realiza serão comportadas e computadas em tempo hábil pelo dispositivo? Vale lembrar novamente que existem aparelhos top de linha com memória RAM disponível 4 como se fosse um computador, bem como outros mais simples, às vezes com um oitavo dessa memória disponível. Em terceiro lugar, devemos ter em conta os recursos do aparelho. Aqui muitas vezes confundimos recursos com desempenho, mas são duas coisas distintas. Nesse ponto, precisamos considerar o que o aparelho pode fazer por nós: sensores, câmera, GPS, acelerômetros etc. Ao planejar o aplicativo e os testes desses recursos, é necessário que saibamos que tais recursos podem ou não estar presentes nos aparelhos em que vamos executar nosso aplicativo. 1.2 Outras considerações nos testes Além desses pontos, devemos pensar em outros três pontos que podemos considerar até mais importantes do que os anteriores. À frente de tudo, devemos citar a segurança. Os aplicativos, antes de mais nada, devem ser seguros e garantir que a informação ali dentro não seja violada de forma alguma; qualquer comunicação externa deve ser criptografada. Depois, temos a usabilidade, que vai validar se o aplicativo é não somente amigável à visão e utilização do ponto de vista do usuário, mas compatível com a plataforma onde está sendo executado e se é de fácil aprendizado e utilização. Por fim, podemos citar também as plataformas de desenvolvimento. Mesmo pensando que grande parte dos iPhones e aparelhos Android rodam versões atuais do sistema, ou, se não atuais, com pelo menos os recursos necessários para executar os aplicativos garantindo os princípios acima, existe uma grande maioria de aparelhos hoje ativos com sistema defasados e antigos, e os usuários estão sedentos por utilizar versões mais recentes com os melhores recursos dos nossos apps. TEMA 2 – TESTES EM APLICATIVOS MÓVEIS Neste tópico, trataremos um pouco mais especificamente dos tipos de testes que vamos aplicar nos projetos de aplicativos. Já vimos que eles são inúmeros e que se encaixam perfeitamente em cada um dos pontos de atenção que devemos ter ao criá-los e planejá-los no processo de desenvolvimento. 5 2.1 Teste de compatibilidade O teste de compatibilidade é o primeiro que devemos ter como foco em nosso ambiente. Vamos lembrar que todo aplicativo interage, levando e trazendo informação para o usuário por meio do hardware e de recursos disponíveis. Porém, o fato de que cada fabricante tem um jeito de construir hardware e software faz com que conhecer essa compatibilidade nos dê uma vantagem competitiva. Por isso, Matos e Pires ([S.d.]) dizem que “realizar testes com cada um desses hardwares existentes seria uma tarefa hercúlea, para isso existe alguns padrões de desenvolvimento que devem ser seguidos”. Esses padrões garantem que o aplicativo sendo escrito vai se comportar da maneira esperada e ser executado perfeitamente nos mais diversos aparelhos. Outra vantagem citada por Matos e Pires ([S.d.]) é que em casos de atualização do sistema operacional, os aplicativos que seguem os padrões passam por nenhuma ou mínimas alterações no seu funcionamento. Créditos: everything possible/Shutterstock. 2.2 Teste de mobilidade ou interoperabilidade Trata-se de testes que vão validar a capacidade do aplicativo de trabalhar de forma desconectada e de se comunicar com outros aplicativos, visto que o compartilhamento de informações é vital para os aplicativos móveis. Vale 6 lembrar que as informações geradas neles não podem ser acessadas por outro aplicativo senão por meio do compartilhamento destas. Nesses testes também se verifica se o aplicativo segue os padrões de compartilhamento de informações, facilitando assim a iteração com o que já existe (fazendo aqui uma conexão com os testes de compatibilidade, visando garantir a padronização de tudo). 2.3 Teste de usabilidade Esse teste foca principalmente o uso do aplicativo pelos usuários. Além de ser recomendada a utilização novamente de padrões já existentes, tal teste vem com o objetivo de garantir que o aplicativo, implicitamente, faça com que o usuário o utilize de maneira natural, pois ele já está acostumado com o que está vendo. Nesse ponto, é interessante que os padrões de componentese de exibições utilizadas na criação do aplicativo estejam alinhados com os padrões do dispositivo (novamente aqui fazendo uma conexão com os testes de compatibilidade, reforçando a necessidade de padronização dos aplicativos e componentes) para que o usuário não tenha dificuldade em utilizá-lo. Créditos: Redpixel.PL/Shutterstock. 7 2.4 Teste de desempenho Esse teste tem a obrigação de capturar e identificar os problemas e lentidões do sistema. Matos e Pires ([S.d.]) afirmam que “os testes de desempenho se baseiam na identificação e eliminação de gargalos de desempenho com o objetivo de descobrir o local da lentidão do sistema para, logicamente, aperfeiçoar o seu código e tornar o aplicativo mais leve possível”. Aqui é importante novamente voltarmos aos testes de compatibilidade, pois, falando em termos mais coloquiais, não é porque instala que roda. Se pensarmos que dispositivos de baixo custo têm hardware inferior ou mais lento que aparelhos top de linha, se os requisitos forem supridos pelo sistema operacional, o usuário pode até instalar o aplicativo, porém o desempenho dele ficará aquém da necessidade, se tornando às vezes um problema de usabilidade para o usuário. Além dessa validação, aqui comumente são aplicados testes de carga e de estresse do aplicativo a fim de validar o comportamento do aplicativo. Créditos: rawf8/Shutterstock. TEMA 3 – AINDA SOBRE OS TIPOS DE TESTE Vimos no tópico anterior quatro dos seis tipos de testes que podemos aplicar sobre os aplicativos. Porém, separamos outros dois tipos por terem uma importância direta nos dias de hoje para garantir o sucesso de um aplicativo. 8 3.1 Teste de sincronismo Hoje em dia, podemos afirmar com toda a certeza que não vivemos pelo menos 80% (senão 100%) dependentes da internet. Seja uma pesquisa, seja um jogo on-line, seja um trabalho, a internet está ali e vai permanecer durante muito tempo. E se pensarmos nas informações que geramos diariamente em nossos dispositivos, temos – por mais superficial que isso pareça a alguns – a necessidade de armazenar esses dados e sincronizá-los com algum armazenamento seguro para que, caso o pior aconteça com o dispositivo, ainda possamos recuperá-los. Realizar testes desse sincronismo de informações é vital para que o usuário tenha segurança e confiança na utilização do aplicativo. Muitas vezes, esse é o ponto-chave para a escolha do aplicativo. Aqui, devemos validar se as informações estão sendo enviadas à plataforma que irá armazená-las, se chegaram íntegras e de forma segura. Créditos: Net Vector/Shutterstock. 3.2 Teste funcional Esse teste é o mais importante dos seis tipos que tratamos até aqui. É ele que vai garantir que o aplicativo está funcionando conforme o planejado, 9 implementado e validado. Tudo o que foi levantado durante a coleta de requisitos (funcionais e não funcionais) é validado pelo time de testes, baseado nessas especificações, e eles terão o papel de assegurar que tudo esteja dentro do esperado, evitando assim a entrega de um aplicativo TEMA 4 – TESTES UNITÁRIOS, VALIDANDO O CÓDIGO DE UM APLICATIVO Fazendo uma relação com o que já estudamos anteriormente, muitos dos tipos de testes que executamos nos aplicativos criados se baseiam nos requisitos ou têm uma interação natural por parte do time de testes para que possam validar o que estão vendo. Porém, existe uma peça muito importante nisso tudo da qual não podemos nos esquecer: o código-fonte. Novamente de uma forma coloquial, não é porque está rodando, que está certo. Pensando dentro de um ciclo de projeto, é muito custoso erros no código-fonte para a equipe, pois é necessário despender tempo em correções que deveria ser gasto com a implementação de novas funcionalidades dentro do software. 4.1 O que são testes unitários Unidade (ou no inglês Unit) é a menor parte testável de um software. Testes unitários são literalmente pedaços de código que testam código. O objetivo é isolar pequenas partes do código-fonte de um aplicativo e validar se os retornos e chamadas dentro daquele método estão corretos. Segundo Hamill ([S.d.], em tradução livre), “no jargão tradicional de testes, eles são categorizados como caixa-preta ou caixa-branca, dependendo do nível de acesso ao funcionamento interno do que está sendo testado”. Os testes unitários têm de ser planejados de forma que o desenvolvedor conheça as entradas (ou desenhe o teste para que tenha as entradas, sejam verdadeiras, sejam falsas) e a saída que aquela unidade deve emitir para os dados processados. Vale relacionar isso com o que já vimos anteriormente, ou seja, os testes unitários são testes de caixa-branca, pois conhecemos o código que será testado. A vantagem de se utilizarem testes unitários vem não somente do fato de que o desenvolvedor está criando o teste, bem como hoje em dia em ambientes de DevOps – de modo simplificado, trata-se de ambientes onde os profissionais de TI que escrevem o código são integrados com os profissionais de TI que o 10 liberam – utilizam testes unitários para automatizar a geração de versões testáveis de softwares somente se nenhum deles falhar. Outra vantagem de utilizar testes unitários está na garantia de que a alteração em uma funcionalidade não vai “quebrar” outra funcionalidade já pronta (e geralmente testada). Isso facilita, e muito, os testes de integração de software. Créditos: Teguh Jati Prasetyo/Shutterstock. 4.2 Como escrever esses testes unitários Fazendo um paralelo com tópicos anteriores, vimos uma infinidade de linguagens de programação, mas em todas elas sempre utilizamos algo em comum, apesar de não parecer: um framework. Assim como uma linguagem de programação tem um framework para apoiá-la e disponibilizar um API para que os desenvolvedores possam escrever software com aquela linguagem, os testes unitários têm inúmeros frameworks diferentes para que possamos escrever esses testes e fazer com que eles sejam executados. Alguns desses frameworks têm variações para várias linguagens de programação, alguns são exclusivos. A utilização de um framework de testes, assunto que trataremos em detalhes mais adiante, é um ponto-chave para um conceito muito importante e para uma das formas mais seguras de escrita de 11 código atualmente, principalmente para equipes que adotam um modelo ágil de desenvolvimento. TEMA 5 – TDD E PADRÕES ÁGEIS DE DESENVOLVIMENTO A ideia de que “o seguro morreu de velho” é bem aplicada a Test Driven Development (TDD, ou em tradução, desenvolvimento baseado em testes). Esse conceito é muito utilizado em processos ágeis de desenvolvimento como o XP ou SCRUM. Hamill ([S.d.]) também diz: “Os frameworks de teste atingem sua utilidade máxima quando são utilizados para o TDD, apesar de ainda serem úteis quando o TDD não é seguido”. 5.1 Regras básicas para o TDD Hamill ([S.d.]) parafraseia uma analogia da carpintaria que é “meça duas vezes, corte uma” para “teste duas vezes, codifique uma”. Isso é relacionado a três regras básicas para o TDD: 1) escreva um teste para um código novo e veja ele falhar, passo importante que verifica se realmente o teste falha como esperado; 2) escreva um código e faça a coisa mais simples que possivelmente funcione, ou seja, faça com que o teste passe, da forma mais trivial e básica possível, pois nesse ponto beleza e implementação complexa não agregam nenhum valor, por mais que sejam tentadoras; e 3) veja o sucesso do teste, e refatore o código, pois é nesse ponto que, sabendo que o teste passou, o código deve ser refatorado. Refatorar é um conceito da engenharia de software em que ocorre uma transformação do código para uma versão melhor dele mesmo, porém sem que o comportamento seja alterado. Dentro do ciclo de TDD, a refatoração começa com código simples, escrito somente para que o teste passe,para que depois possamos melhorá-lo, removendo coisas desnecessárias e outras imperfeições. 5.2 O ciclo do TDD Em sua obra, Hamill ([S.d.]) reforça a ideia de que código novo deve ser escrito somente se um teste falha. Mudanças são esperadas somente na fase de refatoração, adicionando novas funcionalidades ou depurando código. A repetição contínua do ciclo de três passos do TDD (trocando em miúdos, 12 escrever, fazer funcionar e melhorar) deve fazer parte do nível mais baixo de um processo de desenvolvimento de software. Existem duas formas de classificar essas mudanças de software que são feitas. A primeira é a adição de novas funcionalidades. Utilizando o conceito do TDD, o primeiro passo é escrever um teste que use esse novo código. Possivelmente, ele vai falhar nos resultados na primeira execução, aí devemos criar código, implementar a funcionalidade e verificar o sucesso obtido. Fazer isso nos força a pensar e verificar o que podemos melhorar no que escrevemos, agregando valor ao design do nosso código. Além disso, os testes servirão de exemplo de que o código da funcionalidade funciona e de como deve ser utilizado. Créditos: Vector street/Shutterstock. A segunda categoria citada por Hamill ([S.d.]) é a de que as mudanças de software ocorrem quando estamos depurando o código. Para isso, primeiro é necessário a criação de um teste que falhe por causa do problema encontrado, 13 o bug. Depois disso, ele deve ser corrigido e o teste executado novamente, validando a correção feita. Além do benefício trazido por corrigir o problema, esse processo cria um teste capaz de pegar esse problema, fazendo com que, caso ocorra novamente, o teste irá falhar e a falha vai ser facilmente identificada. 5.3 TDD e garantia da qualidade Se seguirmos o ciclo do TDD literalmente, vamos chegar ao mais próximo possível de um código perfeito, parafraseando o “codifique uma vez” da frase de Hamill ([S.d.]). Esse processo é utilizado como um forte indicador de que a funcionalidade está pronta e funcional, pois se o teste falha, ela não está funcionando, por isso está parcialmente feita. Se pegarmos um processo de desenvolvimento de software, em que existe toda uma garantia da qualidade desse software, os testes são muito importantes para que tal garantia seja acertada. A grande maioria dos softwares implementados em ambientes de DevOps utilizam testes unitários como garantia da qualidade, mas não somente eles. Primeiramente, os testes vão mostrar que os códigos escritos são funcionais e foram validados quando submetidos pelos desenvolvedores. Geralmente eles são utilizados em ambientes automatizados de geração de código, no qual temos um processo chamado esteira de build. Além disso, o sucesso nos testes assegura que as ideias e lógicas escritas pelos desenvolvedores estão funcionando corretamente. A ideia central aqui é a de que um código escrito por um desenvolvedor não afetou o código de outro durante a fase de integração. Uma falha em um teste vai indicar pontualmente qual código e qual alteração afetou aquele teste, facilitando a resolução do problema. Mas, afinal, o teste unitário substitui outros tipos de teste? Em poucas palavras, de forma alguma. É tão comum quanto respirar cenários em que um código escrito utilizando TDD, com testes todos assertivos e um código bem escrito, falhar em validações como performance ou usabilidade. Esses testes devem ser considerados juntamente com aqueles criados pelo TDD, pois são cenários em que muitas vezes um teste unitário é impossível de ser feito. Testes unitários são importantes e correspondem a uma ferramenta de necessidade absurda para todo um processo de qualidade no geral. 14 Créditos: Kachka/Shutterstock. FINALIZANDO Nesta etapa, tivemos uma primeira visão das variáveis que afetam todo o ambiente de desenvolvimento mobile como um todo, como o sistema operacional, desempenho e recursos do aparelho, bem como o motivo por que essas variáveis devem ser conhecidas pelo time de desenvolvimento. Também vimos que considerações como segurança e usabilidade contam, e muito, na hora de escrevermos os cenários de teste dos aplicativos. Também fizemos uma introdução para os testes em aplicativos móveis, falando a respeito dos pontos de atenção que devemos considerar ao testar um aplicativo. O teste de compatibilidade é necessário com vistas a garantir que o aplicativo será executado nos mais diversos tipos de aparelho, mantendo uma constância na sua execução. Observamos o teste de mobilidade ou interoperabilidade, que validam a capacidade do aplicativo de se comunicar com outros aplicativos e/ou plataformas, garantindo que esta é feita dentro dos padrões especificados. O teste de usabilidade vai focar principalmente o uso do aplicativo pelos usuários, sendo de extrema importância para o sucesso dele, fazendo com que o usuário inconscientemente saiba como utilizá-lo. Temos ainda o teste de desempenho, que vai assegurar que o aplicativo execute suas funcionalidades de forma ágil. 15 Ainda falando sobre os tipos de testes, tratamos de dois pontos importantes que são os testes de sincronismo, que vão garantir que o aplicativo possa se comunicar de forma padronizada com outras plataformas, e por último, dos seis tipos de teste, temos o teste funcional, que vai assegurar de forma definitiva que o aplicativo funciona como esperado e desenhado nas fases iniciais do projeto. Abordamos também sobre os testes unitários e seu papel importante em um ciclo de desenvolvimento. Explicamos acerca de unidades de código e vimos que esses testes são os de caixa-branca, pois conhecemos o que está sendo testado e podemos validar como foi construído. Por fim, pudemos explorar um pouco o padrão TDD e como aplicar os testes unitários dentro de um ciclo de desenvolvimento, e principalmente as vantagens de termos os testes escritos antes de começar o desenvolvimento de um software. Mais adiante, começar a ver os frameworks de testes e como funcionam dentro do ambiente de desenvolvimento móvel, passando do teste unitário para o teste dentro do aplicativo. 16 REFERÊNCIAS HAMILL, P. Unit Test Frameworks: an Overview. O’Reilly. [S.d.]. Disponível em: <https://www.oreilly.com/library/view/unit-test- frameworks/0596006896/ch01.html>. Acesso em: 16 ago. 2022. MATOS, T.; PIRES, G. A utilização de testes em aplicativos móveis. Tiago Matos. [S.d.]. Disponível em: <https://blog.tiagomatos.com/a-utilizacao-de- testes-em-aplicativos-moveis/>. Acesso em: 8 ago. 2022. MIRANDA, D. Teste unitário e qualidade de software. Medium.com, 6 jul. 2017.Disponível em: <https://medium.com/assertqualityassurance/teste- unit%C3%A1rio-e-qualidade-de-software-acce7b9c537>. Acesso em: 15 ago. 2022. UNIT Testing. Software Testing Fundamentals. 2022. Disponível em: <https://softwaretestingfundamentals.com/unit-testing/>. Acesso em: 15 ago. 2022. Conversa inicial FINALIZANDO REFERÊNCIAS