如何将我的应用程序模块导入MyAppUITests文件?

这是我的简单testing用例:

import XCTest @testable import MyApp //it doesn't work 

因为这个:

在这里输入图像说明

 class TabBarControllerTests: XCTestCase { override func setUp() { super.setUp() let defaults = NSUserDefaults.standardUserDefaults() defaults.setObject([], forKey: DBTabBarOrderedIndexesKey) //key is undefined, because of lack of my app module defaults.synchronize() continueAfterFailure = false XCUIApplication().launch() } func testIsOrderOfTabsSaved() { XCUIApplication().tabBars.buttons["Catering"].tap() //what next? } } 

一旦我点击UITabBarItem我改变了DBAppSettings.mode的值,所以在这里我想有一个访问我的DBAppSettings.mode属性来检查它是否真的改变。

我注意到有一个奇怪的事情,当我build立我的应用程序,并检查构build什么, 没有我的UITest目标的生成 。 是不是重要?

在这里输入图像说明

这是苹果的回应:

UItesting的执行方式与unit testing不同 – unit testing在应用程序进程中运行,以便他们可以访问应用程序代码。 UItesting在应用程序之外的单独进程中执行,以便它们可以模拟用户如何与应用程序交互。 预计您不能从UItesting访问您的应用程序类。

您需要在UItesting中访问的每个对象都必须是UItesting目标的一部分。 这包括对象依赖关系。 这是一个滑坡,而且一塌糊涂。

而不是让你的testing知道你的应用程序,尝试转过身来让你的应用程序知道它正在testing。 一种方法是使用launchArguments属性:

  app = XCUIApplication() app.launchArguments.append("TestMode") app.launch() 

然后在你的应用程序:

  if NSProcessInfo.processInfo().arguments.contains("TestMode") { // I am running in test mode } 

在你的情况下,应用程序可以相应地设置NSUserDefaults。

由于苹果阻止您从UItesting中访问主应用程序,因此您可能会考虑重新组织应用程序结构以将需要检查的相关数据存储到UItesting可访问的位置。

您可能会考虑将定义和数据从您的主应用程序类转移到可以由testing框架加载的单独的类。

我通过从应用程序目标中抽取一些东西到两个框架(模型和视图模型)中,然后导入到我的UItesting中来解决了无法访问的符号问题。

至于访问的可执行文件的实际内存,你不能,但你可以testing的东西,应该出现在屏幕上的某个地方在该模式下。 我使用这个断言来检查表视图单元格的存在:

 XCTAssertTrue(tables.cells.staticTexts["Cell title I expect to exist"].waitForExistence(timeout: 1)) 

既然你可以使用可访问性,你可以通过这种方式访问​​相当多的东西。 我想你可以添加一个不可见的标签,只有你的应用程序的内存转储 – 仅在testing模式!

我也使用启动参数来configuration我的应用程序的UItesting,如迈克尔build议: https : //stackoverflow.com/a/34469136/4789448 。