Je souhaite effectuer un test d’application qui analyse certains JSON, les enregistre dans des données de base et lit certains objets.
Comment mon code peut-il savoir s'il est exécuté dans le cadre d'un test ou d'une exécution normale? Juste un moyen de savoir "sommes-nous en cible de test"? Parce que l'application, lorsqu'elle démarre, déclenche une série de requêtes pour renseigner mon coredata avec les informations du serveur. Je ne veux pas que cela se produise lors de mes tests. Je veux lancer l'application, lire HARDCODED json à partir d'un fichier et le stocker en utilisant les mêmes méthodes que dans COREDATA, et vérifier les résultats.
Si quelqu'un pouvait expliquer comment transmettre des paires clé-valeur spécifiques cible par cible pouvant être lues à partir de l'application, je serais encore plus ravi.
Peu importe ... compris que c'est dans "Schémas" que vous définissez ceci.
Par exemple, si vous souhaitez que TARGET = TEST soit disponible pendant le test et que TARGET = RUN soit affiché pendant l'exécution, définissez-le simplement dans votre modèle> variables d'environnement> nom/valeur.
Ensuite, depuis votre application, vous pouvez faire:
[[[NSProcessInfo processInfo] environment] objectForKey:@"TARGET"]
Utilisation des paramètres de construction avec les macros du préprocesseur DID NE fonctionne PAS parce que ma cible de test (pour les tests d'application/d'intégration) dépend de ma cible principale (non testée). La cible principale est donc créée en premier. ce qui est exécuté et vous vous retrouvez avec les macros du préprocesseur cible même si vous suivez celles définies dans la cible que vous avez exécutée. Si quelque chose me manque ici, n'hésitez pas à expliquer.
Si, par "cible de test", vous entendez vos tests unitaires (c.-à-d. Product > Test
ou ⌘U
), vous pouvez ajouter une macro de préprocesseur à la cible et rechercher cette macro dans votre code. Cela permet quelque chose comme ce qui suit:
#ifdef TEST
// Load the hard-coded data.
#else
// Load data from the server.
#endif
Pour ce faire, cliquez sur votre fichier de projet dans le navigateur de projet, sélectionnez votre cible de test, cliquez sur l'onglet Build Settings
, recherchez "macros", double-cliquez sur l'option Preprocessor Macros
et ajoutez-en une!
Il y a deux situations à traiter:
Tests
est sélectionnée, et#import
conditionnellement certains fichiers pour une cible donnée telle que Tests
.Code de cible pour la cible de test:
Créez une macro dans votre fichier ProjectName-Prefix.pch
comme suit:
#define IsTestTarget [[[[NSProcessInfo processInfo] environment][@"XCInjectBundle"] pathExtension] isEqualToString:@"xctest"]
puis appelez-le n'importe où dans l'application:
if (IsTestTarget) {
//Do something specific for test target;
} else {
//Otherwise do something else
}
Conditionnel #import
:
Pour #import
certains fichiers lorsque la cible Tests
est sélectionnée, vous devez ajouter un Preprocessor Macro
à votre cible Test
et l'utiliser comme suit:
#ifdef APPTESTS
#import "TestSpecificFile.h"
#else
#import "SomeOtherFile.h"
#endif
Voici comment vous pouvez ajouter un Preprocessor Macro
:
Vous pouvez utiliser la fonction ci-dessous.
+(BOOL) isRunningTests
{
NSDictionary* environment = [[NSProcessInfo processInfo] environment];
NSString* injectBundle = environment[@"XCInjectBundle"];
return [[injectBundle pathExtension] isEqualToString:@"xctest"];
}
Habituellement, dans Unit Test, les programmeurs utilisent des classes et des fonctionnalités moqueuses. Vous pouvez créer une classe avec une appartenance à la cible only pour la cible de test.
@interface MockClass : NSObject
@end
Ensuite, dans le code de l'application, vous pouvez vérifier si la classe existe en utilisant la fonction NSClassFromString
(qui retournera Nil
pour la cible non incluse dans l'appartenance à la cible de la classe, dans ce cas-ci, cible non testée.
if (NSClassFromString(@"MockClass")) {
//Test Target
} else {
//App Target
}
Et vous pouvez bien sûr le faire fonctionner
BOOL isUnitTest(){
return NSClassFromString(@"MockClass") != Nil;
}