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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26473058/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 03:16:37  来源:igfitidea点击:

iOS - 'MyProject-Swift.h' file not found when running Unit Tests for Swift

iosunit-testingswiftheader

提问by JimmyJammed

I am trying to setup Unit Testing for my project. It is an existing Objective-C app, that I have recently added one Swift class to. I have setup the 'MyProject-Swift.h' and Swift Bridging files (both 'MyProject' and 'MyProjectTest') and I am able to build and run the app just fine using both Objective-C and Swift code.

我正在尝试为我的项目设置单元测试。这是一个现有的 Objective-C 应用程序,我最近添加了一个 Swift 类。我已经设置了“MyProject-Swift.h”和 Swift 桥接文件(“MyProject”和“MyProjectTest”),并且我能够使用 Objective-C 和 Swift 代码很好地构建和运行应用程序。

However, now I want to run some Unit Tests on the new Swift class. I setup my test file and it looks like the following:

但是,现在我想在新的 Swift 类上运行一些单元测试。我设置了我的测试文件,它看起来像下面这样:

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

}

I get this error when running the app as Test:

将应用程序作为测试运行时出现此错误:

'MyProject-Swift.h' file not found

I am not sure why this happens only when trying to run the Tests. Any suggestions?

我不确定为什么只有在尝试运行测试时才会发生这种情况。有什么建议?

回答by gagarwal

"MyProject-Swift.h"file is generated at following path:

“MyProject-Swift.h”文件在以下路径生成:

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

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

I end up adding this to Header Search Paths for my Unit Test target.

我最终将此添加到我的单元测试目标的标题搜索路径中。

Also as @hyouuu pointed out about being the known issue, hopefully Apple will provide some good solution at their end. Until I believe we need to use this above solution.

同样正如@hyouuu 指出的已知问题一样,希望 Apple 最终能提供一些好的解决方案。直到我相信我们需要使用上述解决方案。

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

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

回答by Christopher Pickslay

Thanks to @gagarwal for figuring this out. In our case the product name has a space, which is collapsed in $PROJECT_NAME, so I had to hard code it. Additionally, by using $CONFIGURATION_TEMP_DIRinstead of $TARGET_TEMP_DIR, you can remove the parent directory (../) from the path. So the solution is to add the following to the Header Search Paths in your test target:

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

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

Or, if your product does not contain spaces:

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

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

回答by hyouuu

Saw in the Xcode 6.1 release note, that this is a known issue... sign... Search for "-swift.h" in the release note https://developer.apple.com/library/content/documentation/Xcode/Conceptual/RN-Xcode-Archive/Chapters/xc6_release_notes.html

在 Xcode 6.1 发行说明中看到,这是一个已知问题...签名...在发行说明中搜索“-swift.h” https://developer.apple.com/library/content/documentation/Xcode /Conceptual/RN-Xcode-Archive/Chapters/xc6_release_notes.html

Tests written in Objective-C cannot import the Swift generated interfaces header ($(PRODUCT_MODULE_NAME)-Swift.h) for application targets, and therefore cannot be used to test code that requires this header.

Tests for Swift code should be written in Swift. Tests written in Objective-C for framework targets can access the Swift generated interfaces by importing the framework module using @import FrameworkName;. (16931027)

用 Objective-C 编写的测试不能为应用程序目标导入 Swift 生成的接口头文件 ($(PRODUCT_MODULE_NAME)-Swift.h),因此不能用于测试需要这个头文件的代码。

Swift 代码的测试应该用 Swift 编写。用 Objective-C 为框架目标编写的测试可以通过使用 @import FrameworkName; 导入框架模块来访问 Swift 生成的接口。(16931027)

Please see @gagarwal's workaround below which WORKS!

请参阅下面的@gagarwal 的解决方法,该方法有效!

回答by dpassage

I had a similar issue to yours, I think; here was my setup.

我想我和你有类似的问题;这是我的设置。

I had an object defined in Swift:

我在 Swift 中定义了一个对象:

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

This class was then used in the initializer of an Objective-C object:

这个类随后被用在一个 Objective-C 对象的初始化器中:

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

@interface Bar: NSObject

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

@end

This made my unit tests for Barnot compile, since the MyProject-Swift.hheader isn't real and the unit test target can't see it. The release note shared by @hyouuu is on point - but I'm not testing a Swift class, I'm testing an Objective-C class!

这使我的单元测试Bar无法编译,因为MyProject-Swift.h标头不是真实的并且单元测试目标无法看到它。@hyouuu 共享的发行说明很重要 - 但我不是在测试 Swift 类,而是在测试 Objective-C 类!

I was able to fix this by changing the header file for Barto use a forward class reference instead:

我能够通过更改头文件来解决此问题,Bar以改用前向类引用:

// file Bar.h
@class Foo;

@interface Bar: NSObject

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

@end

I then included MyProject-Swift.hin Bar.m, and everything worked - my tests of Objective-C objects written in Objective-C compiled properly and continued running, and I could write new tests for Swift objects in Swift.

然后我包含MyProject-Swift.h在 中Bar.m,一切正常——我对用 Objective-C 编写的 Objective-C 对象的测试正确编译并继续运行,我可以在 Swift 中为 Swift 对象编写新的测试。

Hope this helps!

希望这可以帮助!

回答by schrulnz

After I tried out everything I could find on the topic, the thing that worked for mewas actually running the app although it was still showing the 'ModuleName-Swift.h file not found' error.

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

It went away and my app works perfectly fine. I guess I should have considered that earlier... The error keeps coming back, but after running the app it always just goes away again. So the issue is not really solved for me, but I can continue working on other topics for now...

它消失了,我的应用程序运行良好。我想我应该早点考虑...错误不断出现,但在运行应用程序后,它总是再次消失。所以这个问题对我来说并没有真正解决,但我现在可以继续研究其他主题......

回答by niggeulimann

A simple

一个简单的

@testable import MyProject

has done the job for me.

为我完成了工作。

回答by CommaToast

Strangely, I was seeing this same error, but only when targeting a device (not the simulator). Before running the test I would see the red exclamation point next to the import statement for "MyProjectNameTests-Swift.h".

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

However, funny thing is, if I just go ahead and run the test anyway (despite this apparent build error), then during the build phase that happens thereafter, XCode actually does generate the "MyProjectNameTests-Swift.h" file, and the test runs just fine!

然而,有趣的是,如果我继续运行测试(尽管存在明显的构建错误),那么在此后发生的构建阶段,XCode 实际上确实生成了“MyProjectNameTests-Swift.h”文件,并且测试运行得很好!

So, at least in my case, there was no need for the other solutions here, evidently, although I believe they do work also.

因此,至少在我的情况下,显然不需要其他解决方案,尽管我相信它们也有效。

I should also note that I deleted my DerivedData directory prior to this, so maybe that is a step also worth trying.

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

回答by whoKnows

mySwiftClassTests(and any other swift classes you want to use in objective-c) needs to be marked @objc:

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

@objc class MySwiftClassTests: XCTestCase

回答by teradyl

I couldn't get it to work by adding that filepath mentioned by other answers, but I realized the file where it was complaining wasn't even being tested. I just had to remove it from the test target using the Right Utilities Side Bar.

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

回答by Dmitry

Adding a .swift file to that target fixes issue on it.

将 .swift 文件添加到该目标修复了它的问题。