Tecnologia

Automatizando processos do seu projeto iOS com Integração Contínua

Por: , junho 12, 2018

Você em algum momento já leu em algum lugar ou ouviu falar sobre Continuous Integration? CI? Integração contínua?

Ótimo, se você nunca ouviu falar, ou se você já ouviu e não sabe muito bem o que é, muito menos para o que serve, tenho uma dica para você! Leia esse artigo até o final, tenho certeza que você vai ficar muito impressionado com o que é possível fazer com essa prática de desenvolvimento de software incrível.

Nesse artigo, farei uma breve e resumida apresentação sobre o que é integração contínua, para que serve, como funcionam, vantagens de se utilizar, exemplos e dicas de algumas experiências (boas e ruins) que tive ao utilizar alguns sistemas de CI.

O que é CI?

Continuous Integration nada mais é do que uma prática de software na qual se tem a finalidade de resolver problemas de integração dentro de uma equipe de desenvolvimento de software, no caso desse artigo da nossa equipe de engenheiros iOS. Não somente com problemas de integrações de ferramentas propriamente ditas, mas também de problemas com a saúde de um projeto em desenvolvimento, onde existem várias pessoas, sendo elas, o estagiário, o desenvolvedor júnior que começou essa semana e está inseguro de realizar um commit e quebrar os testes e os demais que já são antigos no projeto e querem delegar a todos a responsabilidade de realizar um deploy do projeto.

Os sistemas de integração contínua, alguns deles podem ser configurados em uma máquina comum, ou servidores remotos e outros o próprio sistema já oferece uma máquina para ser configurada, e a mesma ficará olhando diretamente para nosso repositório remoto do sistema de versionamento (Git) onde está o nosso projeto, e tem a responsabilidade de executar um conjunto scripts (steps) que são delegados por nós engenheiros, de forma remota e automatizada.

Para que serve CI?

Como citado anteriormente, a prática tem como finalidade resolver problemas de integrações de uma equipe de desenvolvimento, automatizar processos e trazer inúmeras integrações com diversas ferramentas existentes no mercado atual. Calma que já vou explicar e dar exemplos!

Quando falamos sobre integração continua, acabamos abordando também o tema sobre entrega contínua, que diz… “A partir do momento em que eu realizei um commit de um pacote para o meu aplicativo, e ele passar por todos os passos que foram definidos no sistema de CI, por exemplo, validação da build, validação dos testes unitários, for verificado a cobertura de testes, for realizado a validação de uma ferramenta de Lint e auto correct. Dessa forma eu garanto que meu pacote está pronto para ser enviado para produção”. Com os sistemas de integração contínua é possível também automatizarmos os processos de liberação de uma versão beta do nosso aplicativo para a equipe de testes dentro da empresa, ou até mesmo fazer uma distribuição de uma nova versão do aplicativo para a App Store, sem que seja necessário fazer nenhum processo de forma manual e que você se sinta seguro de fazer essa distribuição.

Como funciona CI?

Em um sistema de CI, você desenvolvedor irá definir um conjunto de passos/processos que serão executados de forma automatizada e remota. Você também fará a configuração de quando esses workflows devem ser executados, ao realizar um push na master, por exemplo.

Já que tocamos nesse assunto, podemos fazer a configuração de realizar uma trigger (gatilho) de um determinado workflow quando realizarmos ações no repositório, como por exemplo, dar um push em determinada ou todas as branches, abrir um pull request de determinada ou todas para determinada ou todas as branches, ou até mesmo quando criarmos uma tag no nosso repositório.

Já podemos imaginar alguns processos bem definidos pensando nesses cenários e casos. Onde conseguiríamos definir padrões podendo criar planos de releases para o nosso aplicativo!

Acredito que a melhor forma de tentarm os entender e nos familiarizar com o assunto, é dando alguns exemplos!

Então vamos nessa…

Tudo começa quando falamos do casal perfeito, CI & Fastlane. Então nesse exemplo, irei configurar a ferramenta de automatização Fastlane, para conseguirmos usufruir ainda mais de possíveis automatizações que conseguimos fazer da integração dessa ferramenta com um sistema de integração contínua.

Escolhi o sistema de CI Circle CI para fazermos a configuração de um novo projeto iOS, e também mostrar como fazemos automatizações de alguns processos comuns e rotineiros da nossa equipe de engenheiros.

  1. Vamos criar um repositório para nosso projeto. O link do projeto que vamos utilizar nesse artigo é esse AQUI.
  2. Agora vamos criar um projeto iOS

3.Crie o projeto com Testes unitários e Testes de UI para validarmos no CI

4. No exemplo, criei um método na nossa view controller para que possamos escrever um teste unitário

Foi escrito um método que recebe dois valores do tipo Double e retorna esses dois valores somados.

5. Vamos escrever alguns testes unitários

Foram escritos dois testes unitários simples que chamam o método criado em nossa View Controller e verifica os valores. 

No primeiro teste “testValidSumWithValidResult” somamos dois valores e esperamos que ele nos retorne o valor correto, nesse caso foram somados os valores 4 e 4, e esperamos que ele retorne o valor final da soma que seria 8. 

Já no segundo teste “testValidSumWithInvalidResult” somamos dois valores e esperamos que ele nos retorne o valor incorreto, nesse caso foram somados os valores 2 e 7, e esperamos que ele retorne o valor final da soma que seria 9.0. Porém no XCTAssert, repare que a condição é “NotEqual”.

Podemos verificar também que os testes já foram executados e estão válidos!

6. Também adicionei um componente na tela, para que possamos realizar um teste de tela

Foram adicionados uma label “Continuous Integration” e um button “Automating Everything” os dois não possuem IBOutlets nem IBActions, só são componentes fixos na nossa View da nossa View Controller.

7. Vamos escrever alguns testes de tela

Foi escrito um teste de tela, onde verificamos se os componentes que adicionamos em nossa View, se eles existem.

Podemos verificar também que os testes já foram executados e estão válidos!

8. Compartilhando o Scheme do projeto

Clique no scheme do seu projeto ao lado do botão pausar build no xCode e clique em Manage Schemes, após isso, habilite a opção Shared do scheme que você irá rodar no sistema de CI. Isso deve ser feito para que o Fastlane consiga enxergar o scheme do seu projeto.

9. Agora vamos configurar o Fastlane no projeto

Após rodarmos o comando “fastlane init” na pasta raiz do nosso projeto. Inicializamos o Fastlane no nosso projeto e selecionamos a opção (4) de criarmos nossas lanes manualmente.

10. Vamos criar uma lane que rode nossa build, testes unitários e testes de tela

Foi criado uma lane “run_build_tests” que irá executar o Scan do Fastlane. A lane irá validar nossa builds, testes unitários e testes de tela, antes de executar a validação ele irá dar um clean no projeto e obter o code coverage quando terminar de rodar os testes. É possível fazer configurações no Scan, como pular a etapa de validar build, rodar build e testes em um device ou sistema operacional específico, clean no projeto, etc.

11. Vamos configurar nosso repositório no nosso sistema de CI

Primeiramente, entre no site do Circle CI: https://circleci.com/.

Clique em Singn Up.

No exemplo, foi realizado o login com GitHub.

É necessário autorizar que o Circle CI tenha acesso ao seu cadastro do seu repositório, nesse caso no GitHub.

A partir desse momento, já temos nosso cadastro dentro da plataforma do Circle CI. Agora já podemos adicionar nosso primeiro projeto.

Como você já deu o acesso da sua conta do GitHub, o sistema irá reconhecer os repositórios criados dentro do GitHub, então encontre e selecione o seu projeto.

Selecione as configurações da máquina que irá rodar o seu projeto, nesse caso MacOs, e a linguagem utilizada em seu projeto, nesse exemplo, estamos utilizando Swift 4.

Nesse momento, já temos a configuração do nosso projeto dentro do nosso sistema de CI, e já temos nosso arquito .yml que contém as configurações manuais do projeto criado. Por padrão, o CircleCI cria um primeiro workflow, onde ele realiza a instalação do Cocoapods e roda a ferramenta Scan do Fastlane, essas configurações nós iremos alterar no próximo passo.

12. Vamos configurar nosso workflow

Nas configurações do workflow, é possível fazer toda configuração de ambiente, como configurar scripts que devem ser executados antes ou depois de rodar builds, testes, comandos que devem ser executados, no caso desse exemplo, rodar nossa lane que escrevemos acima, possível fazer configurações de notificações, chaves SSH, integrações, etc.

Foi configurado um script para executar a instalação do bundler em “Pre-dependency” que será executado antes do nosso script de validações.

Para o comando de validação de nossa build e testes, foi configurado a lane que escrevemos acima, como estamos utilizando o bundler, para garantir as versões das nossas dependências, utilizamos o comando “bundle exec” para executar o Fastlane.

É possível configurar integrações com ferramentas de chats, para que possamos sempre receber o report e logs das nossas builds que serão executadas e validadas em nosso sistema de CI.

13. Pronto! Nosso projeto já está rodando no nosso sistema de CI!

Todos os steps que foram configurados serão executados assim que o seu repositório receber uma atualização de uma nova versão do seu projeto.

É possível verificar que foi executado o comando para instalação do Bundler que configuramos nas pré dependências acima.

O nosso workflow irá executar a nossa lane para realizar a validação da nossa build, testes unitários e testes de tela. Após toda a verificação, dando sucesso ou falha, é possível fazermos a configuração para termos esse report e os logs via e-mail, slack, etc.

Pronto! Automatizamos um processo que normalmente realizamos em nossas máquinas a todo momento em nossa rotina de trabalho.

O que eu ganhei? O que eu automatizei?

Pff’ nada! Ou…

Quando seu time de engenheiros iOS utiliza um sistema de CI, é fácil identificarmos alguns ótimos benefícios que sua equipe usufrui…

Se vocês utilizam Fastlane… Ou… Se vocês utilizam Fastlane com Bundler… Perfeito! Vocês automatizaram tudo então! Mas vou listar alguns processos que automatizamos, para você não achar que estou contando história…

  • Todos da equipe possuem confiança e se garantem do que foi entregue para produção.
  • Frases como “na minha máquina funciona” será extinto do seu time, pois ao utilizarmos um sistema de CI, vícios de ambientes são descartados em um primeiro momento, é de extrema importância fazer uma configuração de ponta de todas as dependências e ferramentas que seu projeto utiliza!
  • Independente da última pessoa que realizou um push, quando você baixar as alterações daquela pessoa, sua build e seus testes estão validados e passando!
  • Em um projeto open source, não é necessário verificar se um pull request está seguindo padrões do seu projeto, ou ter que rodar a build e os testes em sua máquina local…
  • Não é necessário parar o seu trabalho parar rodar build e testes.
  • Caso alguém faça alguma gambiarra no código, não foi necessário seu aplicativo ganhar um crash para verificar que o problema existe.
  • Você economizou horas (quem já trabalhou em um projeto que toda a distribuição beta e prod é realizada de forma manual, sabe o que eu to falando) ao ter que realizar um novo release do aplicativo.
  • Sua equipe de QA’s consegue escrever testes instrumentados e automatizados com mais confiança, e não precisam parar um engenheiro, caso o código dele não segue algum padrão do seu código.
  • É possível fazer uma configuração de feedbacks bem completos, de como seu projeto está e o que está acontecendo com ele na máquina ou servidor que está configurado o CI, através de e-mails, mensagens no slack, etc.

Sistemas de CI

Existem no mercado hoje, várias soluções de sistemas de integração contínua, porém vou abordar e citar nesse artigo alguns, no qual já tive a experiência de conhecer e utilizar em diferentes cenários e projetos:

Quando olhamos para diferentes soluções, é normal surgir a dúvida: “qual dos sistemas apresentados é o melhor?”. Tenho uma má notícia, não existe o melhor… Ou melhor, vou tentar melhorar minha explicação. Existe o melhor para o cenário do seu projeto, como ele é feito, qual a necessidade para o seu projeto, quais ferramentas e tecnologia o seu projeto utiliza, e quais as integrações que seu projeto e sua equipe necessita.

Pois, das soluções apresentadas acima, todas são soluções desenvolvidas para aplicações mobile, porém, cada uma apresenta suas peculiaridades, especialidades, Alguns oferecem planos atrativos (uns gratuitos, outros não), mas vale se questionar de todas essas variáveis antes de escolher qual o sistema de CI você vai utilizar para o projeto em que você atua!

Lembre-se, nem tudo são flores

Como tudo na vida, infelizmente nem tudo são flores, onde você vai conseguir automatizar tudo quanto é processo dentro de qualquer projeto. Lembre-se que, para um código mal escrito, qualquer melhoria se torna algo totalmente custoso!

Vale pensar também: qual é a sua finalidade em utilizar qualquer sistema de integração continua? Vou te ajudar a pensar um pouco.

  • Se você trabalha em um projeto sozinho (no qual é um cenário bem comum, em grandes empresas e startups), e você quer resolver problemas de integração para validação de builds e testes. Talvez não faça muito sentido, pensando que esse problema normalmente é encontrado em uma equipe de desenvolvimento.
  • É estranhamente comum clientes não entenderem algum ganho ao implantar um sistema de CI, entendendo que é exigido um trabalho para configurar um ambiente decente, definir processos, criar workflows e delegar pessoas para dar manutenção nisso.
  • É importante que o prática do GitFlow esteja bem definida dentro do seu time… Caso contrário, será bem difícil estruturar seus Workflows e quando eles serão executados.
  • Em um projeto muito grande, pode acontecer que essa validação de todos os steps em um sistema de CI seja algo muito demorado.
  • Caso você trabalhe em um projeto totalmente legado, onde não existe nenhum tipo de padrão, nenhum teste unitário escrito para o projeto, você não consegue nem configurar o Fastlane no projeto, por ser totalmente inviável. Você não conseguiria aproveitar nada do que um sistema de integração contínua tem a oferecer.
  • A partir do momento que pensamos, que processos estarão rodando de forma remota, devemos pensar sobre como estruturaremos determinados processos para verificação de algum problema que acontecer em um dos passos definidos em um workflow. Por exemplo, caso na máquina aconteça algum problema no emulador do xCode, não teremos de forma clara o porque nossos testes de tela não foram executados, desde que na nossa máquina local está rodando perfeitamente. Então, pode ser que esses tipos de problemas tomem bastante tempo, até descobrirmos o que de fato pode estar acontecendo.

#FicaDica

  • Tenha uma prática de GitFlow decente no seu time, para se tornar mais ágil e menos custoso a definição de processos dentro do sistema de integração contínua.
  • Configure e utilize Fastlane para automatizar processos como, configuração de certificados no projeto, distribuição de versões beta e produção do aplicativo, validação da builds e testes, instalação de dependências, configurações de ambientes, etc.
  • Utilize Bundler com Fastlane, para você garantir que o sistema de CI e toda sua equipe de engenheiros iOS estão utilizando as mesmas versões das dependências do seu projeto.
  • Configure e utilize Swift Lint, para definir padrões, regras e validações, para aumentar a qualidade de todo código do projeto.
  • Invista em workflows com bastante validações e integrações!
  • Usufrua ao máximo das integrações que seu sistema de CI oferece!
  • Utilize um sistema de CI que atenda sua necessidades, pois lembre-se: Não existe o melhor sistema de integração contínua! Mas sim, existe o melhor sistema de integração contínua para o seu contexto e para o seu projeto em específico!

Vou parando por aqui, espero que agora que você tem pelo menos uma idéia do que é integração contínua, para que ela serve e como ela funciona, que você consiga usufruir muito dessas automatizações e integrações!

Caso queira saber mais, nesse link AQUI, você pode assistir a apresentação de uma palestra muito bacana sobre integração contínua em projetos iOS.

Se você quiser dar um feedback desse artigo, tirar dúvidas ou discutir mais sobre o tema, me procure no slack iOS Dev Br, Bruno Ramos ou ‘bruno-hcr’.

  • Receba nosso conteúdo em primeira mão.