Explorando aplicações Android com a Heurística T-PAIN

Uma metodologia feita para direcionar testes à comunicação entre aplicativo e o sistema operacional.

--

Introdução

Quando falamos de programas e aplicações, algumas imagens podem vir na nossa cabeça. Como um app famoso, por exemplo. Ou um programa de computador que usamos a trabalho. Até mesmo um website pode brotar em nossa imaginação. Apesar das similaridades, existem algumas distinções entre eles que são importantes de serem observadas.

Android sendo construído em um tablet e um smartphone.
https://snapstack.cz/wp-content/uploads/2020/07/ToolsForBuildingApps_636x300-op.png

Aplicativos para Android possuem definições robustas devido à serie de limitações de hardware dos dispositivos. Diferente dos programas de PC, que tendem a ficar na memória até que o usuário os encerre, o Android gerencia, constantemente, quais aplicações estão ativas, em que estado elas estão e quais serão removidas da memória. A isso, damos o nome de App Lifecycle.

Da mesma forma que o desenvolvimento destes aplicativos é diferente, precisa-se de uma observação mais detalhada ao testá-los: para ser bem desenvolvido, ele deverá conversar apropriadamente com o sistema.

Concepção da Metodologia

Nos últimos dois anos, trabalhei com desenvolvimento Android e percebi que havia poucas heurísticas que explorassem esse relacionamento entre aplicativo e sistema. Aprendendo mais sobre arquiteturas Android e usando como base o pouco material disponível, consegui mapear alguns aspectos e fundamentar uma técnica que aprimorou meus testes exploratórios.

A técnica foca nos aspectos onde o sistema operacional exerce controle sobre aplicativos, como removê-los da CPU por conta de uma política de escalonamento. Ela pode ser usada em qualquer app nativo desenvolvido para API 23 (Android 6.0) ou superior, ou seja, aplicável em mais de 85% dos dispositivos Android do mundo (statcounter, Mar/21).

A tela de um smartphone Android mostrando ícones de aplicativos.

Ela é composta por 5 características: Rotação, Permissões, Modo Avião, Interrupções e Conexões. Por envolver o sistema operacional, exercitá-la pode ser especialmente eficiente em aplicações que estão em estágios iniciais de desenvolvimento, revelando brechas em sua arquitetura. Abaixo, exemplifico formas de explorá-las:

Ro[T]ação (RoTation)

Preencha informações na tela e rotacione o dispositivo:

  • As informações persistem?
  • Há sobreposição?

Inicie um fluxo e rotacione o dispositivo:

  • O que acontece ao rotacionar no meio de uma requisição a um serviço web?
  • A aplicação se perde ao ser rotacionada?

[P]ermissões (App Permissions)

  • Como o aplicativo se comporta ao não ter todas as permissões?
  • O que acontece se ela perder as permissões durante o uso?
  • As permissões solicitadas fazem sentido?

Modo [A]vião (Airplane Mode)

  • O quão dependente o aplicativo está de conexões com a rede?
  • Como a app se gerencia offline?

[I]nterrupções (Interruptions)

Terceiras (Third-party):

  • Como o aplicativo se comporta quando o sistema escalona outras aplicações por cima da atual?
  • E quando recebe uma chamada?
  • E quando exibe uma notificação de prioridade 0?

Sistêmicas (System-calls):

  • O que acontece quando o Android mata processos em background?
  • Forçar parada com a aplicação em uso faz o quê com os processos?
  • É possível reutilizar a app após removê-la da memória?
  • O que acontece ao remover a cache com a aplicação em uso?

Co[N]exões (CoNnections)

  • Como a app lida com um ping alto?
  • E quando é uma conexão 2G ou 3G?
  • Como o aplicativo reage a timeouts?

Prova de Conceito

Meu amigo e mentor, Júlio de Lima, deu-me a oportunidade de aplicar esta heurística no app da Lojinha — a mesma que ele usa em seu curso “Programa de Testes e Qualidade de Software” — com o objetivo de demonstrar algumas das características e, com sorte, encontrar inconsistências. Vamos à elas:

A tela de criação de item do aplicativo Lojinha sendo rotacionado.

Rotação:

Ao rotacionar uma aplicação, o Android precisa destruir a tela que está sendo mostrada e, então, reconstruí-la na nova posição. Este movimento simples pode revelar inconsistências arquiteturais, como esta ao lado, onde a aplicação não preserva os dados inseridos nos campos de texto.

Aqui, nós temos um problema de UX. Imagine se este fosse um formulário de registro grande. Um movimento e o usuário teria de reescrever todos os seus dados.

Tela de permissões solicitadas pelo aplicativo Lojinha

Permissões:

A partir da API 23 do Android, os aplicativos precisam listar ao que querem ter acesso. Desta forma, usuários passam a ter maior controle sobre estas permissões.

No caso da aplicação da Lojinha, construída inteligentemente de maneira simples, nenhuma permissão foi solicitada, logo, esse aspecto da heurística não pôde ser testado.

Tela mostrando uma tentativa de criação de item em modo avião

Modo Avião:

Ao ligar o modo avião, as peças emissoras de frequência de rádio de médio e longo alcance — wifi, dados móveis, bluetooth — são desativadas. Isso faz com que qualquer conexão wireless seja interrompida.

Em aplicações altamente dependentes destas conexões, isso pode representar um problema: o que a app faz quando não consegue fazer requisições?

Aqui a exceção foi tratada, mas revela um ponto de melhoria: a mensagem de erro possui informações não relevantes ao usuário.

Tela de criação de item sendo interrompida pela notificação de uma mensagem e por uma chamada telefônica

Interrupções:

Com recursos de hardware limitado, o sistema faz manobras para melhorar uso do que está disponível. Para isso, monitora de perto todas as aplicações e processos, delegando e alterando as prioridades sempre que necessário.

Quando um outro processo solicita ao Android permissão para assumir a tela ou sobrepor um aplicativo, temos então uma interrupção, que é quando o Android dá atenção a um outro processo mais prioritário.

Neste caso, temos duas interrupções:

  1. Ao receber a notificação;
  2. Ao receber a ligação.

Ao ter sua prioridade alterada, aplicações mal configuradas tendem a se perder no ciclo de vida, o que pode levar a um crash.

A app da Lojinha respondeu muito bem às interrupções.

Tela mostrando a tentativa de criação de um item enquanto conectado ao 2G

Conexões:

Uma das principais características dos smartphones é conseguir conectar-se a diferentes tecnologias de rede — do 2G ao 5G, do 2.4 GHz ao 5 GHz. Logo, as aplicações também precisam ser capazes de se adaptarem a estes cenários.

Lembre-se: quanto mais difundida for a sua aplicação, a mais variações ela será exposta… e nem todo usuário tem acesso a uma estável conexão WiFi.

Com base nisso, o último aspecto desta heurística verifica como a aplicação se comunica com o sistema e com a rede em conexões lentas e/ou instáveis.

A Lojinha demonstrou lentidão com a requisição da lista de itens, mas não travou em nenhum momento, conseguindo registrar um novo item mesmo numa conexão 2G.

Conclusão

Essa heurística foi desenvolvida com o acúmulo de experiências que tive testando e desenvolvendo (um pouquinho) apps Android. Modifique-a ao seu bel prazer, adapte-a à sua necessidade e revitalize-a para encaixar aplicativos iOS também. Ela está em desenvolvimento e, assim como você e eu, irá se aprimorar ainda mais.

Se você identificou a referência no nome da heurística, guardei um espaço especial pra você em meu coração. Dica: procure este nome no Google.

Àqueles que decidirem experimentar a heurística, por favor, peço que respondam ao meu formulário de pesquisa clicando aqui. Ele é bem curto e irá me ajudar a entender sobre a sua percepção e o que encontrou durante seus testes.

Caso queira conhecer mais sobre heurísticas de teste, fortemente aconselho o artigo de Gabriel Santos, “Heurísticas de teste de software”.

Meus mais sinceros agradecimentos a Júlio de Lima, responsável por abrir minha mente e desenterrar meu potencial, a Jefferson Rodrigues, meu mentor em desenvolvimento Android e esplêndido profissional, aos meus talentosos e inteligentíssimos irmãos Wesley Oliveira e Tiago Pereira, sempre me fornecendo insights e colando comigo em minhas jornadas, e Tarsila Santana, minha piveta, pela revisão extremamente habilidosa. Tamo junto!

--

--