ios - una - testflight pendiente de revisión
¿Cuándo se deben incluir las fuentes de la aplicación en los objetivos de prueba? (6)
En un nuevo proyecto, tengo esta simple prueba
#import <XCTest/XCTest.h>
#import "ViewController.h"
@interface ViewControllerTests : XCTestCase
@end
@implementation ViewControllerTests
- (void)testExample
{
// Using a class that is not in the test target.
ViewController * viewController = [[ViewController alloc] init];
XCTAssertNotNil(viewController, @"");
}
@end
ViewController.h no es parte del objetivo de la prueba pero esto compila y ejecuta las pruebas sin problemas.
Creo que esto se debe a que la aplicación se genera primero (como dependencia) luego las pruebas. El vinculador luego averigua qué es la clase ViewController.
Sin embargo, en un proyecto anterior, con exactamente la misma prueba y el archivo ViewController, la compilación falla en la fase del enlazador:
Undefined symbols for architecture i386: "_OBJC_CLASS_$_ViewController", referenced from: objc-class-ref in ViewControllerTests.o
Este error de enlazador se produce incluso cuando se crea un objetivo de prueba de la unidad XCTest reciente.
Para evitar esto, es posible incluir las fuentes tanto en la aplicación como en los objetivos de prueba (marque ambas casillas en la imagen de arriba). Esto provoca advertencias de construcción para símbolos duplicados, en el registro del sistema del simulador (abra el simulador y presione cmd- / para ver esto):
Class ViewController is implemented in both [...]/iPhone Simulator/ [...] /MyApp.app/MyApp and [...]/Debug-iphonesimulator/LogicTests.octest/LogicTests. One of the two will be used. Which one is undefined.
Estas advertencias ocasionalmente causan problemas ilustrados por el siguiente ejemplo:
[viewController isKindOfClass:[ViewController class]]; // = NO
// Memory address of the `Class` objects are different.
NSString * instanceClassString = NSStringFromClass([viewController class]);
NSString * classString = NSStringFromClass([ViewController class]);
[instanceClassString isEqualToString:classString]; // = YES
// The actual class names are identical
Entonces, la pregunta es ¿qué configuración (es) en el proyecto anterior requieren que los archivos fuente de la aplicación se incluyan en el objetivo de la prueba?
Resumen de comentarios
Entre el proyecto que trabaja y el que no funciona:
- No hay diferencia en la salida del enlazador (el comando que comienza con
Ld
). - No hay diferencia en las dependencias objetivo (hay una dependencia del objetivo de la prueba, que es la aplicación)
- No hay diferencia en la configuración del enlazador.
En Xcode 6, pude solucionar este problema marcando "Permitir probar las API de la aplicación de host" en el objetivo de la prueba> General> Prueba.
En mi caso en Xcode 6.2 hubo un error en diferentes arquitecturas en el objetivo del proyecto y en el objetivo de las pruebas.
El objetivo del proyecto solo tiene las arquitecturas armv7 y armv7s (debido a alguna biblioteca anterior)
El objetivo de Project Tests tiene las arquitecturas armv7, armv7s y arm64.
La eliminación de la arquitectura arm64 resuelve este problema en mi caso.
Project Editor -> Project Tests target -> Build Settings -> Valid Architectures = armv7 armv7s
(quizás también se necesite configurar "Arquitecturas" en lugar de $ (ARCHS_STANDARD) en $ (ARCHS_STANDARD_32_BIT))
La respuesta fue una combinación de las respuestas de jackslash y eph515.
Como en los symbols hidden by default
respuestas de eph515 symbols hidden by default
debería ser No para la depuración.
Además, el deployment postprocessing
debe ser No para depuración.
Además, todas las bibliotecas incluidas en el objetivo de prueba deben eliminarse de la prueba unitaria. Todo lo que debe quedar son los 3 en la captura de pantalla más cualquier cosa que sea específica para la prueba unitaria.
Además, si hay una fase de compilación ejecutar script de compilación al final de la lista, entonces debe eliminarse (ya que es un artefacto de pruebas unitarias).
Entonces haz todo en la respuesta de jackslash .
Me encontré con esto también y seguí la recomendación de jackslash pero con una adición más: seleccione su objetivo principal y busca Símbolos ocultos por defecto (en Apple LVM 5.0 - Generación de código), si el valor es Sí, cámbielo a No. Esto parece para ''ocultar'' todos los símbolos de las fuentes compiladas que está buscando el objetivo de la prueba unitaria. Funciona para mi. Asegúrese de incluir todos los pasos descritos por jackslash.
Pasé algún tiempo descifrando esto.
Si lee esta documentación , encontrará que Xcode tiene dos modos para ejecutar pruebas. Pruebas lógicas y pruebas de aplicación. La diferencia es que las pruebas lógicas crean su propio objetivo con sus clases y símbolos incorporados directamente. El ejecutable resultante se puede ejecutar en el simulador e informa de la salida de prueba a Xcode. Por otro lado, las pruebas de aplicación crean una biblioteca dinámica que enlaza con su código que se inyecta en la aplicación en tiempo de ejecución. Esto le permite ejecutar pruebas en el entorno de iPhone y probar la carga de Xib y otras cosas.
Debido a que los símbolos faltan en su objetivo de prueba cuando desenlaza los archivos fuente, parece que su proyecto anterior parece tener un objetivo de prueba configurado para pruebas lógicas, no pruebas de Aplicación (unidad).
Como en estos días Xcode parece estar tratando de no distinguir entre los dos y los valores predeterminados para crear un objetivo de Pruebas de Aplicación, haga un recorrido por todas las cosas que podría tener que cambiar para convertir su Objetivo de Prueba Lógica en uno de prueba unitaria.
También voy a suponer que tienes un objetivo de aplicación y no un objetivo de biblioteca estática ya que las instrucciones serán un poco diferentes.
- En la configuración de compilación para su destino de prueba, elimine la configuración de compilación "Bundle Loader" y "Test Host". Obtendremos Xcode para agregarlos de nuevo más tarde
- Debe eliminar todos los archivos .m de su aplicación del objetivo de prueba. Puede hacer esto seleccionando todos los archivos .m y eliminando el objetivo de prueba en el inspector de archivos de Xcode o puede usar la fase de compilación de fuentes de compilación del objetivo de prueba.
- Cambie las "rutas de búsqueda de Framework" para su objetivo de prueba. Para Xcode 5 deberían ser
$(SDKROOT)/Developer/Library/Frameworks $(inherited) $(DEVELOPER_FRAMEWORKS_DIR)
en ese orden y sin comillas adicionales o barras invertidas - Vaya al panel General de la configuración de compilación de su objetivo de prueba y seleccione su objetivo en el menú desplegable. Si el menú ya especifica el objetivo de su aplicación, debe apagarlo y volver a encenderlo. Esto hará que Xcode reconfigure el cargador de Bundles y pruebe la configuración del Host con el valor correcto.
- Por último, revise el esquema de su aplicación. En el esquema desplegable seleccione el esquema de edición. Luego haz clic en la acción de prueba. Asegúrese de que el objetivo de prueba esté en la lista en el panel de información y asegúrese de que se seleccionen todas las pruebas.
Esta información proviene más o menos de la documentación vinculada anterior, pero actualicé los pasos para Xcode 5.
EDITAR:
Hmm 100% tenga en cuenta lo que eph515 está diciendo acerca de los símbolos de depuración que son visibles, pero también podría verificar que alguien no haya configurado la acción de prueba de su esquema para compilar la Release
u otra configuración. Haga clic en el selector de esquema y elija editar esquema. Haga clic en la acción de prueba y luego asegúrese de que la Configuración de compilación esté Debug
Si tiene un objetivo de biblioteca estática
Entonces, si tiene un objetivo de biblioteca estática, tiene dos opciones: 1. Pruebas lógicas 2. Pruebas de aplicaciones en una aplicación host
Para 1. debe asegurarse de que Bundle Loader
y Test Host
estén vacíos para su objetivo de biblioteca estática. Sus fuentes deben compilarse en el objetivo de prueba ya que no tendrían otra forma de ejecutarse.
Para 2. Necesita hacer una nueva aplicación Proyecto en Xcode y agregar su proyecto de Biblioteca estática como un subproyecto. A continuación, debe copiar manualmente la configuración de compilación de Bundle Loader
y Test Host
desde el objetivo de prueba de su nueva aplicación a su objetivo de prueba de Lib estático. Luego, abre el esquema de su nueva Aplicación de prueba y agrega su objetivo de prueba a la acción de prueba para la nueva aplicación. Para ejecutar las pruebas en su lib, ejecuta la acción de prueba para su aplicación de host.