我有一个混合结构的ObjC / Swift代码库,并且测试不再在Xcode 10.2下运行(详细信息如下)。我正在尝试进行最小的结构更改以恢复测试,以便为下一步的重构提供一个安全网。在采取我认为显而易见的第一步之后,测试无法建立(下面再次详细介绍)。
我对以下任何一项感兴趣
我对如何构造一个新项目或创建具有更合理配置的新目标的建议不感兴趣:从这些目标中提取代码也不是一件容易的事,因此我确实需要在之前进行测试覆盖我开始任何重构。
myCompany
app
的MyCompany
MyCompany
myCompanyTests
MyCompany
测试文件仅包含在myCompanyTests
目标中,但是许多代码文件都包含在 app
和myCompanyTests
目标中。我认为,这与定义相同模块名称的两个目标可能是为了避免必须将应用程序目标导入测试中,因为Swift / ObjC互操作存在问题(请参阅下一节)。构建测试会产生有关在两个地方实现的类的警告:
objc[9724]: Class _TtC12MyCompany12DiaryFetcher is implemented in both
/Users/tikitu/Library/Developer/CoreSimulator/Devices/556CAC28-B90B-4B6B-A87C-1A1450795051/data/Containers/Bundle/Application/495F33C2-F7FC-4AE6-B3FE-6908D6361B55/mycompany-develop.app/mycompany-develop (0x10d724060)
and
/Users/tikitu/Library/Developer/Xcode/DerivedData/mycompany-bifciplpbqaeqqdrmhivpjgnojri/Build/Products/Debug-iphonesimulator/mycompany-develop.app/PlugIns/myCompanyTests.xctest/myCompanyTests (0x13566dc38).
One of the two will be used. Which one is undefined.
从Xcode 10.2开始,myCompanyTests
成功构建,但是运行测试失败,并且在EXC_BAD_ACCESS
调用内某处的swift_checkMetadataState
中有UIApplicationMain
。我的 guess 是,这与模块名/目标中的文件名都有关。
作为整理事情的第一次尝试,我做了以下工作:
myCompanyTests
目标中删除所有非测试文件myCompanyTests
产品模块名称重命名为MyCompanyTests
@testable import MyCompany
然后我开始遇到Swift / ObjC互操作问题,因为我需要从测试目标中的ObjC代码中调用应用程序目标中的Swift代码。我尝试过的事情:
#import "MyCompany-Swift.h"
在objc .m测试文件中
'MyCompany-Swift.h' file not found
#import <MyCompany-Swift.h>
在objc .m测试文件中
'MyCompany-Swift.h' file not found
#import <MyCompany/MyCompany-Swift.h>
在objc .m测试文件中(是的,您可以看到我实际上并不了解这种机制)
'MyCompany/MyCompany-Swift.h' file not found
#import "MyCompanyTests-Swift.h"
MyCompanyTests-Swift.h
包含一行@import MyCompany;
,看起来很有希望!Module 'MyCompany' not found
尤其是最后一个对我来说似乎很可疑,因为我希望Xcode生成的文件应该“正常工作”。我想我已经覆盖了一些麻烦的用户设置:我很乐意为检查位置提供任何建议。
答案 0 :(得分:0)
由于此信息尚不完整,我不会接受(但),但我至少相信,我知道为什么固定版本会失败:MyCompany-Swift.h
的位置不在单元测试中目标的标头搜索路径,因为它是 app 目标。参考例如https://github.com/jeremy-w/MixedLanguageTesting(建议在标题搜索路径中添加临时条目)。
答案 1 :(得分:0)
我认为问题在于,只有 framework 目标会自动创建swift-to-objc头文件Module-Swift.h
:应用目标和测试目标都没有这样做
我通过创建两个新的框架目标成功解决了这些问题
* MyCompanyStuffThatUsedToBeInApp
(包含除main.h
之外的应用程序目标中的所有内容),它可以双向进行swift / objc互操作,
* MyCompanyTesting
(由测试导入的框架目标,同样针对仅测试代码执行双向swift / objc互操作)。
仍然可以使用更简单的方法来解决此问题,但至少已证明该方法可行。