iOS - File 'MyProject-Swift.h' tidak ditemukan saat menjalankan Tes Unit untuk Swift

94

Saya mencoba menyiapkan Pengujian Unit untuk proyek saya. Ini adalah aplikasi Objective-C yang sudah ada, yang baru-baru ini saya tambahkan satu kelas Swift. Saya telah menyiapkan file 'MyProject-Swift.h' dan Swift Bridging (keduanya 'MyProject' dan 'MyProjectTest') dan saya dapat membangun dan menjalankan aplikasi dengan baik menggunakan kode Objective-C dan Swift.

Namun, sekarang saya ingin menjalankan beberapa Pengujian Unit di kelas Swift baru. Saya menyiapkan file pengujian saya dan terlihat seperti berikut:

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

}

Saya mendapatkan kesalahan ini saat menjalankan aplikasi sebagai Test:

'MyProject-Swift.h' file not found

Saya tidak yakin mengapa ini terjadi hanya ketika mencoba menjalankan Tes. Ada saran?

JimmyJammed
sumber
1
Tambahkan pembaruan tentang ini? Saya menghadapi masalah yang sama ...
hyouuu
1
@Coveloper - Bagaimana Anda dapat menetapkan target untuk file '-Swift.h'? Ini bukan file nyata yang ada dalam proyek, tetapi dikompilasi oleh Xcode saat pembuatan.
JimmyJammed
1
Berikut ini pembaruan untuk komentar "Saya juga mendapatkan file 'MyProject-Swift.h' tidak ditemukan .." di atas: Saya menemukan solusi dengan menyetel Nama Modul Produk target MyProjectTests ke MyProject sebagai lawan dari MyProjectTests. Jadi, sekarang kedua target (MyProject dan MyProjectTests) memiliki Nama Modul Produk yang sama. Itu aneh, tetapi berhasil dan berisiko rendah karena itu adalah target Tes. Saya harus menyebutkan bahwa nama proyek saya sebenarnya seperti Proyek-Saya sehingga My_Project adalah nama modul yang sebenarnya.)
finneycanhelp
6
File "MyProject-Swift.h" dibuat di "$ (TARGET_TEMP_DIR) /../$ (PROJECT_NAME) .build / DerivedSources". Saya akhirnya menambahkan ini ke Jalur Pencarian Header untuk target Tes Unit saya.
gagarwal
1
@gagarwal Menambahkan "$ (TARGET_TEMP_DIR) /../$ (PROJECT_NAME) .build / DerivedSources" ke Header Search Paths untuk target Unit Test saya berhasil. :) Buatlah jawaban BEGITU dari komentar itu dan saya dapat memberi Anda hadiah plus menjelaskan kepada orang lain betapa hebatnya jawaban itu.
finneycanhelp

Jawaban:

148

File "MyProject-Swift.h" dibuat di jalur berikut:

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

Saya akhirnya menambahkan ini ke Jalur Pencarian Header untuk target Tes Unit saya.

Juga seperti yang ditunjukkan @hyouuu tentang menjadi masalah yang diketahui, semoga Apple akan memberikan solusi yang baik pada akhirnya. Sampai saya yakin kita perlu menggunakan solusi di atas.

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

gagarwal
sumber
Bekerja seperti pesona!
DonnaLea
Hebat! Tidak tahu mengapa Apple tidak menyebutkan ini sebagai solusi. Juga kagum karena tidak ada lagi orang yang mengalami masalah ini. Siapa pun dengan proyek Obj-C yang sudah ada yang mengubah sesuatu ke Swift secara bertahap akan terkena masalah ini.
mluisbrown
@fabb tidak benar - TARGET_NAME pada umumnya mirip <Product Name> Testsdengan target pengujian Anda. Namun solusi ini tidak berfungsi jika nama produk Anda memiliki spasi. Lihat jawaban saya di bawah ini untuk solusinya.
Christopher Pickslay
2
Sekadar catatan, saya harus menambahkan Jalur Pencarian, dan mengaturnya sebagai "rekursif" secara khusus. Mungkin sudah jelas, tetapi tidak berhasil beberapa kali sampai saya melakukannya; Saya berasumsi kalau itu masuk ke subfolder.
Miro
1
Untuk proyek saya, $(TARGET_TEMP_DIR)tidak berhasil. Saya akhirnya menggunakan$CONFIGURATION_TEMP_DIR/{myTargetName}.build/DerivedSources
Jordan Bondo
32

Terima kasih kepada @gagarwal untuk memecahkan masalah ini. Dalam kasus kami, nama produk memiliki spasi, yang diciutkan $PROJECT_NAME, jadi saya harus membuat kode keras. Selain itu, dengan menggunakan $CONFIGURATION_TEMP_DIRalih-alih $TARGET_TEMP_DIR, Anda dapat menghapus direktori induk ( ../) dari jalur. Jadi solusinya adalah dengan menambahkan yang berikut ini ke Jalur Pencarian Header di target pengujian Anda:

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

Atau, jika produk Anda tidak mengandung spasi:

"$(CONFIGURATION_TEMP_DIR)/$(PROJECT_NAME).build/DerivedSources"
Christopher Pickslay
sumber
Juga memecahkan masalah kelas codegen Data Inti pengujian unit.
Elise van Looij
14

Lihat di catatan rilis Xcode 6.1, bahwa ini adalah masalah yang diketahui ... tanda ... Cari "-swift.h" di catatan rilis https://developer.apple.com/library/content/documentation/Xcode /Conceptual/RN-Xcode-Archive/Chapters/xc6_release_notes.html

Pengujian yang ditulis dalam Objective-C tidak dapat mengimpor header antarmuka yang dibuat Swift ($ (PRODUCT_MODULE_NAME) -Swift.h) untuk target aplikasi, dan oleh karena itu tidak dapat digunakan untuk menguji kode yang memerlukan header ini.

Pengujian untuk kode Swift harus ditulis dalam Swift. Pengujian yang ditulis dalam Objective-C untuk target kerangka kerja dapat mengakses antarmuka yang dihasilkan Swift dengan mengimpor modul kerangka kerja menggunakan @import FrameworkName ;. (16931027)

Silakan lihat solusi @ gagarwal di bawah ini yang BEKERJA!

hyouuu
sumber
8

Saya memiliki masalah serupa dengan Anda, saya pikir; inilah pengaturan saya.

Saya memiliki objek yang ditentukan di Swift:

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

Kelas ini kemudian digunakan dalam penginisialisasi objek Objective-C:

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

@interface Bar: NSObject

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

@end

Ini membuat pengujian unit saya Bartidak dapat dikompilasi, karena MyProject-Swift.hheader tidak nyata dan target pengujian unit tidak dapat melihatnya. Catatan rilis yang dibagikan oleh @hyouuu ada benarnya - tetapi saya tidak menguji kelas Swift, saya sedang menguji kelas Objective-C!

Saya dapat memperbaiki ini dengan mengubah file header untuk Barmenggunakan referensi kelas maju sebagai gantinya:

// file Bar.h
@class Foo;

@interface Bar: NSObject

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

@end

Saya kemudian dimasukkan MyProject-Swift.hdalamBar.m , dan semuanya bekerja - tes saya Objective-C benda ditulis di Objective-C disusun dengan baik dan terus berjalan, dan aku bisa menulis tes baru untuk Swift objek di Swift.

Semoga ini membantu!

dpassage
sumber
Solusi Anda tidak mengizinkan untuk menggunakan FooAPI di dalam Bar.m.
Yevhen Dubinin
2
Tentu itu terjadi - itulah yang termasuk MyProject-Swift.hdalam .mfile membuat Anda.
dpassage
4

Setelah saya mencoba semua yang dapat saya temukan tentang topik tersebut, hal yang berhasil bagi saya sebenarnya adalah menjalankan aplikasi meskipun masih menampilkan kesalahan 'ModuleName-Swift.h file not found'.

Itu hilang dan aplikasi saya berfungsi dengan baik. Saya kira saya seharusnya mempertimbangkan itu sebelumnya ... Kesalahan terus muncul , tetapi setelah menjalankan aplikasi itu selalu hilang lagi. Jadi masalah ini tidak benar-benar terpecahkan untuk saya, tetapi saya dapat terus mengerjakan topik lain untuk saat ini ...

schrulnz.dll
sumber
Ya, ini adalah solusi untuk menghilangkan kesalahan "tidak ditemukan".
Vijay Kumar Kanta
Bahkan sekarang, Build gagal saat menjalankan aplikasi saja. Perbaiki ini, Apple!
ScottyB
1

Sederhana

@testable import MyProject

telah melakukan pekerjaan untuk saya.

niggeulimann
sumber
0

Anehnya, saya melihat kesalahan yang sama, tetapi hanya saat menargetkan perangkat (bukan simulator). Sebelum menjalankan pengujian, saya akan melihat tanda seru merah di sebelah pernyataan impor untuk "MyProjectNameTests-Swift.h".

Namun, lucunya, jika saya tetap melanjutkan dan menjalankan pengujian (terlepas dari kesalahan build yang jelas ini), maka selama fase build yang terjadi setelahnya, XCode sebenarnya menghasilkan file "MyProjectNameTests-Swift.h", dan pengujian berjalan dengan baik!

Jadi, setidaknya dalam kasus saya, tidak diperlukan solusi lain di sini, jelas, meskipun saya yakin mereka juga berhasil.

Saya juga harus mencatat bahwa saya menghapus direktori DerivedData saya sebelum ini, jadi mungkin itu langkah yang juga patut dicoba.

CommaToast
sumber
-1

mySwiftClassTests(dan kelas swift lainnya yang ingin Anda gunakan di objektif-c) perlu ditandai @objc:

@objc class MySwiftClassTests: XCTestCase
siapa tahu
sumber
-1

Saya tidak bisa membuatnya berfungsi dengan menambahkan jalur file yang disebutkan oleh jawaban lain, tetapi saya menyadari file yang dikeluhkannya bahkan tidak diuji. Saya hanya harus menghapusnya dari target pengujian menggunakan Bar Sisi Utilitas Kanan.

teradyl
sumber
-2

Menambahkan file .swift ke target itu akan memperbaiki masalah di dalamnya.

Dmitry
sumber