这是我的简单测试用例:
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
媒体资源,以检查它是否真的发生了变化。
我注意到有一个奇怪的事情,当我构建我的应用程序并检查构建的内容时,不是我的UITest目标的构建。这很重要吗?
答案 0 :(得分:5)
这是Apple的回复:
UI测试与单元测试的执行方式不同 - 单元测试在应用程序进程内运行,以便他们可以访问您的应用程序代码。 UI测试在应用程序之外的单独进程中执行,因此它们可以模拟用户与应用程序交互的方式。您不希望自己能够通过UI测试访问您的应用类。
答案 1 :(得分:1)
您在UI测试中需要访问的每个对象都必须是UI测试目标的一部分。这包括对象依赖性。这是一个滑坡,而且是一团糟。
答案 2 :(得分:1)
不要让您的测试了解您的应用,请尝试扭转它并让您的应用知道它正在接受测试。一种方法是使用launchArguments
属性:
app = XCUIApplication()
app.launchArguments.append("TestMode")
app.launch()
然后在你的应用中:
if NSProcessInfo.processInfo().arguments.contains("TestMode") {
// I am running in test mode
}
在您的情况下,应用程序可以相应地设置NSUserDefaults。
答案 3 :(得分:0)
由于Apple阻止您从UI测试访问主应用程序,因此您可能会考虑重新组织应用程序结构以存储需要检查UI测试可访问的位置的相关数据。
您可以考虑将主应用程序类中的定义和数据移动到可由测试框架加载的单独类中。
答案 4 :(得分:0)
我通过将我的app目标中的一些东西拉到两个框架(模型和视图模型)中解决了无法访问的符号问题,然后我可以将其导入到我的UI测试中。
至于访问可执行文件的实际内存,你不能,但你可以测试应该在该模式的某个地方显示的内容。我使用这个断言来例如检查是否存在表格视图单元格:
XCTAssertTrue(tables.cells.staticTexts["Cell title I expect to exist"].waitForExistence(timeout: 1))
由于您可以使用辅助功能,因此您可以通过这种方式访问相当数量的内容。我想你可以添加一个不可见的标签,只转储你应用程序的内存测试模式!
我也使用启动参数来配置我的应用程序进行UI测试,正如迈克尔建议的那样:https://stackoverflow.com/a/34469136/4789448。