OCUnit 中的简化断言
Posted
技术标签:
【中文标题】OCUnit 中的简化断言【英文标题】:Simplified asserts in OCUnit 【发布时间】:2010-02-11 20:06:23 【问题描述】:我刚开始使用 OCUnit,发现断言有点麻烦。在 JUnit 中,我可以编写一个测试来比较如下数字。这个测试显然会失败,但这显示了我可以为两个数字编写的漂亮、简单的断言以及我得到的反馈:“预期 但是 ”,代码很少。
到目前为止,我在 XCode 中尝试的是:
这很有效,但不如 JUnit 优雅。你知道它是否存在断言宏 alà JUnit for XCode (OCUnit)?另外,是否可以在 XCode 中获得红/绿条?
【问题讨论】:
你可以试试AppCode,测试结果和Eclipse用JUnittv.jetbrains.net/videocontent/unit-testing-in-appcode提供的输出比较相似 【参考方案1】:首先要注意的是 OCUnit(又名 SenTestingKit.framework)与 Xcode 集成,但并不是真正的 Xcode 的部分。 OCUnit 最初是第三方代码,后来成为 Objective-C 单元测试的事实上的标准,因此 Apple 采用了它并现在对其进行维护。
更重要的是,您看到的输出似乎有些奇怪。我正在使用 Snow Leopard 附带的 Xcode 3.2.1。我尝试了以下测试:
- (void) testNumbers
int number1 = 2;
int number2 = 3;
STAssertEquals(number1, number2, nil);
STAssertEquals(4, 5, nil);
这是我在 Xcode 构建结果窗格/窗口中看到的错误:
-[ExampleTest testNumbers] : '2' should be equal to '3'
-[ExampleTest testNumbers] : '4' should be equal to '5'
当我双击构建日志中的错误时,Xcode 直接跳转到失败断言的行。
OCUnit 宏当然并不完美,但您在上面使用的示例非常冗长。宏需要 2+ 或 3+ 参数。 (STFail
是一个例外,只需要 1+ 个参数。)最后一个必需的参数始终是描述的可选格式字符串,并且任何其他参数都用于替换这些占位符,就像你对 @ 所做的那样987654324@ 或NSLog()
。如果你通过nil
,你只会得到默认错误,没有额外的细节。
我通常只在测试确实需要上下文时添加描述。例如,断言的测试和/或主题实际上意味着什么。通常,我只是将这些信息包含在断言周围的 cmets 中。越简单越好。 :-)
要回答您的最后一个问题,目前还没有一种方法可以在 Xcode 中像您在 JUnit 中看到的那样获得红/绿条。这可能是一个不错的补充,但我个人认为这不是关键。 YMMV。
【讨论】:
【参考方案2】:正如其他人所说,您可以通过将nil
作为最后一个参数来使宏更容易接受。如果测试失败,这将为您提供默认输出。当然,您可以在需要时提供自己的字符串。我经常发现这对于具有返回 BOOL
或 id
但通过引用获取 NSError*
的方法的代码很有用,如下所示:
- (void)testFoo
NSError *err;
STAssertTrue([bar fooMethodReturningBOOLError:&err], @"Error: %@ (%@)", err, [err userInfo]);
关于红/绿条,在构建窗口中构建的最后一步,您确实会得到一个红/绿结果,但它不像在其他 IDE 中那样可见。有很多很好的心理学文献表明,让它更加突出将是一个好主意。一定要在bugreport.apple.com 提交增强请求。可以参考rdar://7685315
(我的票就是这个效果)。
【讨论】:
【参考方案3】:现在有一个很棒的框架可用,称为 OCHamcrest。它允许您的测试断言读起来像一个句子,而且通常您不必提供失败描述,对我来说,这是我在测试中不想做的最后一件事,因为它必须被维护。
这里是githubhttps://github.com/hamcrest/OCHamcrest
这是自述文件中的一个示例
NSCalendarDate* date = [NSCalendarDate dateWithString:@"26 Apr 2008" calendarFormat:@"%d %b %Y"];
assertThat(date, is(onASaturday()))
断言对 OCUnit 非常友好,添加您自己的断言非常简单。
【讨论】:
【参考方案4】:为什么不为此创建自己的包装器?
OCUnit 将运行结果转储到控制台窗口,没有 GUI 集成,抱歉。我觉得挺方便的,不过习惯了。
【讨论】:
不是我想听到的答案,但足够公平。让我们希望 Apple 在 XCode 的下一个版本中更加关注这一点。 是的,这是真的。我的同事(通常在 Visual Studio/Eclipse 中开发)抱怨 XCode 并嘲笑它缺乏功能。确实它可能看起来很裸露,但至少它比 VS 快一点(接口方面):) 创建自定义包装器是可能的,但完全没有必要。无需额外的函数/宏杂技就很容易获得简洁的断言。详情见我的回答。以上是关于OCUnit 中的简化断言的主要内容,如果未能解决你的问题,请参考以下文章
UINavigationController 中的 OCUnit 测试问题