对由 NSTimer 异步发送的 NSNotification 进行单元测试

Posted

技术标签:

【中文标题】对由 NSTimer 异步发送的 NSNotification 进行单元测试【英文标题】:Unit test on a NSNotification which is sent ansynchronous by a NSTimer 【发布时间】:2015-10-21 10:19:41 【问题描述】:

几天以来,我试图弄清楚如何使用 GHUnit 测试我的 API。现在我来测试这个问题:

API 获得一些输入,CUT 执行一些操作并启动一个 NSTimer。计时器触发后,它会发送一个带有一些 userInfo 数据的 NSNotification。很清楚如何测试 userInfo 数据,但我要测试的是,是否仅在某些特定情况下才发送通知,如果不是,则根本不应该发送。

我如何测试它,读完这篇就很清楚了:http://www.hpique.com/2013/12/nsnotificationcenter-part-3/

但现在逻辑问题出现了:CUT 的异步行为在 NSTimer 触发后发送 NSNotification。当我现在在每个测试中等待计时器触发时,我的测试会变得非常慢。

如何在不一直等待 NSTimer 触发的情况下测试行为?你有什么想法吗?

【问题讨论】:

所以,您的问题实际上是,是否可以并发执行一个或多个异步测试,以及是否存在类似“异步测试”`? 或多或少。实际的想法是,去掉定时器,让异步测试变成同步测试,测试起来相当容易。如果这是不可能的,如何以正确的方式测试这种异步行为而不是进行缓慢的测试。 【参考方案1】:

我不知道在 Xcode 中使用 XCTest 执行 同步 测试并发 的方法。当然,您可以定义多个测试项目并从控制台同时运行它们。但我想,这不是你要找的。​​p>

异步测试要求测试方法在断言测试之前返回,但最终会被测试。测试运行者需要了解 异步 测试才能正确处理它们。

使用 XCTest,不可能进行 异步 测试。源代码文档中有一些提示让我相信,这可能根本不可能:

waitForExpectationsWithTimeout 的描述中写道:

"-waitForExpectationsWithTimeout:handler: 在测试流程中创建一个同步点。只有一个-waitForExpectationsWithTimeout:handler: 可以在任何给定时间处于活动状态,但期望->等待的多个离散序列可以链接在一起。"

waitForExpectationsWithTimeout在处理事件时运行运行循环,直到满足所有期望或达到超时。客户端在使用此 API 时不应操纵运行循环。

所以,只有 一个 waitForExpectationsWithTimeout:handler: 可以处于活动状态,我们不能修改底层的运行循环——这很清楚地表明我们不能异步执行测试

注意:您可以在测试方法中测试异步方法或函数。然而,在 XCTest 中,测试方法本身总是同步 - 因为它等待结果可用。

【讨论】:

是的,我听说过一些关于这个事实的谣言,XCTest 在这种特殊情况下有点没用。甚至 GHUnit 也没有这个选择,对吧? GHUnit 声明,它可以“并行运行测试”。而且,还有GRUnit 似乎改进了异步测试。不过,我不熟悉这些测试框架。为了获得更好的帮助,您应该发布您的代码。 为什么不在单个测试用例中运行所有内容并使用定时预期?您可以通过更少的努力实现几乎相同的效果。

以上是关于对由 NSTimer 异步发送的 NSNotification 进行单元测试的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中使用 NSTimer 时发送到类的无法识别的选择器; NSInvalidArgumentException

无法识别的选择器发送到 NSTimer scheduleTimerWithTimeInterval 中的实例

NSTimer 不适用于 AsyncSocket 库

如何在选择器成功之前调用 NSTimer [重复]

NSTimer 中的错误(Swift:Xcode)

应用程序进入后台时如何保持NSTimer?