iOS - ไม่พบไฟล์ 'MyProject-Swift.h' เมื่อเรียกใช้การทดสอบหน่วยสำหรับ Swift


95

ฉันกำลังพยายามตั้งค่าการทดสอบหน่วยสำหรับโครงการของฉัน เป็นแอป Objective-C ที่มีอยู่ซึ่งฉันเพิ่งเพิ่มคลาส Swift ไปหนึ่งคลาส ฉันได้ตั้งค่าไฟล์ 'MyProject-Swift.h' และ Swift Bridging (ทั้ง 'MyProject' และ 'MyProjectTest') และฉันสามารถสร้างและเรียกใช้แอปได้โดยใช้ทั้งรหัส Objective-C และ Swift

อย่างไรก็ตามตอนนี้ฉันต้องการเรียกใช้การทดสอบหน่วยในคลาส Swift ใหม่ ฉันตั้งค่าไฟล์ทดสอบและมีลักษณะดังต่อไปนี้:

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

}

ฉันได้รับข้อผิดพลาดนี้เมื่อเรียกใช้แอปเป็นการทดสอบ:

'MyProject-Swift.h' file not found

ฉันไม่แน่ใจว่าเหตุใดจึงเกิดขึ้นเฉพาะเมื่อพยายามเรียกใช้การทดสอบ ข้อเสนอแนะใด ๆ ?


1
เพิ่มการอัปเดตเกี่ยวกับสิ่งนี้หรือไม่ ฉันกำลังเจอปัญหาเดียวกัน ...
hyouuu

1
@Coveloper - คุณจะตั้งเป้าหมายของไฟล์ '-Swift.h' ได้อย่างไร? ไม่ใช่ไฟล์จริงที่อยู่ในโปรเจ็กต์ แต่คอมไพล์โดย Xcode ในบิลด์แทน
JimmyJammed

1
นี่คือการอัปเดตสำหรับ "ฉันยังได้รับไฟล์" MyProject-Swift.h "ที่ไม่พบข้อผิดพลาด .. ดังนั้นตอนนี้ทั้งสองเป้าหมาย (MyProject และ MyProjectTests) มีชื่อโมดูลผลิตภัณฑ์เหมือนกัน มันแปลก แต่ใช้งานได้และมีความเสี่ยงต่ำเนื่องจากเป็นเป้าหมายการทดสอบ ฉันควรพูดถึงว่าชื่อโครงการของฉันเหมือน My-Project ดังนั้น My_Project จึงเป็นชื่อโมดูลที่แท้จริง)
finneycanhelp

6
ไฟล์ "MyProject-Swift.h" ถูกสร้างขึ้นที่ "$ (TARGET_TEMP_DIR) /../$ (PROJECT_NAME) .build / DerivedSources" ฉันจบลงด้วยการเพิ่มสิ่งนี้ในเส้นทางการค้นหาส่วนหัวสำหรับเป้าหมายการทดสอบหน่วยของฉัน
gagarwal

1
@gagarwal การเพิ่ม "$ (TARGET_TEMP_DIR) /../$ (PROJECT_NAME) .build / DerivedSources" ลงในเส้นทางการค้นหาส่วนหัวสำหรับเป้าหมายการทดสอบหน่วยของฉันได้ผล :) ให้คำตอบ SO จากความคิดเห็นนั้นและฉันสามารถมอบรางวัลให้กับคุณรวมทั้งชี้แจงให้คนอื่นเห็นว่าคำตอบที่ยอดเยี่ยมคืออะไร
finneycanhelp

คำตอบ:


148

ไฟล์ "MyProject-Swift.h"ถูกสร้างขึ้นตามเส้นทางต่อไปนี้:

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

ฉันจบลงด้วยการเพิ่มสิ่งนี้ในเส้นทางการค้นหาส่วนหัวสำหรับเป้าหมายการทดสอบหน่วยของฉัน

เช่นเดียวกับที่ @hyouuu ชี้ให้เห็นถึงปัญหาที่ทราบแล้วหวังว่า Apple จะให้วิธีแก้ปัญหาที่ดีในตอนท้าย จนกว่าฉันจะเชื่อว่าเราจำเป็นต้องใช้วิธีแก้ปัญหาข้างต้นนี้

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


ทำงานอย่างมีเสน่ห์!
DonnaLea

สุดยอด! ไม่รู้ว่าทำไม Apple ถึงไม่พูดถึงเรื่องนี้เป็นวิธีแก้ปัญหา ยังประหลาดใจที่ไม่มีคนพบปัญหานี้มากขึ้น ใครก็ตามที่มีโครงการ Obj-C ที่มีอยู่แล้วที่แปลงสิ่งต่างๆเป็น Swift จะค่อยๆแก้ไขปัญหานี้
mluisbrown

@fabb ไม่เป็นความจริง - โดยทั่วไป TARGET_NAME จะเหมือนกับ<Product Name> Testsในเป้าหมายการทดสอบของคุณ อย่างไรก็ตามวิธีนี้ใช้ไม่ได้หากชื่อผลิตภัณฑ์ของคุณมีช่องว่าง ดูคำตอบของฉันด้านล่างสำหรับวิธีแก้ปัญหา
Christopher Pickslay

2
เพียงทราบว่าฉันต้องเพิ่มเส้นทางการค้นหาและตั้งค่าเป็น "เรียกซ้ำ" โดยเฉพาะ อาจจะชัดเจน แต่ก็ไม่ได้ผลสักสองสามครั้งจนกว่าฉันจะทำอย่างนั้น ฉันถือว่ามันเข้าสู่โฟลเดอร์ย่อยแล้ว
Miro

1
สำหรับโครงการของฉัน$(TARGET_TEMP_DIR)ไม่ได้ผล ฉันใช้$CONFIGURATION_TEMP_DIR/{myTargetName}.build/DerivedSources
Jordan Bondo

33

ขอบคุณ @gagarwal สำหรับการหาสิ่งนี้ ในกรณีของเราชื่อผลิตภัณฑ์มีช่องว่างซึ่งยุบเข้าไป$PROJECT_NAMEฉันจึงต้องฮาร์ดโค้ด นอกจากนี้โดยใช้$CONFIGURATION_TEMP_DIRแทนคุณ$TARGET_TEMP_DIRสามารถลบไดเร็กทอรีหลัก ( ../) ออกจากพา ธ ดังนั้นวิธีแก้ปัญหาคือเพิ่มสิ่งต่อไปนี้ลงใน Header Search Paths ในเป้าหมายการทดสอบของคุณ:

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

หรือหากผลิตภัณฑ์ของคุณไม่มีช่องว่าง:

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

ยังแก้ปัญหาการทดสอบหน่วย Core Data codegen คลาส
Elise van Looij

14

เห็นในบันทึกประจำรุ่น Xcode 6.1 ว่านี่เป็นปัญหาที่ทราบ ... ลงชื่อ ... ค้นหา "-swift.h" ในบันทึกประจำรุ่นhttps://developer.apple.com/library/content/documentation/Xcode /Conceptual/RN-Xcode-Archive/Chapters/xc6_release_notes.html

การทดสอบที่เขียนใน Objective-C ไม่สามารถนำเข้าส่วนหัวของอินเทอร์เฟซที่สร้างโดย Swift ($ (PRODUCT_MODULE_NAME) -Swift.h) สำหรับแอปพลิเคชันเป้าหมายดังนั้นจึงไม่สามารถใช้ทดสอบโค้ดที่ต้องใช้ส่วนหัวนี้

การทดสอบโค้ด Swift ควรเขียนด้วย Swift การทดสอบที่เขียนใน Objective-C สำหรับเป้าหมายเฟรมเวิร์กสามารถเข้าถึงอินเทอร์เฟซที่สร้างโดย Swift ได้โดยการนำเข้าโมดูลกรอบงานโดยใช้ @import FrameworkName; (16931027)

โปรดดูวิธีแก้ปัญหาของ @gagarwal ด้านล่างซึ่งได้ผล!


8

ฉันมีปัญหาคล้าย ๆ กับคุณฉันคิดว่า; นี่คือการตั้งค่าของฉัน

ฉันมีวัตถุที่กำหนดไว้ใน Swift:

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

จากนั้นคลาสนี้ถูกใช้ในการเริ่มต้นของวัตถุ Objective-C:

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

@interface Bar: NSObject

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

@end

สิ่งนี้ทำให้การทดสอบหน่วยของฉันBarไม่สามารถรวบรวมได้เนื่องจากMyProject-Swift.hส่วนหัวไม่ใช่ของจริงและเป้าหมายการทดสอบหน่วยไม่สามารถมองเห็นได้ บันทึกประจำรุ่นที่แบ่งปันโดย @hyouuu ตรงประเด็น - แต่ฉันไม่ได้ทดสอบคลาส Swift ฉันกำลังทดสอบคลาส Objective-C!

ฉันสามารถแก้ไขได้โดยเปลี่ยนไฟล์ส่วนหัวBarเพื่อใช้การอ้างอิงคลาสส่งต่อแทน:

// file Bar.h
@class Foo;

@interface Bar: NSObject

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

@end

จากนั้นฉันรวมไว้MyProject-Swift.hในBar.mและทุกอย่างก็ใช้ได้ - การทดสอบ Objective-C ของฉันที่เขียนใน Objective-C รวบรวมอย่างถูกต้องและทำงานต่อไปและฉันสามารถเขียนการทดสอบใหม่สำหรับวัตถุ Swift ใน Swift ได้

หวังว่านี่จะช่วยได้!


วิธีการแก้ปัญหาของคุณไม่อนุญาตให้ใช้Foo's Bar.mภายใน
Yevhen Dubinin

2
แน่นอนว่านั่นคือสิ่งที่รวมMyProject-Swift.hอยู่ใน.mไฟล์ทำให้คุณได้รับ
dpassage

4

หลังจากที่ฉันลองทำทุกอย่างที่ฉันพบในหัวข้อสิ่งที่ได้ผลสำหรับฉันคือการเรียกใช้แอพจริงแม้ว่ามันจะยังคงแสดงข้อผิดพลาด 'ไม่พบไฟล์' ModuleName-Swift.h '

มันหายไปและแอปของฉันทำงานได้ดีอย่างสมบูรณ์ ผมคิดว่าผมควรจะได้พิจารณาแล้วเห็นว่าก่อนหน้านี้ ... ความผิดพลาดช่วยให้กลับมาแต่หลังจากใช้ app มันก็แค่ออกไปอีกครั้ง ดังนั้นปัญหาจึงไม่ได้รับการแก้ไขสำหรับฉันจริงๆ แต่ฉันสามารถทำงานในหัวข้ออื่น ๆ ต่อได้ในตอนนี้ ...


ใช่วิธีแก้ปัญหาเพื่อให้ข้อผิดพลาด "ไม่พบ" หายไป
Vijay Kumar Kanta

แม้ตอนนี้ Build จะล้มเหลวในขณะที่ใช้งานแอป แก้ไขปัญหานี้ Apple!
ScottyB


0

น่าแปลกที่ฉันเห็นข้อผิดพลาดเดียวกันนี้ แต่เฉพาะเมื่อกำหนดเป้าหมายอุปกรณ์ (ไม่ใช่เครื่องจำลอง) ก่อนดำเนินการทดสอบฉันจะเห็นเครื่องหมายอัศเจรีย์สีแดงถัดจากคำสั่งนำเข้าสำหรับ "MyProjectNameTests-Swift.h"

อย่างไรก็ตามสิ่งที่น่าตลกก็คือถ้าฉันดำเนินการทดสอบต่อไป (แม้จะมีข้อผิดพลาดในการสร้างที่ชัดเจนก็ตาม) ในระหว่างขั้นตอนการสร้างที่เกิดขึ้นหลังจากนั้น XCode จะสร้างไฟล์ "MyProjectNameTests-Swift.h" และการทดสอบ วิ่งได้ดี!

ดังนั้นอย่างน้อยในกรณีของฉันไม่จำเป็นต้องมีวิธีแก้ปัญหาอื่น ๆ ที่นี่เห็นได้ชัดแม้ว่าฉันเชื่อว่าพวกเขาทำงาน

ฉันควรสังเกตด้วยว่าฉันลบไดเร็กทอรี DerivedData ของฉันก่อนหน้านี้ดังนั้นอาจเป็นขั้นตอนที่ควรลอง


-1

mySwiftClassTests(และคลาสที่รวดเร็วอื่น ๆ ที่คุณต้องการใช้ในวัตถุประสงค์ -c) จะต้องทำเครื่องหมาย@objc:

@objc class MySwiftClassTests: XCTestCase

-1

ฉันไม่สามารถใช้งานได้โดยการเพิ่ม filepath ที่กล่าวถึงโดยคำตอบอื่น ๆ แต่ฉันรู้ว่าไฟล์ที่ถูกร้องเรียนนั้นไม่ได้รับการทดสอบ ฉันต้องลบออกจากเป้าหมายการทดสอบโดยใช้แถบด้านข้างยูทิลิตี้ด้านขวา


-2

การเพิ่มไฟล์. swift ไปยังเป้าหมายนั้นจะช่วยแก้ปัญหาได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.