iOS - podczas uruchamiania testów jednostkowych dla języka Swift nie znaleziono pliku „MyProject-Swift.h”

95

Próbuję skonfigurować testy jednostkowe dla mojego projektu. Jest to istniejąca aplikacja Objective-C, do której niedawno dodałem jedną klasę Swift. Skonfigurowałem pliki „MyProject-Swift.h” i Swift Bridging (zarówno „MyProject”, jak i „MyProjectTest”) i mogę dobrze zbudować i uruchomić aplikację, używając zarówno kodu Objective-C, jak i Swift.

Jednak teraz chcę uruchomić kilka testów jednostkowych na nowej klasie Swift. Skonfigurowałem plik testowy i wygląda to następująco:

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.
        }
    }

}

Otrzymuję ten błąd podczas uruchamiania aplikacji jako test:

'MyProject-Swift.h' file not found

Nie jestem pewien, dlaczego dzieje się tak tylko podczas próby uruchomienia testów. Jakieś sugestie?

JimmyJammed
źródło
1
Dodać aktualizacje? Mam ten sam problem ...
hyouuu
1
@Coveloper - Jak możesz ustawić cele dla pliku „-Swift.h”? Nie jest to prawdziwy plik, który znajduje się w projekcie, ale zamiast tego jest kompilowany przez Xcode podczas kompilacji.
JimmyJammed
1
Oto aktualizacja mojego powyższego komentarza „Otrzymuję również błąd„ Nie znaleziono pliku MyProject-Swift.h ”..”: Znalazłem obejście tego problemu, ustawiając nazwę modułu produktu celu MyProjectTests na MyProject, a nie na MyProjectTests. Tak więc teraz oba obiekty docelowe (MyProject i MyProjectTests) mają tę samą nazwę modułu produktu. To dziwne, ale działa i wiąże się z niskim ryzykiem, ponieważ jest celem testu. Powinienem wspomnieć, że nazwa mojego projektu jest w rzeczywistości taka jak My-Project, więc My_Project to rzeczywista nazwa modułu.)
finneycanhelp
6
Plik „MyProject-Swift.h” jest generowany pod adresem „$ (TARGET_TEMP_DIR) /../$ (PROJECT_NAME) .build / DerivedSources”. W końcu dodam to do ścieżek wyszukiwania nagłówka dla mojego celu testu jednostkowego.
gagarwal
1
@gagarwal Dodanie „$ (TARGET_TEMP_DIR) /../$ (PROJECT_NAME) .build / DerivedSources” do ścieżek wyszukiwania nagłówka dla mojego celu testu jednostkowego zadziałało. :) Zrób TAK odpowiedź z tego komentarza, a mogę przyznać ci nagrodę i wyjaśnić innym, jaka to wspaniała odpowiedź.
finneycanhelp

Odpowiedzi:

148

Plik „MyProject-Swift.h” jest generowany pod następującą ścieżką:

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

W końcu dodam to do ścieżek wyszukiwania nagłówka dla mojego celu testu jednostkowego.

Również, jak @hyouuu wskazał, że jest znanym problemem, mam nadzieję, że Apple zapewni dobre rozwiązanie na ich końcu. Dopóki nie uwierzę, musimy skorzystać z powyższego rozwiązania.

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

gagarwal
źródło
Działał jak urok!
DonnaLea
Niesamowite! Nie wiem, dlaczego Apple nie wspomina o tym jako obejściu. Jestem również zdumiony, że nie ma więcej osób, które mają ten problem. Każdy, kto ma istniejący projekt Obj-C, który stopniowo konwertuje rzeczy do Swift, napotka ten problem.
mluisbrown
@fabb nie jest prawdziwe - TARGET_NAME jest ogólnie czymś w rodzaju <Product Name> Testscelu testowego. Jednak to rozwiązanie nie działa, jeśli nazwa produktu zawiera spacje. Zobacz moją odpowiedź poniżej, aby znaleźć rozwiązanie.
Christopher Pickslay
2
Uwaga, musiałem dodać ścieżkę wyszukiwania i ustawić ją specjalnie jako „rekurencyjną”. Może to być oczywiste, ale nie zadziałało kilka razy, dopóki tego nie zrobiłem; Zakładam, że trafia wtedy do podfolderów.
Miro
1
W moim projekcie $(TARGET_TEMP_DIR)nie udało się. Skończyło się na używaniu$CONFIGURATION_TEMP_DIR/{myTargetName}.build/DerivedSources
Jordan Bondo
33

Dzięki @gagarwal za rozwiązanie tego problemu. W naszym przypadku nazwa produktu ma spację, która jest zwinięta $PROJECT_NAME, więc musiałem go na stałe zakodować. Ponadto, używając $CONFIGURATION_TEMP_DIRzamiast $TARGET_TEMP_DIR, można usunąć katalog nadrzędny ( ../) ze ścieżki. Rozwiązaniem jest więc dodanie następujących elementów do ścieżek wyszukiwania nagłówków w celu testowym:

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

Lub, jeśli Twój produkt nie zawiera spacji:

"$(CONFIGURATION_TEMP_DIR)/$(PROJECT_NAME).build/DerivedSources"
Christopher Pickslay
źródło
Rozwiązuje również problem testowania jednostek klas kodowania Core Data.
Elise van Looij
14

W informacjach o wydaniu Xcode 6.1 zauważyłem, że jest to znany problem ... znak ... Wyszukaj „-swift.h” w informacji o wydaniu https://developer.apple.com/library/content/documentation/Xcode /Conceptual/RN-Xcode-Archive/Chapters/xc6_release_notes.html

Testy napisane w Objective-C nie mogą zaimportować nagłówka interfejsów wygenerowanych przez Swift ($ (PRODUCT_MODULE_NAME) -Swift.h) dla celów aplikacji i dlatego nie mogą być używane do testowania kodu, który wymaga tego nagłówka.

Testy kodu Swift powinny być napisane w języku Swift. Testy napisane w Objective-C dla celów frameworka mogą uzyskać dostęp do interfejsów wygenerowanych przez Swift, importując moduł platformy przy użyciu @import FrameworkName ;. (16931027)

Zobacz obejście @ gagarwal, poniżej które DZIAŁA!

hyouuu
źródło
8

Myślę, że miałem podobny problem do twojego; tutaj była moja konfiguracja.

Miałem obiekt zdefiniowany w Swift:

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

Ta klasa została następnie użyta w inicjatorze obiektu Objective-C:

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

@interface Bar: NSObject

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

@end

To spowodowało, że moje testy jednostkowe Barnie były kompilowane, ponieważ MyProject-Swift.hnagłówek nie jest prawdziwy, a cel testu jednostkowego nie może go zobaczyć. Informacja o wydaniu udostępniona przez @hyouuu jest na miejscu - ale nie testuję klasy Swift, testuję klasę Objective-C!

Udało mi się to naprawić, zmieniając plik nagłówkowy, Baraby zamiast tego użyć odwołania do klasy do przodu:

// file Bar.h
@class Foo;

@interface Bar: NSObject

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

@end

I wtedy zawarte MyProject-Swift.hwBar.m , i wszystko działało - moje testy Objective-C obiekty napisane w Objective-C skompilowany poprawnie i nadal działa, i mógłbym napisać nowe testy dla obiektów w Swift Swift.

Mam nadzieję że to pomoże!

dpassage
źródło
Twoje rozwiązanie nie pozwala na korzystanie Fooz API wewnątrz Bar.m.
Yevhen Dubinin
2
Jasne, że tak - to właśnie zapewnia dołączenie MyProject-Swift.hdo .mpliku.
dpassage
4

Po wypróbowaniu wszystkiego, co mogłem znaleźć na ten temat, rzecz, która pracowała dla mnie był rzeczywiście uruchamiając aplikację choć wciąż pokazując „plik ModuleName-Swift.h nie znaleziono” błąd.

Odeszło, a moja aplikacja działa doskonale. Chyba powinienem był to wcześniej przemyśleć ... Błąd wraca , ale po uruchomieniu aplikacji zawsze znowu znika. Więc problem nie został dla mnie rozwiązany, ale na razie mogę kontynuować pracę nad innymi tematami ...

schrulnz
źródło
Tak, jest to rozwiązanie pozwalające wyeliminować błąd „nie znaleziono”.
Vijay Kumar Kanta
Nawet teraz kompilacja kończy się niepowodzeniem, podczas gdy samo uruchomienie aplikacji działa. Napraw to, Apple!
ScottyB
1

Prosty

@testable import MyProject

wykonał pracę za mnie.

niggeulimann
źródło
0

O dziwo, widziałem ten sam błąd, ale tylko podczas celowania w urządzenie (nie symulator). Przed uruchomieniem testu zobaczyłbym czerwony wykrzyknik obok instrukcji importu dla „MyProjectNameTests-Swift.h”.

Jednak zabawne jest to, że jeśli mimo wszystko uruchomię test (pomimo tego widocznego błędu kompilacji), to podczas fazy kompilacji, która nastąpi później, XCode faktycznie generuje plik „MyProjectNameTests-Swift.h”, a test działa dobrze!

Tak więc, przynajmniej w moim przypadku, ewidentnie tutaj nie było potrzeby innych rozwiązań, chociaż uważam, że też działają.

Powinienem również zauważyć, że wcześniej usunąłem mój katalog DerivedData, więc może jest to krok warty spróbowania.

CommaToast
źródło
-1

mySwiftClassTests(i wszystkie inne klasy Swift, których chcesz użyć w celu-c) należy zaznaczyć @objc:

@objc class MySwiftClassTests: XCTestCase
kto wie
źródło
-1

Nie mogłem go uruchomić, dodając ścieżkę do pliku wymienioną w innych odpowiedziach, ale zdałem sobie sprawę, że plik, w którym narzekał, nie był nawet testowany. Po prostu musiałem usunąć go z celu testowego za pomocą prawego paska bocznego narzędzi.

teradyl
źródło
-2

Dodanie pliku .swift do tego celu rozwiązuje problem.

Dmitry
źródło