UI 测试 + postNotificationName + 永远不会到达观察者 + Xcode 7

Posted

技术标签:

【中文标题】UI 测试 + postNotificationName + 永远不会到达观察者 + Xcode 7【英文标题】:UI Tests + postNotificationName + never reaches observer + Xcode 7 【发布时间】:2015-11-10 15:18:42 【问题描述】:

我有用于测试 MyApp 的 UI 测试目标。要测试特定的 MyApp 条件,我需要将通知从 UI Test 目标发布到 MyApp 目标。要从 UI 测试目标函数发布通知,我正在使用这个:

NSNotificationCenter.defaultCenter().postNotificationName(name, object: nil, userInfo: aUserInfo)

看起来这个通知永远不会从 UI Test 目标到达观察者,但是当从 MyApp 目标发布这个通知时它工作正常。

如何将通知从 UI Target 发布到 MyApp 目标?

使用 Xcode 7。

【问题讨论】:

你是在调用 addObserver 吗?您确定在 postNotification 之前调用了 addObserver 吗? 从 MyApp 目标发布通知工作正常,但从 UI 测试目标发布时却不行。我也更新了问题。 离题,但最好将self 作为object 参数发送。 反之亦然(至少对我而言):来自 UI 测试目标的观察者无法看到从主应用发布的通知,但可以看到从内部测试发布的通知。 快速提问,我们可以在没有权限的情况下使用套接字在这里发送/接收数据吗? 【参考方案1】:

有类似的问题(试图确保在某些 UI 操作后发布 NSNotification)。对此做了一些小的研究。

未收到 NSNotification,因为 UI 测试和应用在不同的进程中运行。 NSNotification 无法通过进程边界,并且 NSDistributedNotificationServer 在 ios 上不可用。因此,目前没有默认且简单的方法可以在 UI 测试套件和应用实例之间发布 NSNotification。

但是,有一些方法可以在进程之间进行通信,并且可能会编写小型包装器甚至 NSDistributedNotificationCenter iOS 代理来进行测试。查看来自 Realm 的这篇精彩文章:https://academy.realm.io/posts/thomas-goyne-fast-inter-process-communication/

【讨论】:

【参考方案2】:

我想使用 UI 测试来测试内存泄漏,为此我想在调用视图控制器的 deinit 时在 UI 测试用例中得到通知。所以我想出了这个来提供IPC机制:

/**
  Provides simple IPC messaging. To use this class you need to include     
  #include <notify.h>
  in your bridging header. (Ab)uses UIPasteboard for message delivery, ie. 
  should not be used in production code.
*/
public class SimpleIPC 
  /// Event notification name for libnotify.
  private static let notifyEventName = "com.foo.SimpleIPC"

  /// libnotify token.
  private var token: Int32 = 0

  /// Starts listening to the events
  public func listen(callback: (String? -> Void)) 
      notify_register_dispatch(SimpleIPC.notifyEventName, &token, dispatch_get_main_queue())  token in
          callback(UIPasteboard.generalPasteboard().string)
      
  

  public class func send(message: String) 
      UIPasteboard.generalPasteboard().string = message
      notify_post(SimpleIPC.notifyEventName)
  

  deinit 
      notify_cancel(token)
  

它使用libnotifyUIPasteboard 的组合进行通知+数据传递。可用于 1-way 通信,对于 2-way,要么使有效负载包含发送者令牌,要么使用 2 个具有参数化 libnotify 事件名称的实例。

马蒂

【讨论】:

2way 在这里如何工作?我一直在设置它时遇到问题。这里的发送者令牌到底是什么?【参考方案3】:

这是针对 Mac 应用还是 iOS 应用?对于 Mac 应用程序,您可以使用 NSDistributedNotificationCenter。

在您的订阅者中:

NSDistributedNotificationCenter.defaultCenter().addObserver(object, selector: #selector(ObjectsClass.myFuncWithoutParentheses), name: "uniqueString", object: nil)

在您的发布商中:

NSNotificationCenter.defaultCenter().postNotificationName("uniqueString" object:nil)

【讨论】:

以上是关于UI 测试 + postNotificationName + 永远不会到达观察者 + Xcode 7的主要内容,如果未能解决你的问题,请参考以下文章

UI测试

APP UI自动化测试是鸡肋吗?

在 UI 测试期间测试对象状态 (iOS)

在 UI 测试期间,如何使用 Xcode 7 截取我的 UI 截图?

Xcode UI 测试:我可以使用 UI 测试脚本访问目标应用程序文件夹吗?

Web UI自动化测试之Selenium3