web-dev-qa-db-fra.com

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

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é le 'MyProject-Swift.h' et Swift Le pontage des fichiers ('MyProject' et 'MyProjectTest') et je suis capable de construire et d'exécuter l'application parfaitement en utilisant Objective-C et le code Swift.

Cependant, je souhaite maintenant exécuter des tests unitaires sur la nouvelle classe Swift. J'ai configuré mon fichier de test et il se présente comme 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.
        }
    }

}

Je reçois 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?

90
JimmyJammed

Le fichier "MyProject-Swift.h" est généré à l'emplacement 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 d'unité.

De plus, comme @hyouuu l'a signalé comme étant le problème connu, Apple fournira une solution intéressante à leur problème. 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

143
gagarwal

Merci à @gagarwal de l'avoir découvert. Dans notre cas, le nom du produit a un espace qui est réduit dans $PROJECT_NAME, j'ai donc dû le coder en dur. De plus, en utilisant $CONFIGURATION_TEMP_DIR au lieu de $TARGET_TEMP_DIR, vous pouvez supprimer le répertoire parent (../) du chemin. La solution consiste donc à ajouter les éléments suivants 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"
30

Vu dans la note de publication de Xcode 6.1, 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 d'interface généré par Swift ($ (PRODUCT_MODULE_NAME) -Swift.h) et ne peuvent donc pas être utilisés pour tester le code qui requiert cet en-tête.

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

S'il vous plaît voir la solution de contournement @ gagarwal ci-dessous qui fonctionne!

14
hyouuu

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

J'ai eu 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 fait que mes tests unitaires pour Bar ne soient pas compilés, car le MyProject-Swift.h en-tête n’est pas réel et la cible de test unitaire ne le voit pas. La note de publication partagée par @hyouuu est pertinente - 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 que Bar utilise une référence de classe à la place:

// file Bar.h
@class Foo;

@interface Bar: NSObject

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

@end

J'ai ensuite inclus MyProject-Swift.h dans Bar.m, et tout a fonctionné - mes tests des objets Objective-C écrits en Objective-C correctement compilés et poursuivis, et je pouvais écrire de nouveaux tests pour les Swift objets dans Swift.

J'espère que cela t'aides!

7
dpassage

Après avoir essayé tout ce que je pouvais trouver sur le sujet, la chose qui a fonctionné pour moi était en train d'exécuter l'application, même si elle montrait toujours le fichier 'NomModule-Swift.h non trouvé' erreur.

Il est parti et mon application fonctionne parfaitement. J'imagine que j'aurais dû considérer cela plus tôt ... Le l'erreur revient constamment, mais après avoir exécuté l'application, il disparaît toujours à nouveau. Donc, le problème n'est pas vraiment résolu pour moi, mais je peux continuer à travailler sur d'autres sujets pour le moment ...

4
schrulnz

Un simple

@testable import MyProject

a fait le travail pour moi.

0
niggeulimann

Étrangement, je voyais cette même erreur, mais seulement lorsque je ciblais 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 amusant, c’est que si je lance le test quand même (malgré cette erreur de construction apparente), alors pendant la phase de construction qui s’ensuit, XCode génère le fichier "MyProjectNameTests-Swift.h", et le test fonctionne très bien!

Donc, du moins dans mon cas, les autres solutions ici n'étaient évidemment pas nécessaires, bien que je pense qu'elles fonctionnent également.

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

0
CommaToast