iOS - Không tìm thấy tệp 'MyProject-Swift.h' khi chạy Bài kiểm tra đơn vị cho Swift


94

Tôi đang cố gắng thiết lập Unit Testing cho dự án của mình. Nó là một ứng dụng Objective-C hiện có, mà gần đây tôi đã thêm một lớp Swift vào. Tôi đã thiết lập các tệp 'MyProject-Swift.h' và Swift Bridging (cả 'MyProject' và 'MyProjectTest') và tôi có thể xây dựng và chạy ứng dụng tốt bằng cả Objective-C và Swift code.

Tuy nhiên, bây giờ tôi muốn chạy một số Bài kiểm tra đơn vị trên lớp Swift mới. Tôi thiết lập tệp thử nghiệm của mình và nó trông giống như sau:

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

}

Tôi gặp lỗi này khi chạy ứng dụng dưới dạng Kiểm tra:

'MyProject-Swift.h' file not found

Tôi không chắc tại sao điều này chỉ xảy ra khi cố gắng chạy Kiểm tra. Bất kỳ đề xuất?


1
Thêm cập nhật về điều này? Tôi đang phải đối mặt với cùng một vấn đề ...
hyouuu

1
@Coveloper - Làm cách nào để bạn có thể đặt mục tiêu cho tệp '-Swift.h'? Nó không phải là một tệp thực nằm trong dự án, mà thay vào đó được biên dịch bởi Xcode khi xây dựng.
JimmyJammed

1
Đây là bản cập nhật cho "Tôi cũng nhận được lỗi không tìm thấy tệp 'MyProject-Swift.h' .." ở trên nhận xét: Tôi đã tìm thấy giải pháp thay thế bằng cách đặt Tên mô-đun sản phẩm của mục tiêu MyProjectTests thành MyProject thay vì MyProjectTests. Vì vậy, bây giờ cả hai mục tiêu (MyProject và MyProjectTests) có cùng Tên mô-đun sản phẩm. Điều đó thật kỳ lạ, nhưng nó hoạt động và ít rủi ro vì nó là mục tiêu Thử nghiệm. Tôi nên đề cập đến cái tên dự án của tôi là thực sự như Mỹ-Dự án do đó My_Project là tên mô-đun thực tế).
finneycanhelp

6
Tệp "MyProject-Swift.h" được tạo tại "$ (TARGET_TEMP_DIR) /../$ (PROJECT_NAME) .build / DerivedSources". Tôi kết thúc việc thêm điều này vào Đường dẫn Tìm kiếm Tiêu đề cho mục tiêu Kiểm tra Đơn vị của tôi.
gagarwal

1
@gagarwal Thêm "$ (TARGET_TEMP_DIR) /../$ (PROJECT_NAME) .build / DerivedSources" vào Đường dẫn Tìm kiếm Tiêu đề cho mục tiêu Kiểm tra Đơn vị của tôi đã hoạt động. :) Tạo một câu trả lời SO từ nhận xét đó và tôi có thể trao tiền thưởng cho bạn cộng với việc làm rõ cho người khác câu trả lời tuyệt vời đó là gì.
finneycanhelp

Câu trả lời:


148

Tệp "MyProject-Swift.h" được tạo theo đường dẫn sau:

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

Tôi kết thúc việc thêm điều này vào Đường dẫn Tìm kiếm Tiêu đề cho mục tiêu Kiểm tra Đơn vị của tôi.

Cũng như @hyouuu đã chỉ ra về vấn đề đã biết, hy vọng Apple sẽ cung cấp một số giải pháp tốt vào cuối của họ. Cho đến khi tôi tin rằng chúng ta cần sử dụng giải pháp trên.

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


Làm việc như người ở!
DonnaLea

Tuyệt vời! Không biết tại sao Apple không đề cập đến điều này như một giải pháp. Cũng ngạc nhiên rằng không có nhiều người gặp vấn đề này. Bất kỳ ai có dự án Obj-C hiện tại đang chuyển đổi mọi thứ sang Swift dần dần sẽ gặp phải vấn đề này.
mluisbrown

@fabb không đúng - TARGET_NAME thường giống như <Product Name> Teststrong mục tiêu thử nghiệm của bạn. Tuy nhiên, giải pháp này không hoạt động nếu tên sản phẩm của bạn có khoảng trắng. Xem câu trả lời của tôi dưới đây để có giải pháp.
Christopher Pickslay

2
Chỉ cần một lưu ý, tôi đã phải thêm Đường dẫn tìm kiếm và đặt cụ thể là "đệ quy". Có thể là hiển nhiên, nhưng nó đã không hoạt động một vài lần cho đến khi tôi làm điều đó; Tôi cho rằng nó sẽ đi vào các thư mục con.
Miro

1
Đối với dự án của tôi, $(TARGET_TEMP_DIR)không hoạt động. Tôi vết thương lên sử dụng$CONFIGURATION_TEMP_DIR/{myTargetName}.build/DerivedSources
Jordan Bondo

32

Cảm ơn @gagarwal vì đã tìm ra điều này. Trong trường hợp của chúng tôi, tên sản phẩm có một khoảng trắng, được thu gọn vào trong $PROJECT_NAME, vì vậy tôi đã phải đánh mã nó. Ngoài ra, bằng cách sử dụng $CONFIGURATION_TEMP_DIRthay thế $TARGET_TEMP_DIR, bạn có thể xóa thư mục mẹ ( ../) khỏi đường dẫn. Vì vậy, giải pháp là thêm phần sau vào Đường dẫn tìm kiếm tiêu đề trong mục tiêu thử nghiệm của bạn:

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

Hoặc, nếu sản phẩm của bạn không chứa khoảng trắng:

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

Đồng thời giải quyết vấn đề của các lớp codegen Core Data thử nghiệm đơn vị.
Elise van Looij

14

Đã thấy trong ghi chú phát hành Xcode 6.1, rằng đây là một vấn đề đã biết ... ký ... Tìm kiếm "-swift.h" trong ghi chú phát hành https://developer.apple.com/library/content/documentation/Xcode /Conceptual/RN-Xcode-Archive/Chapter/xc6_release_notes.html

Các bài kiểm tra được viết bằng Objective-C không thể nhập tiêu đề giao diện được tạo bằng Swift ($ (PRODUCT_MODULE_NAME) -Swift.h) cho các mục tiêu ứng dụng và do đó không thể được sử dụng để kiểm tra mã yêu cầu tiêu đề này.

Các bài kiểm tra cho mã Swift nên được viết bằng Swift. Các bài kiểm tra được viết bằng Objective-C cho các mục tiêu khung có thể truy cập các giao diện do Swift tạo ra bằng cách nhập mô-đun khung bằng cách sử dụng @import FrameworkName ;. (16931027)

Vui lòng xem cách giải quyết của @ gagarwal bên dưới mà HOẠT ĐỘNG!


8

Tôi đã gặp vấn đề tương tự như của bạn, tôi nghĩ vậy; đây là thiết lập của tôi.

Tôi đã có một đối tượng được định nghĩa trong Swift:

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

Lớp này sau đó được sử dụng trong trình khởi tạo của một đối tượng Objective-C:

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

@interface Bar: NSObject

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

@end

Điều này khiến các bài kiểm tra đơn vị của tôi Barkhông được biên dịch, vì MyProject-Swift.htiêu đề không có thật và mục tiêu kiểm tra đơn vị không thể nhìn thấy nó. Ghi chú phát hành do @hyouuu chia sẻ là đúng - nhưng tôi không thử nghiệm một lớp Swift, tôi đang thử nghiệm một lớp Objective-C!

Tôi đã có thể sửa lỗi này bằng cách thay đổi tệp tiêu đề Barđể sử dụng tham chiếu lớp chuyển tiếp thay thế:

// file Bar.h
@class Foo;

@interface Bar: NSObject

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

@end

Sau đó tôi đưa MyProject-Swift.hvào Bar.mvà mọi thứ đều hoạt động - các bài kiểm tra của tôi về các đối tượng Objective-C được viết bằng Objective-C được biên dịch đúng cách và tiếp tục chạy, và tôi có thể viết các bài kiểm tra mới cho các đối tượng trong Swift.

Hi vọng điêu nay co ich!


Giải pháp của bạn không cho phép sử dụng FooAPI của bên trong Bar.m.
Yevhen Dubinin

2
Chắc chắn là có - đó là những gì bao gồm MyProject-Swift.htrong .mtệp giúp bạn.
dpassage

4

Sau khi tôi đã cố gắng ra tất cả mọi thứ tôi có thể tìm về chủ đề này, điều mà làm việc cho tôi đã thực sự chạy ứng dụng mặc dù nó vẫn cho thấy sự 'modulename-Swift.h tập tin không tìm thấy' lỗi.

Nó đã biến mất và ứng dụng của tôi hoạt động hoàn toàn tốt. Tôi đoán tôi nên xem xét điều đó sớm hơn ... Lỗi tiếp tục quay trở lại , nhưng sau khi chạy ứng dụng, nó luôn biến mất một lần nữa. Vì vậy, vấn đề vẫn chưa thực sự được giải quyết đối với tôi, nhưng tôi có thể tiếp tục làm việc với các chủ đề khác vào lúc này ...


Có, đó là một giải pháp để loại bỏ lỗi "không tìm thấy" đó.
Vijay Kumar Kanta

Ngay cả bây giờ, Build không thành công trong khi chỉ chạy ứng dụng hoạt động. Hãy sửa lỗi này, Apple!
ScottyB

1

Một đơn giản

@testable import MyProject

đã hoàn thành công việc cho tôi.


0

Thật kỳ lạ, tôi đã gặp lỗi tương tự, nhưng chỉ khi nhắm mục tiêu một thiết bị (không phải trình mô phỏng). Trước khi chạy thử nghiệm, tôi sẽ thấy dấu chấm than màu đỏ bên cạnh câu lệnh nhập cho "MyProjectNameTests-Swift.h".

Tuy nhiên, điều buồn cười là, nếu tôi vẫn tiếp tục và chạy thử nghiệm (bất chấp lỗi xây dựng rõ ràng này), thì trong giai đoạn xây dựng xảy ra sau đó, XCode thực sự tạo tệp "MyProjectNameTests-Swift.h" và kiểm tra chạy tốt!

Vì vậy, ít nhất trong trường hợp của tôi, rõ ràng là không cần các giải pháp khác ở đây, mặc dù tôi tin rằng chúng cũng có hiệu quả.

Tôi cũng nên lưu ý rằng tôi đã xóa thư mục DerivedData của mình trước đó, vì vậy có lẽ đó là một bước cũng đáng thử.


-1

mySwiftClassTests(và bất kỳ lớp nhanh nào khác mà bạn muốn sử dụng trong mục tiêu-c) cần được đánh dấu @objc:

@objc class MySwiftClassTests: XCTestCase

-1

Tôi không thể làm cho nó hoạt động bằng cách thêm đường dẫn tệp đó được đề cập bởi các câu trả lời khác, nhưng tôi nhận ra tệp nơi nó đang phàn nàn thậm chí còn chưa được kiểm tra. Tôi chỉ phải xóa nó khỏi mục tiêu thử nghiệm bằng Thanh bên Tiện ích Bên phải.


-2

Thêm tệp .swift vào mục tiêu đó sẽ khắc phục sự cố trên đó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.