是否可以在 Xcode 7 个自动化 UI 测试中存根 HTTP 请求?

Is it possible to stub HTTP requests in Xcode 7 automated UI tests?

我一直在尝试拦截 stub/mock HTTP 请求 Xcode 7 个自动化 UI 测试,使用像 OHHTTPStubs 这样的工具,但没有成功。

下面是我如何尝试在 UI 测试文件的 setUp 方法中使用 OHHTTPStubs 捕获任何 HTTP 请求的示例:

override func setUp() {
  super.setUp()

  let matcher: OHHTTPStubsTestBlock = { (request) -> Bool in
    return true
  }

  OHHTTPStubs.stubRequestsPassingTest(matcher) { (response) -> OHHTTPStubsResponse! in
    return OHHTTPStubsResponse.init()
  }
}

UI 测试的工作方式是否可以防止这种情况发生?有没有人能够做到这一点?

UI 测试 运行 在与您的应用程序不同的实例中。虽然您可能可以使用应用程序中的 classes,但它们只是一个副本。

在您的应用程序中,您可以使用此处提供的解决方案检测您是否 运行 处于 UI 测试模式:How to detect if iOS app is running in UI Testing mode

我个人采用了原文post中提到的launchEnvironment解决方案;我的设置如下所示:

override func setUp() {
    super.setUp()

    let app = XCUIApplication()
    app.launchEnvironment["TEST"] = "1"
    app.launch()
}

我的一个单例实例化器(称为 RealmManager)看起来像这样(用于实例化 Realm 数据库):

func realm() -> Realm {
    let dic = NSProcessInfo.processInfo().environment
    if dic["TEST"] != nil {
        return try! Realm(configuration: Realm.Configuration(inMemoryIdentifier: "test"))
    }
    return try! Realm()
}

如果您不喜欢复制,但您可能已经在复制 XCUIApplication().launch(),您总是可以制作一个扩展 XCTestCase 的自定义测试用例 class,覆盖那里的设置加上这个,然后在你所有的测试中使用它 classes.

正如 Martijn 正确指出的那样,由于 UI 测试的工作方式,您无法在运行时直接与应用程序交互,因此任何对 NSUserDefaults 之类的 HTTP 模拟或操作 XCUITestCase 不会影响您的应用。

如果您确实需要能够模拟 HTTP 或设置和拆卸您的应用程序环境以进行特定 UI 测试,您需要在 [=] 中启动应用程序之前设置启动参数或启动环境变量XCUITestCase 的 14=] 方法,然后修改您的应用程序代码以读取启动参数或环境变量和 bootstrap 测试环境。

示例测试用例

class MyTestCase: XCTestCase {

  /**
  Called before each test in this test case.
  */
  override func setUp() {
    super.setUp()

      let app = XCUIApplication()
      app.launchArguments = [ "STUB_HTTP_ENDPOINTS" ]
      app.launch()
  }

}

示例 AppDelegate

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

#if DEBUG
  if (NSProcessInfo.processInfo().arguments.contains("STUB_HTTP_ENDPOINTS")) {
    // setup HTTP stubs for tests
  }
#endif

  return true
}

注意: 为了在本示例中使用像 OHHTTPStubs 这样的 HTTP 模拟框架,存根代码和您需要使用的任何 JSON 固定装置都需要在您的应用程序目标中,而不是测试目标中。

这是一个非常有用的话题阅读主题:https://github.com/AliSoftware/OHHTTPStubs/issues/124