Concrete | Papo sobre desenvolvimento iOS e testes unitários
Devs iOS não escrevem testes unitários?
Siga Victor Lima no twitter.
No unit tests? No continuous integration? No TDD?
Recentemente Jonathan Rasmusson, autor do excelente livro Agile Samurai, escreveu o seguinte texto It's Not About the Unit Tests. Ver também o blog dele em It's not about the unit tests
OK, bem polêmico, hein? Causou uma boa discussão no forum da PragPub em Magazine Forum
O desenvolvimento para iOS tem mudado, e na medida do possível estamos tentando acompanhar. Assim resolvi escrever um email para o Jonathan cujo texto está traduzido abaixo:
Li seu artigo e como desenvolvedor iOS, gostaria de compartilhar algumas considerações sobre engenharia de software e qualidade de software.
1) A Apple tenta ajudar… 😉
Quem segue a evolução do Xcode, notou que as últimas edições superaram a falta de suporte a testes. A IDE e a dificuldade de setup do ambiente de testes não servem mais como desculpa para não escrever testes automatizados ou praticar TDD. Mas não podemos esconder uns probleminhas relatados nos links abaixo:
Terminating since there is no workspace
Command Line Tests Fail — Xcode 4.5
https://devforums.apple.com/thread/167012
(precisa estar logado no forum da Apple, processo extremamente burocrático)
Os Frameworks tais como SenTestKit, OCMock and Frank permitem fazer testes automatizados do mesmo jeito que em outras plataformas.
As ferramentas evoluiram para satisfazer os praticantes de XP. Você pode fazer o build via command-line e integrar seu código fonte com o Jenkins ou outro CI.
2) A maioria dos aplicativos na App Store são "one-offs"
Ou seja, não são feitos para evoluir para novas versões. Se sua aplicação é assim, talvez possa ter sido feita a la cowboy. Mas se você tiver que dar manutenção nessa base de código durante muito tempo, inevitavelmente algum tipo de automação e testes será necessária. Pense quando você precisar um dia inserir novas features, terá que se precaver com algum mecanismo que garanta o comportamento, e assim não quebrar nada.
3) Aplicação simples baseada principalmente na interface de usuário e/ou que faz uma tarefa específica
Muitas aplicações têm grande parte da sua lógica na interação entre a View e a View controller, normalmente com uma camada de model muito fina e talvez atendendo a uma ou duas requisições. Isto depende do tipo de aplicação que você está fazendo. Na medida em que as coisas vão se tornando mais complexas, haverá a necessidade de ter os tais mecanismos de proteção providos pelos testes.
4) Continuous Integration ou Delivery.
Uma apresentação deste ano no WWDC foi sobre fazer build pela linha de comando e com demos mostrando como integrar com o Jenkins. Realmente ficou mais fácil.
Eu mesmo venho tentando fazer um Continuous Delivery pipeline para as aplicações que faço. Talvez alguém lendo este post possa contribuir: https://github.com/victorlima/AutoBuild/.
É um projeto simples no qual pretendo agregar algum conhecimento de Continuous delivery que adquiri em alguns projetos que participei. Foram alguns projetos iOS e outros usando android.
5) O argumento da qualidade
Deveras, unit tests != qualidade. Os testes unitários se referem a defeitos no estágio corrente da aplicação sem cuidar da qualidade como um todo da aplicação exposta ao usuário. Há muito mais sobre qualidade e a paixão que o Steve Jobs passou a muitos desenvolvedores faz uma grande diferença quando se compara com as aplicações android.
No todo concordo que o povo tem escrito aplicações bem atrativas sem testes unitários. Eu já escrevi muitas aplicações sem testes.
Mas agora estou me esforçando quanto a isto e consolidando este delivery pipeline na área de desenvolvimento mobile na Concrete, empresa onde trabalho.
Espero saber o que pensa sobre o que escrevi.
Bem, o Jonathan atenciosamente respondeu e compartilho aqui as palavras dele:
A resposta do Jonathan
Obrigado por seus comentários. Eu estava com vontade de ter essa conversa por algum tempo e agradeço por entrar em contato comigo para discutir.
No geral acho que estamos muito alinhados.
Sim, estou ciente que você pode fazer muitas das práticas (teste de unidade, TDD, refatoração, CI). Eu tenho escrito testes unitários, gosto do Frank e tenho CI rodando no Jenkins.
Mas acho que poucas pessoas da comunidade o fazem. E escrever testes de unidade era difícil (em comparação com Java / C # / Ruby).
O framework e as APIs não suportam o que eu estava acostumado a fazer com outras linguagens. E também há a questão da natureza altamente visual das aplicações (significando que não era prático testar fazer testes unitários com a app no modo offline, com conectividade de Internet lenta, etc.).
Eu não desisti (parte por falta de total entendimento de Objective-C) mas fiquei surpreso como o pessoal da comunidade encarou isto como um problema e foi ótimo perceber que a qualidade do trabalho está mudando para melhos.
Descobri que não poderia trabalhar (ou escrever código) da mesma forma que fazia antes. Tive que me ajustar.
1. Foi possível construir aplicações sem testes unitários (embora não recomendado).
2. Havia muito mais considerações para a construção de uma aplicação de qualidade do que testes de unidade (que é onde anteriormente foquei a maior parte do meu tempo e esforço).
Não sosseguei até perceber que precisava ajustar o modo como trabalhava. Ainda estou me ajustando (a jornada não acabou).
Acredito que o desenvolvimento para iOS irá emparelhar com a grande comunidade de desenvolvimento de software. A Microsoft começou devagar com Agile em 2001 mas chegaram com suas ferramentas. Provavelmente acontecerá o mesmo com iOS, embora julgando pelo último WWDC, não parece coisa prioritária.
Há mais discussão acontecendo no forum em: It's Not About the Unit Tests. Then about what?
Suas considerações foram bem-vindas. Tanto melhor que mais pessoas como você escrevam e o resto de nós aprenderá.