iOS-运行Swift单元测试时找不到'MyProject-Swift.h'文件


94

我正在尝试为我的项目设置单元测试。这是现有的Objective-C应用程序,最近我添加了一个Swift类。我已经设置了“ MyProject-Swift.h”和Swift桥接文件(“ 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 2014年

1
@Coveloper-如何设置“ -Swift.h”文件的目标?它不是项目中的真实文件,而是由Xcode在构建时编译的。
JimmyJammed 2014年

1
这是对“我也收到未找到'MyProject-Swift.h'文件的错误。。”的更新。因此,现在两个目标(MyProject和MyProjectTests)都具有相同的产品模块名称。这很奇怪,但是它是测试目标,因此有效且风险低。我应该提到我的项目名称实际上类似于My-Project,因此My_Project是实际的模块名称。)
finneycanhelp 2015年

6
在“ $(TARGET_TEMP_DIR)/../$(PROJECT_NAME).build / DerivedSources”处生成“ MyProject-Swift.h”文件。我最终将其添加到我的单元测试目标的标题搜索路径中。
gagarwal

1
@gagarwal将“ $(TARGET_TEMP_DIR)/../$(PROJECT_NAME).build / DerivedSources”添加到我的单元测试目标的标题搜索路径中。:)从评论中提出一个SO答案,我可以奖励您,同时也让其他人清楚这是一个很好的答案。
finneycanhelp 2015年

Answers:


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

太棒了!不知道为什么苹果公司没有提到这是一种解决方法。还感到惊讶的是,没有更多的人遇到这个问题。拥有现有Obj-C项目并将其逐步转换为Swift的任何人都会遇到此问题。
mluisbrown 2015年

@fabb不正确-TARGET_NAME通常类似于<Product Name> Tests您的测试目标。但是,如果您的产品名称带有空格,则此解决方案不起作用。请参阅下面答案以获取解决方案。
Christopher Pickslay 2015年

2
请注意,我必须添加搜索路径,并将其专门设置为“递归”。可能很明显,但是直到我做到了几次,它才起作用。我假设它会进入子文件夹。
米罗(Miro)

1
对于我的项目,$(TARGET_TEMP_DIR)没有用。我使用了$CONFIGURATION_TEMP_DIR/{myTargetName}.build/DerivedSources
Jordan Bondo

32

感谢@gagarwal弄清楚了这一点。在我们的案例中,产品名称具有一个空格,该空格在中折叠$PROJECT_NAME,因此我不得不对其进行硬编码。此外,通过使用$CONFIGURATION_TEMP_DIR代替$TARGET_TEMP_DIR,您可以../从路径中删除父目录()。因此,解决方案是将以下内容添加到测试目标的标题搜索路径中:

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

或者,如果您的产品不包含空格:

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

还解决了对核心数据代码生成类进行单元测试的问题。
Elise van Looij

14

在Xcode 6.1发行说明中看到,这是一个已知问题... sign ...在发行说明中搜索“ -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编写的针对框架目标的测试可以通过使用@import FrameworkName;导入框架模块来访问Swift生成的接口。(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.hBar.m,和一切工作-我的Objective-C的测试对象写在正确的编译Objective-C和持续运行,并为Swift在斯威夫特对象我可以写新的测试。

希望这可以帮助!


您的解决方案不允许在Foo内部使用的API Bar.m
Yevhen Dubinin

2
当然它-这是包括MyProject-Swift.h.m文件中得到你。
dpassage 2014年

4

我尝试了一切后,我能找到的话题,这对我工作的事实际运行的应用程序,虽然它仍然显示错误“未找到模块名,Swift.h文件”。

它消失了,我的应用程序运行正常。我想我应该早些考虑...该错误不断出现,但是运行该应用程序后,它总是会再次消失。因此,对于我来说,该问题尚未真正解决,但我现在可以继续处理其他主题...


是的,这是解决“未找到”错误的解决方案。
维杰·库马尔·坎塔

即使是现在,仅在运行应用程序时构建仍会失败。解决这个问题,苹果!
ScottyB


0

奇怪的是,我看到了同样的错误,但仅在针对设备(而非模拟器)时才看到。在运行测试之前,我会在“ MyProjectNameTests-Swift.h”的导入语句旁边看到红色的感叹号。

但是,有趣的是,如果我继续进行测试(尽管存在明显的生成错误),则在此后发生的生成阶段中,XCode实际上确实会生成“ MyProjectNameTests-Swift.h”文件,并进行测试运行得很好!

因此,至少在我看来,这里不需要其他解决方案,尽管我相信它们也可以工作。

我还应该注意,在此之前我删除了DerivedData目录,因此也许这也是一个值得尝试的步骤。


-1

mySwiftClassTests(以及您要在Objective-C中使用的任何其他Swift类)都需要标记@objc

@objc class MySwiftClassTests: XCTestCase

-1

我无法通过添加其他答案中提到的文件路径来使其正常工作,但是我意识到甚至没有在测试它抱怨的文件。我只需要使用Right Utilities Side Bar将其从测试目标中删除。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.