iOS - Fichier 'MyProject-Swift.h' introuvable lors de l'exécution de tests unitaires pour Swift

94

J'essaie de configurer les tests unitaires pour mon projet. C'est une application Objective-C existante, à laquelle j'ai récemment ajouté une classe Swift. J'ai configuré les fichiers 'MyProject-Swift.h' et Swift Bridging (à la fois 'MyProject' et 'MyProjectTest') et je suis capable de créer et d'exécuter l'application très bien en utilisant à la fois le code Objective-C et Swift.

Cependant, je souhaite maintenant exécuter des tests unitaires sur la nouvelle classe Swift. J'ai configuré mon fichier de test et il ressemble à ce qui suit:

MySwiftClassTests.swift:

import UIKit
import XCTest
import MyProject

class MySwiftClassTests: XCTestCase {

    override func setUp() {
        super.setUp()
        // Put setup code here. This method is called before the invocation of each test method in the class.
    }

    override func tearDown() {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        super.tearDown()
    }

    func testExample() {
        // This is an example of a functional test case.
        XCTAssert(true, "Pass")
    }

    func testPerformanceExample() {
        // This is an example of a performance test case.
        self.measureBlock() {
            // Put the code you want to measure the time of here.
        }
    }

}

J'obtiens cette erreur lors de l'exécution de l'application en tant que test:

'MyProject-Swift.h' file not found

Je ne sais pas pourquoi cela se produit uniquement lorsque vous essayez d'exécuter les tests. Aucune suggestion?

JimmyJammed
la source
1
Ajouter des mises à jour à ce sujet? Je suis confronté au même problème ...
hyouuu
1
@Coveloper - Comment pouvez-vous définir les cibles pour le fichier '-Swift.h'? Ce n'est pas un vrai fichier qui se trouve dans le projet, mais plutôt compilé par Xcode lors de la construction.
JimmyJammed
1
Voici une mise à jour de mon commentaire "Je reçois également l'erreur" Fichier "MyProject-Swift.h" introuvable. "Ci-dessus: J'ai trouvé une solution de contournement en définissant le nom du module de produit de la cible MyProjectTests sur MyProject par opposition à MyProjectTests. Ainsi, maintenant, les deux cibles (MyProject et MyProjectTests) ont le même nom de module de produit. C'est étrange, mais cela fonctionne et présente un faible risque car c'est la cible du test. Je devrais mentionner que le nom de mon projet est en fait comme My-Project, donc My_Project est le nom réel du module.)
finneycanhelp
6
Le fichier "MyProject-Swift.h" est généré à "$ (TARGET_TEMP_DIR) /../$ (PROJECT_NAME) .build / DerivedSources". Je finis par l'ajouter aux chemins de recherche d'en-tête pour ma cible de test unitaire.
gagarwal
1
@gagarwal L'ajout de "$ (TARGET_TEMP_DIR) /../$ (PROJECT_NAME) .build / DerivedSources" aux chemins de recherche d'en-tête pour ma cible de test unitaire a fonctionné. :) Faites une réponse SO à ce commentaire et je peux vous attribuer la prime et faire comprendre aux autres quelle excellente réponse c'est.
finneycanhelp

Réponses:

148

Le fichier "MyProject-Swift.h" est généré au chemin suivant:

"$(TARGET_TEMP_DIR)/../$(PROJECT_NAME).build/DerivedSources"

Je finis par l'ajouter aux chemins de recherche d'en-tête pour ma cible de test unitaire.

Aussi, comme @hyouuu l'a souligné à propos du problème connu, j'espère qu'Apple fournira une bonne solution à leur fin. Jusqu'à ce que je pense que nous devons utiliser cette solution ci-dessus.

https://developer.apple.com/library/content/documentation/Xcode/Conceptual/RN-Xcode-Archive/Chapters/xc6_release_notes.html

gagarwal
la source
A travaillé comme un charme!
DonnaLea
Impressionnant! Je ne sais pas pourquoi Apple ne mentionne pas cela comme solution de contournement. Aussi étonné qu'il n'y ait pas plus de personnes ayant ce problème. Toute personne ayant un projet Obj-C existant convertissant progressivement des éléments en Swift rencontrera ce problème.
mluisbrown
@fabb n'est pas vrai - le TARGET_NAME est généralement quelque chose comme <Product Name> Testsdans votre cible de test. Cependant, cette solution ne fonctionne pas si le nom de votre produit comporte des espaces. Voir ma réponse ci-dessous pour une solution.
Christopher Pickslay
2
Juste une note, j'ai dû ajouter le chemin de recherche et le définir comme "récursif" spécifiquement. Cela peut être évident, mais cela n'a pas fonctionné plusieurs fois jusqu'à ce que je fasse cela; Je suppose que cela va dans des sous-dossiers alors.
Miro
1
Pour mon projet, cela $(TARGET_TEMP_DIR)n'a pas fonctionné. J'ai fini par utiliser$CONFIGURATION_TEMP_DIR/{myTargetName}.build/DerivedSources
Jordan Bondo
32

Merci à @gagarwal pour avoir compris cela. Dans notre cas, le nom du produit a un espace, qui est réduit $PROJECT_NAME, donc j'ai dû le coder en dur. En outre, en utilisant $CONFIGURATION_TEMP_DIRau lieu de $TARGET_TEMP_DIR, vous pouvez supprimer le répertoire parent ( ../) du chemin. La solution consiste donc à ajouter ce qui suit aux chemins de recherche d'en-tête de votre cible de test:

"$(CONFIGURATION_TEMP_DIR)/Product Name With Spaces.build/DerivedSources"

Ou, si votre produit ne contient pas d'espaces:

"$(CONFIGURATION_TEMP_DIR)/$(PROJECT_NAME).build/DerivedSources"
Christopher Pickslay
la source
Résout également le problème des classes de codegen Core Data de test unitaire.
Elise van Looij
14

Vu dans la note de publication de Xcode 6.1, qu'il s'agit d'un problème connu ... signe ... Recherchez "-swift.h" dans la note de publication https://developer.apple.com/library/content/documentation/Xcode /Conceptual/RN-Xcode-Archive/Chapters/xc6_release_notes.html

Les tests écrits en Objective-C ne peuvent pas importer l'en-tête des interfaces générées par Swift ($ (PRODUCT_MODULE_NAME) -Swift.h) pour les cibles d'application et ne peuvent donc pas être utilisés pour tester le code qui nécessite cet en-tête.

Les tests de code Swift doivent être écrits en Swift. Les tests écrits en Objective-C pour les cibles de framework peuvent accéder aux interfaces générées par Swift en important le module de framework à l'aide de @import FrameworkName ;. (16931027)

Veuillez voir la solution de contournement de @ gagarwal ci-dessous qui FONCTIONNE!

hyouuu
la source
8

J'ai eu un problème similaire au vôtre, je pense; voici ma configuration.

J'avais un objet défini dans Swift:

// file Foo.swift
@objc public class Foo {
    // ...
}

Cette classe a ensuite été utilisée dans l'initialiseur d'un objet Objective-C:

// file Bar.h
#import "MyProject-Swift.h"

@interface Bar: NSObject

- (instancetype)initWithFoo:(Foo *)foo;

@end

Cela a rendu mes tests unitaires pour Barne pas compiler, car l'en- MyProject-Swift.htête n'est pas réel et la cible du test unitaire ne peut pas le voir. La note de publication partagée par @hyouuu est sur le point - mais je ne teste pas une classe Swift, je teste une classe Objective-C!

J'ai pu résoudre ce problème en modifiant le fichier d'en-tête pour Barutiliser une référence de classe avant à la place:

// file Bar.h
@class Foo;

@interface Bar: NSObject

- (instancetype)initWithFoo:(Foo *)foo;

@end

Je puis inclus MyProject-Swift.hdans Bar.m, et tout fonctionnait - mes tests d'objets Objective-C écrit en Objective-C compilé correctement et continuer à l' utiliser, et je pourrais écrire de nouveaux tests pour les objets Swift à Swift.

J'espère que cela t'aides!

dpassage
la source
Votre solution ne permet pas d'utiliser Fool'API de l'intérieur Bar.m.
Yevhen Dubinin
2
Bien sûr, c'est ce que vous permet d'inclure MyProject-Swift.hdans le .mfichier.
dpassage
4

Après avoir essayé tout ce que je pouvais trouver sur le sujet, la chose qui fonctionnait pour moi était en fait d'exécuter l'application bien qu'elle montrait toujours l'erreur `` ModuleName-Swift.h file not found ''.

Il a disparu et mon application fonctionne parfaitement. J'imagine que j'aurais dû y penser plus tôt ... L' erreur revient sans cesse , mais après avoir exécuté l'application, elle disparaît toujours. Le problème n'est donc pas vraiment résolu pour moi, mais je peux continuer à travailler sur d'autres sujets pour l'instant ...

schrulnz
la source
Oui, c'est une solution pour éliminer l'erreur "introuvable".
Vijay Kumar Kanta
Même maintenant, Build échoue alors que le seul fonctionnement de l'application fonctionne. Corrige ça, Apple!
ScottyB
1

Un simple

@testable import MyProject

a fait le travail pour moi.

Niggeulimann
la source
0

Étrangement, je voyais cette même erreur, mais uniquement lorsque je visais un appareil (pas le simulateur). Avant d'exécuter le test, je voyais le point d'exclamation rouge à côté de l'instruction d'importation pour "MyProjectNameTests-Swift.h".

Cependant, ce qui est drôle, c'est que si je continue et exécute le test de toute façon (malgré cette erreur de construction apparente), alors pendant la phase de construction qui se produit par la suite, XCode génère en fait le fichier "MyProjectNameTests-Swift.h", et le test fonctionne très bien!

Donc, du moins dans mon cas, il n'y avait évidemment pas besoin des autres solutions ici, bien que je pense qu'elles fonctionnent également.

Je dois également noter que j'ai supprimé mon répertoire DerivedData avant cela, alors peut-être que c'est une étape qui vaut également la peine d'être essayée.

Virgule
la source
-1

mySwiftClassTests(et toutes les autres classes rapides que vous souhaitez utiliser dans objective-c) doivent être marquées @objc:

@objc class MySwiftClassTests: XCTestCase
qui sait
la source
-1

Je ne pouvais pas le faire fonctionner en ajoutant ce chemin de fichier mentionné par d'autres réponses, mais j'ai réalisé que le fichier dans lequel il se plaignait n'était même pas testé. Je devais simplement le supprimer de la cible de test en utilisant la barre latérale Right Utilities.

teradyl
la source
-2

L'ajout d'un fichier .swift à cette cible résout le problème.

Dmitry
la source