02 Mar, 2010 11:30

Testes no iPhone - Usando o framework padrão do Xcode

Pesquisando na internet, decidimos implementar um projeto utilizando o framework padrão. Este post visa mostrar como configurar seu projeto para iPhone usando o framework nativo e compará-lo com o GTM. Por enquanto, estamos lidando apenas com teste unitários. Em um post futuro comentamos sobre Mock e como adicioná-lo ao seu projeto.

Configuração

Uma vez criado o projeto, você deve criar um novo target para o projeto. Clique com o botão direito em Target > Add > New Target....

Adicionando novo target

Como template, escolha Unit Test Bundle. Escolha um nome para o target (sugestão: Testes Unitarios) e clique em Finish.

Agora, arraste o target original para dentro do target de teste, para criar dependência (forçar o aplicativo a dar build no projeto antes de executar os testes). Após fazer isso, o target deve ficar assim:

Targets aninhados

Pronto! Com isso você já tem o suficiente para rodar seus testes. Mas pode ser que você queira algo a mais, então vamos ao próximo passo que pode ser muito útil nos seus testes.

Debug

Esta foi a parte mais complicada de fazer funcionar. Depois de muitas indas e vindas em diversos sites, conseguimos configurar o debug (funcionando com breakpoint). Assim você pode correr passo-a-passo as linhas de código dos seus testes caso precise. Vale ressaltar que o debug não funciona caso tenha ocorrido erro de compilação, mas funciona perfeitamente em caso de falhas ocorridas nos testes.

Mas vamos ao que interessa: primeiro, crie um executável para o projeto (Project > New Custom Executable...).

Criando executável

Na janela que se abre, escolha o nome do executável. Ele deverá executar o otest, um programa de termnal que serve para depurar o código das classes em Objective-C. Ele deve ser específico para o SDK do iPhone que você utiliza no projeto. Para saber onde ele está e qual versão você deve utilizar, vá no terminal e digite:

find /Developer -name otest

Eu obtive os seguintes resultados:

/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/Developer/usr/bin/otest
/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.1.2.sdk/Developer/usr/bin/otest
/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.1.sdk/Developer/usr/bin/otest
/Developer/Tools/otest

Que fique bem claro que o último não serve para projetos em iPhone. No nosso caso, usamos o segundo (3.1.2). Clique em Finish. Agora precisamos configurar os argumentos do executável na janela que aparece. A imagem abaixo mostra como eles devem ser configurados:

Parâmetros do executável

Na seção dos argumentos, você deve obedecer a ordem em que eles estão escritos. O segundo argumento deve ser o nome do produto gerado pelo target de testes que você utiliza (veja no grupo Products). Na seção de variáveis, utilize os seguintes valores:

Variável Valor
DYLD_LIBRARY_PATH ${BUILD_PRODUCTS_DIR}:${DYLD_LIBRARY_PATH}
DYLD_FRAMEWORK_PATH "${BUILD_PRODUCTS_DIR}:${DEVELOPER_LIBRARY_DIR}/Frameworks:
${DYLD_FRAMEWORK_PATH}"
DYLD_NEW_LOCAL_SHARED_REGIONS YES
CFFIXED_USER_HOME "${HOME}/Library/Application Support/iPhone Simulator/User"
IPHONE_SIMULATOR_ROOT $SDKROOT
DYLD_NO_FIX_PREBINDING YES
DYLD_ROOT_PATH /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/
iPhoneSimulator3.1.2.sdk

Cuidado com a última variável: ela deve ser a mesma versão do SDK utilizado com o otest. Feito isso, você já possui a configuração necessária para "debugar" seus testes. Tudo que você precisa fazer é configurar o executável como o padrão (Project > Set Active Executable). Marque os breakpoints que achar necessário e execute com "Build and Debug".

Comparações

Com o framework configurado e com vários casos de teste já implementados, fica inevitável a comparação entre o framework padrão e o GTM. Algumas diferenças são notadas logo de cara.

  • Menos métodos de teste: foi um susto ao ver que o framework padrão não tinha o STAssertEqualStrings. Mas nada que assustasse muito: o STAssertEqualObjects servia para o mesmo propósito. No final das contas, não houve nenhum teste que não conseguimos fazer por não existir método para tal.

  • Bundle: Isso é ponto positivo para o GTM. Para acessar arquivos no ambiente padrão você não utiliza o [NSBundle mainBundle]. Para fazer funcionar, tivemos que configurar no target (na aba Properties, no campo Identifier) um identificador que pudesse ser referenciado no código. Se, por exemplo, você colocar lá um identificador "com.mobits.caricas.tests", basta chamar o bundle identificado por essa string: [NSBundle bundleWithIdentifier:@"com.mobits.caricas.tests"]. É óbvio que isso nos causou alguns problemas nos testes, principalmente nos casos em que no target do aplicativo eu tinha que rodar em um bundle e no target de testes eu tinha que rodar em outro. A solução foi utilizar diretivas de pré-compilação.

  • Build Results: nisso o framework padrão ganha de lavada do GTM. Enquanto neste os erros aparecem todos duplicados, e listados diretamente na lista dos resultados do build, naquele aparece bem organizado, cada erro apontado hierarquicamente dentro do seu específico caso de teste.

Exibição de erros no GTM
Exibição dos erros no GTM: duplicado

Exibição dos erros no framework padrão: visão hierárquica dos testes
Exibição dos erros no framework padrão: visão hierárquica dos testes

Conclusão

Por ser mais simples de configurar, por exibir melhor os erros dos testes e por não ter certas mandingas que o GTM tem (não poder rodar os testes com o iPhone Simulator aberto, por exemplo), a escolha é o framework padrão do Xcode. Os métodos a mais de teste do GTM não foram um diferencial tão grande que pesasse em favor dele, mas talvez aqueles que o utilizam e desejam migrar vão ter alguns problemas de adaptação, mas nada que seja o fim do mundo.

Em um post futuro eu comento outra parte importante nos testes, a técnica de Mock Objects, como configurá-lo e como utilizá-lo em seus testes. Ah, e se você encontrou algum erro ao tentar configurar o ambiente, adiciona um comentário aqui, pode ser que já tenhamos passado por isso e saibamos como solucionar.

Grande abraço!

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.