我正在尝试为我的项目设置单元测试。 它是一个现有的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
我不确定为什么只有在尝试运行测试时才会发生这种情况。 有什么建议吗?
答案 0 :(得分:142)
" MyProject-Swift.h" 文件在以下路径生成:
"$(TARGET_TEMP_DIR)/../$(PROJECT_NAME).build/DerivedSources"
我最终将此添加到我的单元测试目标的标题搜索路径。
同样@hyouuu指出已成为已知问题,希望Apple能在他们的最后提供一些好的解决方案。直到我相信我们需要使用上述解决方案。
答案 1 :(得分:29)
感谢@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"
答案 2 :(得分: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编写的框架目标测试可以通过使用@import FrameworkName;导入框架模块来访问Swift生成的接口。 (16931027)
请参阅以下@ gagarwal的解决方法,其工作原理!
答案 3 :(得分:7)
我在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对象编写新的测试迅速的。
希望这有帮助!
答案 4 :(得分:4)
在我尝试了关于这个主题的所有内容后,对我有用的东西 实际上正在运行应用程序,尽管它仍然显示'ModuleName-Swift.h文件没有发现'错误。
它消失了,我的应用程序运行得很好。我想我应该早点考虑过...... 错误不断回来,但在运行应用程序后它总是会再次消失。所以这个问题并没有真正解决,但我现在可以继续研究其他主题......
答案 5 :(得分:0)
奇怪的是,我看到了同样的错误,但只是在定位设备(而不是模拟器)时。在运行测试之前,我会在“MyProjectNameTests-Swift.h”的import语句旁边看到红色感叹号。
然而,有趣的是,如果我继续运行测试(尽管存在这种明显的构建错误),那么在此后发生的构建阶段,XCode实际上会生成“MyProjectNameTests-Swift.h”文件,测试运行得很好!
所以,至少在我的情况下,显然不需要其他解决方案,但我相信它们也可以工作。
我还应该注意到,在此之前我删除了DerivedData目录,所以也许这也是值得尝试的一步。
答案 6 :(得分:0)
一个简单的
import pandas as pd
df = pd.read_csv('UNT_Data.csv', low_memory=False)
df.columns = df.columns.str.replace(' ', '_')
#making index for every change period
df['idx'] = df.groupby('GR_Key').cumcount()
#converting index column name to Change_Period_Start_
df['date_idx'] = 'Change_Period_Start_' + df.idx.astype(str)
#converted the columns to one row for one GR Key
date = df.pivot_table(index='GR_Key', columns='date_idx', values='Change_Period_Start', aggfunc='first')
已经为我完成了工作。
答案 7 :(得分:0)
在我的一个客户项目中,他们直接在项目中添加了框架。我解决了这样的错误;
答案 8 :(得分:-1)
mySwiftClassTests
(以及您希望在objective-c中使用的任何其他快速类)需要标记为@objc
:
@objc class MySwiftClassTests: XCTestCase
答案 9 :(得分:-1)
我无法通过添加其他答案提到的文件路径来使其工作,但我意识到它抱怨的文件甚至没有被测试。我只需要使用Right Utilities Side Bar将其从测试目标中删除。
答案 10 :(得分:-2)
将.swift文件添加到该目标可修复问题。