09 Jan, 2009 20:54

Testes no iPhone

Não vou me alongar sobre os benefícios do TDD (Test Driven Development), pois acho que há muita referência na internet e quem já experimentou sabe de como esse método contribui para um código limpo, bem organizado e com maior resistência a falhas.

Vamos direto ao assunto, então.

Ruby to the rescue

Logo na minha primeira busca, fiquei muito feliz de descobrir que um dos mestres do mundo digital o Dr. Nic já havia tido a bondade de contribuir com um projeto que permite escrever testes em Ruby para suas classes ObjectiveC. Não perdi tempo e comecei a fuçar a novidade.

Utilizei o framework por algum tempo, contudo comecei a querer fazer alguns testes mais complexos e incluir alguns frameworks novos - p. ex. ActiveRecord para iPhone que já comentamos. E, por causa dessa necessidade, os testes passaram a não funcionar como eu gostaria. Gastei um bom tempo tentando editar o próprio framework de teste para me atender, mas foi em vão.

Resumindo, os testes em Ruby são excelentes para o aprendizado, para realizar testes simples sobre classes NSObject, mas começam a complicar a medida que você testa coisas mais complexas.

Ok, voltando ao Objective C

Desmotivado, sem vontade de cantar uma bela canção, resolvi buscar alternativas dentro do mundo ObjectiveC e encontrei o framework de testes do GTM - Google Toolbox for Mac. Com esse framework consegui testar tudo que precisava e pude continuar a tocar o projeto com os queridos testes.

Para usar o GTM no seu projeto faça o seguinte:

  1. Baixe o GTM e extraia para uma pasta qualquer ;
  2. No seu projeto no XCode, crie um novo iPhone Target (Cocoa Touch Application) via Project > New Target... e nomeie como algo como Testes Unitarios ;
  3. Modifique o Active Target para o novo target;
    selecionando o target
  4. Crie um novo grupo GTM na raiz do seu projeto;
  5. Adicione os seguintes arquivos ao grupo (garantindo que estejam associados somente ao target de testes):
    • google-toolbox-for-mac/UnitTesting/GTMIPhoneUnitTestMain.m
    • google-toolbox-for-mac/UnitTesting/GTMIPhoneUnitTestDelegate.m
    • google-toolbox-for-mac/UnitTesting/GTMIPhoneUnitTestDelegate.h
    • google-toolbox-for-mac/UnitTesting/GTMSenTestCase.m
    • google-toolbox-for-mac/UnitTesting/GTMSenTestCase.h
    • google-toolbox-for-mac/GTMDefines.h

    adicionando gtm ao target
  6. adicione uma build phase ao seu target do tipo run script atraves do menu Project > New Build Phase > New Run Script Build Phase. Arraste para o fim das atividades do seu target se for necessário;
    criando build phase
  7. Duplo-clique nessa nova build phase para editar. Defina o shell como "/bin/sh" e o script como "CAMINHO_GTM_NA_SUA_MAQUINA/UnitTesting/RunIPhoneUnitTest.sh";
    editando build phase
  8. Execute o Build - não Build and Go. Abra o Build Results (command+shift+B) para ver o resultado dos testes.
    build com sucesso

Escrevendo os testes

Para organizar, crie uma pasta para seus testes (ex. Testes :P) e adicione ao projeto. Cada classe do projeto que você quiser testar, basta adicionar seu arquivo .m* ao target de teste (ele passará a estar associado aos dois targets) e criar uma classe de teste correspondente, convencionada como *NomeDaClasseTestadaTest.m - embora este formato não seja obrigatório.

classe do projeto no target de teste

Uma sugestão para facilitar a manipulação dos testes, é manter a @interface e @implementation no mesmo arquivo .m, ou seja, dispensando o arquivo .h das classes de teste.

classe de teste

Todos os métodos que serão executados como teste, devem iniciar por test e não precisam ser declarados na interface. O método setUp pode ser sobrescrito e será executado sempre antes de cada método de teste. O mesmo ocorrerá com o método tearDown no final de cada teste.

Quando escrever o teste, você poderá utilizar os asserts que o GTM lhe provê: todos estão definidos começando com STAssert... e se encontram no GTMSenTestCase.h. A qualquer momento, rode o Build e verifique os erros. Note que cada erro sempre aparece duplicado.

build failed

Considerações

Se estiver usando controle de versão, talvez seja interessante que os arquivos do GTM estejam dentro da pasta do seu projeto. Não há a necessidade de copiar a pasta inteira, somente os arquivos que citei acima, preservando a estrutura de diretórios.

Existem outros recursos que precisei desenvolver ou obter para atender minhas necessidades como uma imitação de test fixtures para controlar meu banco de testes e uma biblioteca de mock para abstrair algumas dependências a classes mais complexas. Pretendo abordar o uso destes em futuros posts.

Se o simulador do iPhone estiver aberto durante os testes, dá um erro esquisitão. Verifique sempre que ele esteja fechado.

Bom Desenvolvimento Orientado a Testes para todos e até a próxima!

Ao navegar neste site, você consente o uso de cookies nossos e de terceiros, que coletam informações anônimas e são essenciais para melhorar sua experiência em nosso site.