Resultados para 'xcode'
Testes no iPhone - Usando o framework padrão do Xcode
Escrito por Afonso Junior em 02/03/10 11:30
O post do Felipe sobre testes em iPhone, escrito em janeiro do ano passado, serviu como parâmetro para vários projetos nossos aqui na Mobits. Só depois de um bom tempo utilizando o framework do Google, descobrimos lendo posts do Matt Gallagher no Cocoa with love que o framework nativo do Xcode estava disponível para projetos em iPhone.
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....

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:

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...).

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:

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 dos erros no GTM: duplicado

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!
Leia também
Formatador Automático para Objective C
Escrito por Felipe Barreto em 04/05/09 19:55
Uma das coisas que me incomodam na hora de programar pra iPhone é que o XCode não possui um mecanismo para formatar automaticamente o código como há no Eclipse ou no NetBeans. O máximo que a IDE da Apple permite é tabular automaticamente um trecho de código selecionado. Muito fraco.
Durante a pesquisa, foi difícil escolher o termo certo para encontrar o que eu queria, pois existem diversas variações: code beautifier, formatter, code styler, entre outras.
Finalmente, encontrei o tal do Uncrustify que é um programa de terminal para UNIX - logo, para MAC - e que permite configurar uma série de parâmetros de formatação e aplicar sobre um arquivo de código de diversas linguagens baseadas em C - inclusive Objective C.
"Estou no caminho certo", pensei eu. "Agora só falta aprender a instalar, configurar e fazer o XCode usar o programinha". Depois de penar um pouco, cheguei ao artigo que me colocou na direção que eu esperava. Nem tudo o que foi dito nele funcionou 100% ou está completo, mas foi de grande ajuda para conseguir alcançar o que vou apresentar abaixo.
Baixando e instalando o Uncrustify
- Faça o download do uncrustify e extraia em qualquer lugar;
- Abra o arquivo uncrustify.xcodeproj no XCode e dê um Build (Command-B);
- Volte à pasta onde extraiu o Uncrustify e procure o executável no caminho build/ppc.
Agora, como meu conhecimento de UNIX é meio tosco, não garanto que o passo seguinte seja o mais correto, mas funcionou. :D
- Copie o executável para a pasta /usr/bin (pode ser necessário se autenticar como admin).
Pronto! O Uncrustify está disponível para ser usado por qualquer usuário da máquina.
Criando o arquivo de configuração
Na pasta do Uncrustify, você vai encontrar o arquivo etc/defaults.cfg que possui praticamente todos os parâmetros disponíveis acompanhado de comentários bem explicativos. Mas eles são muitos e configurá-los um por um sem ver o efeito que causam sobre o código é impensável para alguém preguiçoso como eu.
Felizmente, alguém teve a bondade de criar um configurador para diversas ferramentas como o Uncrustify, inclusive o próprio: UniversalIndentGUI.
Esta ferramenta, apesar de ter a interface um pouco tosca e com usabilidade mediana, facilita muito o trabalho, pois permite editar os parâmetros e ver imediatamente o resultado sobre um trecho de código que você pode fornecer e manipular durante a fase de configuração.
Não vou me aprofundar sobre os detalhes desta fase, mas se você não estiver interessado em passar por ela, compartilho aqui o arquivo - ainda em desenvolvimento - com o padrão de código da Mobits.
Usando o arquivo acima, ou gerando o seu próprio, recomendo salvá-lo em /etc/uncrustify/qualquer_coisa.cfg para que esteja disponível para todos os usuários.
Colocando no XCode
Embora o XCode não possua diversas ferramentas comuns em outras IDEs, ele tem um mecanismo simples para adicionar funcionalidades sem muito esforço: os User Scripts.

- Abra a tela de edição dos User Scripts e adicione um Shell Script com nome tipo "Auto Format";
- Sugiro definir um atalho de teclado, como command-shift-A;
- Copie o código abaixo para o seu script (renomeie o arquivo de configuração se necessário):
#!/bin/sh
echo -n "%%%{PBXSelection}%%%"
uncrustify -q -l OC -c /etc/uncrustify/mobits-uncrustify.cfg
echo -n "%%%{PBXSelection}%%%"
- Configure os parâmetros de entrada e saída
- Input: Entire Document
- Directory: Selection
- Output: Replace Document Contents
- Errors: Display in Alert
Pronto. Agora basta executar o script sobre o código que estiver aberto no momento e apreciar sua beleza. :D
Até a próxima.
Leia também: