
foto de Unsplash para "pipeline"
Abordagem geral
Oi Estou iniciando uma série de postagens em pipelines em desenvolvimento e não apenas isso que ajudam a verificar a qualidade dos aplicativos móveis que estão sendo desenvolvidos. A idéia principal é destacar todas as abordagens ao desenvolvimento móvel que são relevantes agora: desenvolvimento nativo para Android e iOS, React Native, Xamarin e Flutter. Vou começar com o Android, mas primeiro gostaria de dar uma idéia geral do que se trata.
Lembre-se de que esta é uma visão geral geral das ferramentas e práticas que podem ser úteis durante o desenvolvimento de aplicativos Android, e não um tutorial sobre como configurar essas ferramentas.
Para que serve tudo isso?
Vamos começar com a conhecida verdade: quanto mais tarde você encontrar um defeito no aplicativo, mais caro será corrigi-lo. Suponha que você tenha descoberto um bug já em produção. Seus testadores precisam reproduzir esse bug localmente, registrá-lo, priorizá-lo, transmiti-lo aos desenvolvedores e, por sua vez, precisam corrigi-lo, fazer um novo assembly, transferi-lo de volta para os testadores, para que eles estejam convencidos de que tudo está consertado e faça a versão compilar, e somente então envie a nova versão aos usuários.

Muitas horas de trabalho poderiam ser salvas se você tivesse mecanismos para impedir o aparecimento de erros desde o início. Não estou dizendo que há uma bala de prata que elimina todos os erros - isso é impossível. Mas é possível erguer barreiras (também conhecidas como portões de qualidade) que aumentam a probabilidade de detectar bugs no seu código o mais cedo possível.

No computador do desenvolvedor
Como desenvolvedor, você sempre trabalha em sua máquina com um IDE e ferramentas de linha de comando. Vamos ver o que existe para desenvolvedores do Android.
Android Studio
Agora, essa é a opção padrão para o desenvolvedor do Android e, como é baseada na plataforma IntelliJ, há muitas inspeções para Java, Kotlin e XML. Aconselho que você concorde em uma equipe sobre as regras específicas que deseja usar, configure-as em um computador e faça o upload do arquivo settings.jar com essas regras para o sistema de controle de versão ou algum tipo de ferramenta de trabalho colaborativo (como o Confluence).

Configurações de inspeção no Android Studio
O AS também possui correções rápidas que podem ser aplicadas ao seu código pressionando Alt + Enter.

Exemplo de correção rápida do Android Studio
Android Lint
Esta é uma ferramenta de análise estática especificamente para o desenvolvimento do Android, pronta para uso com centenas de regras, qualquer uma das quais você pode usar. O Lint também pode ser iniciado a partir da tarefa Gradle (tarefa), fornecer avisos diretamente no Android Studio e gerar um relatório. Possui muitas verificações, divididas em categorias - segurança, internacionalização, usabilidade, desempenho ...
Mas a capacidade de adicionar suas próprias regras o torna especialmente poderoso. Por exemplo, a sala possui seu próprio conjunto de regras, a biblioteca de log de madeira tem a sua. Você pode criar regras para sua equipe ou projeto e garantir que ninguém cometa erros típicos. (A propósito, em breve na conferência Mobius, haverá um relatório sobre isso, explicando tanto o lado teórico quanto o prático).

Exemplo de relatório do Android Lint
Análise mais estática
Obviamente, existem muitas ferramentas de análise estática projetadas não especificamente para Android, mas em geral para Java e Kotlin : PMD , FindBugs (abandonado, use SpotBugs ), Checkstyle , Ktlink , Detekt e outros. Escolha do seu agrado, integre-o ao seu pipeline e garanta seu uso real (como exatamente? Continue lendo).

Exemplo de relatório de FindBugs
Mas não basta ter uma ferramenta que forneça dados sobre o que precisa ser corrigido. Você também encontrará as seguintes informações úteis:
- Como a cobertura do código com os testes muda com o tempo?
- Quanto tempo levarei para corrigir todos os problemas encontrados?
- Quanto código duplicado existe no projeto?
- Como estender minhas regras para várias equipes?
E muitos outros. Na EPAM Systems, focamos na qualidade, por isso escolhemos o SonarQube como uma ferramenta para responder a essas perguntas. Para outros benefícios do SonarQube, clique aqui .
Teste de unidade
Espero que você não precise garantir novamente que seu maldito código precisa de testes de unidade por vários motivos . Não importa se você segue o TDD, segue o princípio da pirâmide de teste ou a nova ideia do cogumelo de teste . Não é tão importante que nível de cobertura você define como sua meta; em qualquer caso, seus testes de unidade são um componente necessário. Então, você precisa escrever e executá-los! Felizmente, ao longo de 11 anos de evolução, conseguimos um mecanismo bastante conveniente para executar testes no plug-in Gradle e Android Gradle.
No projeto Android, o projeto padrão tem uma tarefa testDebugUnitTest (para você, é claro, pode ser diferente dependendo dos sabores), e é ela quem executa os testes. Certifique-se de usá-lo e a cobertura do código está aumentando com o tempo. A vantagem dos testes de unidade Java é que eles funcionam na estação de trabalho JVM, e não no Dalvik / ART, o que oferece uma vantagem na velocidade.
No caso de testes de unidade do Android, há um problema fundamental: dependência do SDK do Android. Essa é uma das razões pelas quais todas essas abordagens da camada de interface do usuário apareceram como MVP, MVVM, MVI e outras MV *. O problema específico, dependendo da classe no Android, é que os testes de unidade simplesmente caem devido ao uso de stubs deste próprio Android, o que simplesmente gera uma exceção. Obviamente, existem algumas opções: pular testes para esta classe ou extrair parte da lógica para outras classes, ou criar interfaces para classes dependentes do Android para testar alguma lógica de alto nível ou usar Robolectric (que está longe de ser ideal). Outra opção é usar testes instrumentados, que podem ser adequados para verificar o comportamento de uma atividade, mas a tendência atual é que a atividade não deve conter testes.
Para a questão da cobertura: você quer saber o que é no seu momento e como isso muda ao longo do tempo, para que você também precise de uma ferramenta para isso. Até onde eu sei, o jacoco é um padrão do setor para Java e tem suporte para Kotlin.
Testes Instrumentados
Esses testes são executados no emulador do Android, o que lhes permite usar o Android Framework. Infelizmente, eles são lentos e instáveis (devido a alguns problemas com o emulador); portanto, a maioria dos desenvolvedores conhecidos por mim tenta evitá-los. Mas o suporte deles está no Gradle e no Android Studio; portanto, para você, eles podem ser adequados.
Auditoria de segurança
Além de erros simples, erros de digitação, problemas com copiar e colar e similares, também há uma grande categoria de problemas que você deve prestar atenção: segurança. Obviamente, o Android Lint já fornece algumas dicas relevantes, mas é melhor cuidar de ferramentas especializadas especificamente para esta tarefa. Essas ferramentas podem funcionar nos modos estático e dinâmico; dependendo dos seus requisitos de segurança, convém usar um desses modos ou ambos. Você pode começar, por exemplo, com o Mobile Security Framework e, posteriormente, considerar as opções pagas.
Felizmente, há uma lista de ferramentas de análise estática compiladas diretamente pelo OWASP. Por exemplo, você pode escolher Localizar erros de segurança ou usar o Projeto OWASP SonarCube .
Verificar verificações
Como eu disse, quanto menor o ciclo de feedback, menos tempo e dinheiro você gasta na correção de bugs. Então, quero ter certeza de que o código corresponde à qualidade da produção antes mesmo de chegar ao repositório ou mesmo se comunicar localmente. Obviamente, você pode simplesmente pedir que seus desenvolvedores realizem verificações, mas há uma opção muito melhor: Git hooks.
Sugiro adicionar um gancho de pré-confirmação para todas as verificações que discutimos acima: Lint, análise estática de código e testes de unidade. Um exemplo do processo de instalação pode ser encontrado aqui .
Pipeline de CI / CD
É muito difícil imaginar um projeto Android sem um pipeline de CI / CD. Seu objetivo é repetir todas as verificações acima na fase de montagem. Existem várias razões para isso:
- Os ganchos Git podem ser facilmente contornados com a opção --no-confirm
- O código pode passar com êxito por todas as verificações localmente, mas apresenta problemas após a mesclagem
- Necessita de relatórios de teste e cobertura

Exemplo de relatório em bitrise.io
Felizmente, basta mencionar essas verificações de segurança diretamente no script de construção Gradle ou invocar as tarefas correspondentes no seu pipeline de CI / CD. Se você tiver dificuldades para criar um pipeline, fiz recentemente uma apresentação na conferência DevOops sobre DevOps para dispositivos móveis em 2019.
Faça também o seguinte:
- Execute todas as verificações para solicitações pull. Não permita mesclar qualquer solicitação que viole alguma das regras. Isso é muito importante: se a regra não for executada, na verdade ela não existe.
- Execute todas as verificações durante a montagem e implantação. Você não deseja diminuir sua barra de qualidade.
- Se a construção for interrompida, esta é a primeira prioridade. A equipe deve corrigir o problema imediatamente, porque viola sua prática de entrega contínua e impede que a equipe escreva um código de qualidade.
E boa sorte para melhorar seu código!
Se você gostou deste artigo, siga-me no Twitter para não perder o seguinte. E se você estiver em Moscou em dezembro ou puder vir, venha à nossa conferência Mobius e descubra muitas outras coisas sobre desenvolvimento para Android (e iOS)!
PS Agradecimentos ao vixentael por abordar questões de segurança, a Alexei Nikitin pelas revisões e comentários, a Alexander Bakanov pela revisão.