Pergunta

Estou migrando meu projeto do Xcode 4.6.3 para o Xcode 5.0.2.Os testes unitários do projeto foram desenvolvidos com SenTestingKit/OCUnit.Agora, quando estou executando os testes no Xcode 5, recebo um erro do RunUnitTests roteiro me dizendo isso

RunUnitTests está obsoleto.

Possivelmente relacionada está esta nota nas notas de lançamento do Xcode 5:

SenTestingKit e OCUnit estão obsoletos.Use o migrador para migrar para o XCTest.

Infelizmente, não consegui saber mais sobre este misterioso “migrador”.Possivelmente meu google-fu está faltando [de novo], então minha pergunta principal é:Como migrar testes unitários do SenTestingKit/OCUnit para o novo XCTest (com ou sem o "migrador")?

Uma questão secundária, caso a migração seja um negócio complicado:É possível fazer com que o Xcode 5 execute testes de unidade que ainda são baseados em SenTestingKit/OCUnit?Afinal, eles estão meramente obsoletos, então eles ainda devem estar disponíveis e funcionais.

Foi útil?

Solução

Graças à resposta do Shaggy Frog, sabemos que o misterioso "migrador" mencionado nas notas de lançamento do Xcode é um assistente iniciado selecionando "Editar > Refatorar > Converter para XCTest".Vou escrever sobre minha experiência com esse assistente em duas partes.A primeira parte é uma resposta incompleta à questão principal, a segunda parte responde à questão secundária.


Parte 1:Como migrar do OCUnit para o XCTest

A primeira coisa que você precisa entender é que para o assistente funcionar, você precisa selecione um destino de teste de unidade.Se você tiver o destino principal selecionado, o assistente simplesmente não lista nenhum destino para converter.

Assim que descobri isso, consegui passar pelo assistente, mas no meu caso o resultado final ainda foi um fracasso espetacular!O assistente afirmou que nenhuma alteração na fonte era necessária e que apenas as configurações de compilação precisavam ser atualizadas para migrar para o XCTest.No final, o assistente nem conseguiu fazer isso corretamente:Isto fez remova a referência à estrutura SenTestingKit, mas isso aconteceu não coloque uma referência à estrutura XCTest.

De qualquer forma, o que se segue é uma lista das alterações que tive que fazer manualmente porque o assistente não conseguiu fazê-las para mim.Se o assistente funcionar melhor para você, talvez não seja necessário fazer todas essas coisas.

  1. Remova a fase de compilação "Run Script" do destino do teste de unidade
  2. Altere a classe base de todas as classes de casos de teste de SenTestCase para XCTestCase
  3. Altere o cabeçalho importado de <SenTestingKit/SenTestingKit.h> para <XCTest/XCTest.h>
  4. Nas configurações de compilação do destino de teste, altere a extensão Wrapper de octest para xctest.
  5. Renomeie todas as macros de declaração de ST* para XCT* (por exemplo. STAssertTrue torna-se XCTAssertTrue)
  6. Exceção ao acima: STAssertEquals precisa ser renomeado para XCTAssertEqual (observe o "s" faltante no final).Você saberá que se esqueceu disso se receber este aviso do compilador: warning: implicit declaration of function 'XCTAssertEquals' is invalid in C99
  7. As novas macros de afirmação do XCTest não permitem nil a ser passado como a descrição da falha.Por exemplo, XCTAssertNotNil(anObject, nil) não é possível e deve ser alterado para XCTAssertNotNil(anObject).Você saberá que tem esse problema quando receber este erro do compilador: error: called object type 'NSString *' is not a function or function pointer.
  8. Se você fazer precisa passar uma descrição de falha, as novas macros de afirmação XCTest requerem uma expressão constante para o especificador de formato, assim como o NSString método de classe stringWithFormat: faz.Você saberá que tem esse problema quando receber este erro do compilador: error: expected ')'.Alguns exemplos:
NSString* formatSpecifier = @"%@";
NSString* failureDescription = @"foo";
// These are OK
XCTAssertNotNil(anObject, @"foo")
XCTAssertNotNil(anObject, @"%@", failureDescription)
// These are not OK
XCTAssertNotNil(anObject, failureDescription);
XCTAssertNotNil(anObject, formatSpecifier, failureDescription);

Por último, mas não menos importante, como já mencionado acima, a referência ao framework XCTest precisa ser adicionada ao alvo do teste unitário.Você saberá que esqueceu isso se receber erros do vinculador, como Undefined symbols for architecture i386: "_OBJC_CLASS_$_XCTestCase", referenced from: foo.

Atualização do Xcode 6:A vinculação ao XCTest não é mais necessária no Xcode 6 (na verdade, o XCTest nem está mais listado como uma estrutura disponível).Em vez disso, defina a configuração de construção CLANG_ENABLE_MODULES como YES (exposta na UI como "Ativar Módulos (C e Objective-C)").Isto causará clang para vincular automaticamente ao XCTest quando vê um #import <XCTest/XCTest.h> declaração.Os detalhes estão disponíveis no Seção "Módulos" da documentação do clang.


Parte 2:Como executar testes OCUnit no Xcode 5

Nesse ponto recebi um erro de linker que me fez perceber que minha missão de migrar para o XCTest havia falhado.A razão:O XCTest não faz parte do SDK 6.1, mas ainda estou construindo meu projeto com o SDK base iOS 6.1 (esta resposta SO explica como integrar o SDK 6.1 ao Xcode 5).

Como não consigo continuar com a migração, minha solução no momento é manter meus testes de unidade baseados em SenTestingKit/OCUnit, até encontrar tempo para atualizar meu aplicativo para iOS 7.Isso é o que eu tive que fazer para executar os testes de unidade:

  1. Remova a fase de compilação "Run Script" do destino do teste de unidade.Isso é tudo o que é necessário para permitir que o Xcode execute testes de unidade por meio da ação "Teste" ( + você) enquanto o destino do teste de unidade estiver selecionado.
  2. Porém, isso não é o ideal, porque não quero mudar de alvo apenas para executar testes de unidade.Em vez disso, quero executar testes unitários enquanto o alvo principal está selecionado.A segunda etapa, portanto, é modificar o esquema Xcode do destino principal para que, quando eu executar a ação "Teste", os testes do destino do teste de unidade sejam executados.

A solução final não é tão boa quanto no Xcode 4.x, onde os testes de unidade eram executados automaticamente toda vez que eu executava a ação "Executar" ou "Construir" do alvo principal.Infelizmente, parece que não consigo fazer isso funcionar sem uma fase de construção "Run Script".

Outras dicas

editar -> Refator -> Converter para XCTEST

Os testes Ocunit ainda funcionarão, mas você também pode migrar.As mudanças acabam sendo mínimas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top