Xcode: PRUEBA frente a las macros del preprocesador DEBUG

Al crear un nuevo proyecto con pruebas unitarias, Xcode establece la configuración de comstackción en Debug para el esquema de prueba (lo mismo para el esquema de ejecución).

¿Debería diferenciar entre los esquemas de Ejecutar (Comando-R) y Probar (Comando-U)?

Es decir, ¿debería crear una nueva configuración de comstackción llamada Test, agregarle una macro de preprocesador TEST = 1 y utilizarla como la configuración de comstackción para el esquema de prueba? O, ¿debería mantener Run & Test como Debug?

Vengo de un entorno de Ruby / Rails, donde generalmente tiene entornos de prueba, desarrollo y producción. Me parece que Debug es como desarrollo y Release es como producción, pero nos falta una prueba, y es por eso que creo que podría tener sentido agregar Test.

¿Comentarios? Opiniones? Sugerencias?

Específicamente pregunto esto porque quiero comstackr algo para Test con:

#ifdef TEST // Do something when I test. #endif 

No creo que importe si también compilo esto para Debug. Entonces, realmente podría hacer:

 #ifdef DEBUG // Do something when I run or test. #endif 

Pero, en realidad, solo tengo la intención de hacerlo para las pruebas por ahora. Entonces, es por eso que estoy pensando que debería diferenciar entre depuración y prueba, pero me pregunto por qué Xcode no hace eso por usted de manera predeterminada. ¿Apple piensa que no deberías diferenciar entre ellos?

Las macros de preprocesador no funcionarán, debe verificar el entorno en tiempo de ejecución.

 static BOOL isRunningTests(void) { NSDictionary* environment = [[NSProcessInfo processInfo] environment]; return (environment[@"XCInjectBundleInto"] != nil); } 

(Actualizado para Xcode 7.3)

Puede considerar agregar una nueva configuración de comstackción.

En xcode 4, haga clic en su proyecto en el navegador de la izquierda.

En la ventana principal, haga clic en su proyecto y luego seleccione la pestaña “información”.

Haga clic en el botón “+” para agregar una nueva configuración (puede llamar a la suya “prueba” si lo desea “).

Ahora, haz clic en tu objective y ve a la pestaña de configuración de construcción.

Buscar “macros de preprocesador”

Aquí puede agregar macros de preprocesador para su nueva configuración de comstackción.

Simplemente haga doble clic en su nueva configuración de “prueba” y agregue TESTING = 1.

Finalmente, edite su esquema de comstackción. Seleccione las opciones de prueba para su esquema. Debe haber un menú desplegable de “Configuración de comstackción”. Seleccione su configuración de “prueba”.

En lugar de crear una configuración de comstackción de prueba, I:

  1. creado un archivo Tests-Prefix.pch :

     #define TEST 1 #import  #import "CocoaPlant-Prefix.pch" 
  2. ingresó a su ruta en el campo Encabezado de prefijo de la configuración de comstackción del objective de Pruebas.

  3. MyAppDefines.h el siguiente código a la parte superior de un archivo que creé llamado MyAppDefines.h , importado en MyApp-Prefix.pch :

     #ifdef TEST #define TEST_CLASS NSClassFromString(@"AppDelegateTests") // any test class #define BUNDLE [NSBundle bundleForClass:TEST_CLASS] #define APP_NAME @"Tests" #else #define BUNDLE [NSBundle mainBundle] #define APP_NAME [[BUNDLE infoDictionary] objectForKey:(NSString *)kCFBundleNameKey] #endif 

Esto me permite usar BUNDLE donde quiera decir [NSBundle mainBundle] y también hacer que funcione cuando ejecuto Tests.

La importación de SenTestingKit en Tests-Prefix.pch también acelera la comstackción de SenTestingKit Framework y me permite omitir #import desde la parte superior de todos los archivos de prueba.

Decidí agregar un cheque para una variable de entorno en el código en sí, en lugar de usar la sugerencia de isRunningTests () que Robert hizo.

  1. Edite el Esquema actual (Esquema de producto / esquema / edición) o Comando + <
  2. Haga clic en la configuración de prueba
  3. Haga clic en Argumentos Desmarque “Utilizar los argumentos y las variables de entorno de la acción Ejecutar
  4. Expanda la sección Variable de entorno y agregue la variable PRUEBA con el valor SÍ
  5. Agregue esto a su código en alguna parte y llame cuando lo necesite:
  + (BOOL) isTesting { NSDictionary* environment = [[NSProcessInfo processInfo] environment]; return [environment objectForKey:@"TESTING"] != nil; } 

La pantalla debería verse así cuando haya terminado.

La pantalla debería verse así

El código anterior encontrará la variable de entorno PRUEBA cuando se ejecuta en modo de prueba o modo de aplicación. Este código va en su aplicación, no en los archivos de prueba de la unidad. Puedes usar

 #ifdef DEBUG ... #endif 

Para evitar que el código se ejecute en producción.

Pruebo mucho tiempo, encontré un resultado:

No solo agrega la macro preprocesador a su objective de prueba unitaria (puede tener muchos métodos que usan variables solo para pruebas unitarias y seguir los métodos @MattDiPasquale),

pero también debe agregar el archivo de condición de conformidad en su objective de prueba. debemos recomstackr este archivo, porque tiene una nueva macro de preprocesador para este archivo, pero este archivo ha incorporado el destino de la aplicación esa vez que no se configuró la macro del preprocesador.

Espero que esto te ayude

La respuesta de Robert en SWIFT 3.0:

 func isRunningTests() -> Bool { let environment = ProcessInfo().environment return (environment["XCInjectBundleInto"] != nil); } 

Mire las variables de entorno para ver si se están ejecutando pruebas unitarias. Similar a la respuesta de Robert, pero solo reviso una vez por el bien del rendimiento.

 + (BOOL)isRunningTests { static BOOL runningTests; static dispatch_once_t onceToken; // Only check once dispatch_once(&onceToken, ^{ NSDictionary* environment = [[NSProcessInfo processInfo] environment]; NSString* injectBundle = environment[@"XCInjectBundle"]; NSString* pathExtension = [injectBundle pathExtension]; runningTests = ([pathExtension isEqualToString:@"octest"] || [pathExtension isEqualToString:@"xctest"]); }); return runningTests; } 

En iOS, [UIApplication sharedApplication] devolverá nil cuando se esté ejecutando una prueba de unidad.

Versión modificada de la respuesta de Kev que funciona para mí en Xcode 8.3.2

 +(BOOL)isUnitTest { static BOOL runningTests; static dispatch_once_t onceToken; // Only check once dispatch_once(&onceToken, ^{ NSDictionary* environment = [[NSProcessInfo processInfo] environment]; if (environment[@"XCTestConfigurationFilePath"] != nil && ((NSString *)environment[@"XCTestConfigurationFilePath"]).length > 0) { runningTests = true; } else { runningTests = false; } }); return runningTests; } 

Si crea una configuración de comstackción de prueba y luego establece la propiedad “Otras banderas rápidas” de su objective para “-DESTAR”, definirá una macro de PRUEBA que funcionará en su código rápido. Asegúrese de configurarlo en la configuración de comstackción de su destino de la aplicación para que pueda usarlo en el código Swift de su aplicación.

Otros ajustes de Swift Flags para DEPURACIÓN y PRUEBA

Luego, con este conjunto, puedes probar tu código así:

 func testMacro() { #if !TEST // skipping over this block of code for unit tests #endif }