Dans un nouveau projet, j'ai ce test simple
#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 fait not une partie de la cible de test, mais cela compile et exécute les tests sans aucun problème.
Je pense que cela est dû au fait que l’application est construite d’abord (en tant que dépendance), puis aux tests. L'éditeur de liens détermine ensuite ce qu'est la classe ViewController.
Cependant, sur un projet plus ancien, avec exactement le même test et le même fichier ViewController, la construction échoue à la phase de l'éditeur de liens:
Undefined symbols for architecture i386: "_OBJC_CLASS_$_ViewController", referenced from: objc-class-ref in ViewControllerTests.o
Cette erreur de l'éditeur de liens se produit même si une nouvelle cible de test d'unité XCTest est créée.
Pour contourner ce problème, il est possible d'inclure les sources dans l'application et les cibles de test (cochez les deux cases dans l'image ci-dessus). Cela provoque des avertissements de construction pour les symboles en double, dans le journal système du simulateur (ouvrez le simulateur et appuyez sur cmd-/pour voir ceci):
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.
Ces avertissements provoquent parfois des problèmes illustrés par l'exemple suivant:
[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
La question est donc de savoir quels paramètres de l'ancien projet exigent que les fichiers source de l'application soient inclus dans la cible de test.
Entre le projet de travail et le projet de non-travail:
Ld
).J'ai passé du temps à comprendre cela.
Si vous lisez cette documentation , vous constaterez que Xcode dispose de deux modes pour exécuter des tests. Tests de logique et tests d'application. La différence réside dans le fait que les tests logiques construisent leur propre cible avec vos classes et symboles intégrés. L'exécutable résultant peut être exécuté dans le simulateur et restitue le résultat du test dans Xcode. Les tests d’application, d’autre part, construisent une bibliothèque dynamique reliant votre code qui est injecté dans l’application au moment de l’exécution. Cela vous permet d'exécuter des tests dans l'environnement iPhone et de tester le chargement Xib et d'autres choses.
Comme les symboles manquent dans votre cible de test lorsque vous dissociez les fichiers source, il semble que votre ancien projet ait une cible de test configurée pour les tests de logique, et non pour les tests d'application (unité).
Comme ces jours-ci, Xcode semble être essayer de ne pas faire la distinction entre les deux et créer une cible de test d’application par défaut permet de parcourir tout ce que vous pourriez avoir à changer pour transformer votre cible de test logique en test unitaire.
Je vais également supposer que vous avez une cible d'application et non une cible de bibliothèque statique, car les instructions seront un peu différentes.
$(SDKROOT)/Developer/Library/Frameworks
$(inherited)
$(DEVELOPER_FRAMEWORKS_DIR)
dans cet ordre et sans guillemets ni barres obliques inverses supplémentairesCette information provient plus ou moins de la documentation liée ci-dessus, mais j'ai mis à jour les étapes pour Xcode 5.
Hmm 100% note ce que dit eph515 à propos de la visibilité des symboles de débogage, mais vous pouvez également vérifier que quelqu'un n'a pas défini l'action de test de votre schéma pour intégrer la configuration Release
ou une autre configuration. Cliquez sur le sélecteur de schéma, puis choisissez modifier le schéma. Cliquez sur l'action de test, puis assurez-vous que la configuration de construction est Debug
Donc, si vous avez une cible de bibliothèque statique, vous avez deux options: 1. Tests de logique 2. Tests d'application dans une application hôte
Pour 1. vous devez vous assurer que Bundle Loader
et Test Host
sont vides pour votre cible de bibliothèque statique. Vos sources doivent ensuite être compilées dans la cible de test car elles n'auraient aucun autre moyen de fonctionner.
Pour 2. Vous devez créer un nouveau projet d'application dans Xcode et ajouter votre projet de bibliothèque statique en tant que sous-projet. Vous devez ensuite copier manuellement les paramètres de construction Bundle Loader
et Test Host
de la cible de test de votre nouvelle application vers votre cible de test Static Lib. Ensuite, vous ouvrez le schéma de votre nouvelle application test et ajoutez votre cible test à l'action tests de la nouvelle application . Pour exécuter les tests sur votre bibliothèque, exécutez l'action test de votre application hôte.
Sur Xcode 6, j'ai pu résoudre ce problème en cochant la case "Autoriser le test des API d'application hôte" dans la cible de test> Général> Test.
J'ai également rencontré ce problème et suivi la recommandation de jackslash, mais avec un dernier ajout: sélectionnez votre cible principale et recherchez les symboles masqués par défaut (sous Apple LVM 5.0 - Génération de code); si la valeur est Oui, remplacez-le par Non pour "masquer" tous les symboles des sources compilées que la cible de test unitaire recherche. Travaille pour moi. Assurez-vous d'inclure toutes les étapes décrites dans jackslash.
La réponse était une combinaison des réponses de jackslash et de eph515.
Comme dans la réponse de eph515, symbols hidden by default
devrait être Non pour le débogage.
De plus, deployment postprocessing
devrait être Non pour le débogage.
De même, toutes les bibliothèques incluses dans la cible de test doivent être supprimées du test unitaire. Il ne reste que les 3 dans la capture d'écran, ainsi que tout ce qui est spécifique aux tests unitaires.
De même, s'il existe une phase de génération de script d'exécution à la fin de la liste, vous devez la supprimer (car il s'agit d'un artefact de test unitaire).
Ensuite, faites tout dans la réponse de jackslash .
Dans mon cas, dans Xcode 6.2, une erreur était survenue dans différentes architectures de cible de projet et cible de test.
La cible du projet a uniquement les architectures armv7 et armv7s (à cause de certaines bibliothèques plus anciennes)
La cible Tests du projet a les architectures armv7, armv7s et arm64.
La suppression de l'architecture arm64 résout ce problème dans mon cas.
Project Editor -> Project Tests target -> Build Settings -> Valid Architectures = armv7 armv7s
(Peut-être est-il également nécessaire de définir "Architectures" au lieu de $ (ARCHS_STANDARD) sur $ (ARCHS_STANDARD_32_BIT))