您将如何编写单元测试 - 例如使用OCUnit - 以确保在Cocoa/Objective-C中正确释放/保留对象?
一个天真的方法是检查它的价值retainCount,但当然你永远不应该使用retainCount.您是否可以简单地检查对象的引用是否被赋值nil以指示它已被释放?另外,您对实际取消分配对象的时间有什么保证?
我希望只有几行代码的简洁解决方案,因为我可能会广泛使用它.实际上可能有两个答案:一个使用自动释放池,另一个不使用.
为了澄清,我不是在寻找一种全面测试我创建的每个对象的方法.全面地对任何行为进行单元测试是不可能的,更不用说内存管理了.但至少,最好检查已发布对象的行为以进行回归测试(并确保相同的与内存相关的错误不会发生两次).
我接受了BJ Homer的答案,因为我发现它是实现我想到的最简单,最简洁的方法,但需要注意的是,在XCode的生产版本中,提供自动引用计数的弱指针是不可用的.从2011年7月23日到4.2?)我也对这一点印象深刻
可以基于每个文件启用ARC; 它不要求整个项目使用它.您可以使用ARC编译单元测试并将主项目保留为手动保留释放,此测试仍然有效.
话虽如此,为了更详细地探讨Objective-C中单元测试内存管理所涉及的潜在问题,我强烈推荐Peter Hosey的深入回应.
我想知道你是否可以将一个单元测试包链接到多个目标.因此,可以使用一个测试包测试所有应用程序目标.
我在所有应用程序目标之间有一些共享代码,但也有一些基于运行的应用程序目标的特定计算.
目前,如果我想测试不同的应用程序目标,我必须将Build Settings中的Bundle Loader选项设置为使用的应用程序目标的.app文件.
我的问题是:这可以在不为每个应用目标创建多个测试包目标的情况下完成,而不必总是更改Bundle Loader选项吗?
我刚刚安装了Xcode 4.6.当我现在运行我的OCUnit测试时,在所有测试完成后,我在输出窗口中得到多行"profiling:invalid magic number".我很确定Xcode 4.5.2没有给我那个输出.
有人知道这条线是什么意思吗?
使用OCUnit,有没有办法测试委托协议?
我正在尝试这个,这不起作用.
-(void) testSomeObjDelegate {
SomeObj obj = [[SomeObj alloc] initWithDelegate:self];
[obj executeMethod];
}
-(void) someObjDelegateMethod {
//test something here
}
Run Code Online (Sandbox Code Playgroud)
我将尝试obj在不同的线程上调用该方法,并让测试进入睡眠状态,直到调用该委托.似乎应该有一种更简单的方法来测试它.
我想在我的XCode应用程序中为类编写一些逻辑单元测试.在Xcode 4中,我在Project Navigator中单击了项目名称,然后从底部单击Add Target.我选择了其他的"Cocoa Touch Unit Testing Bundle",给新目标一个"测试"的"产品名称",并完成.
因为我要测试的类是作为现有应用程序目标的一部分编译的,所以对于我的新"测试"目标,我立即转到Build Phases选项卡并将我现有的应用程序目标添加为唯一的目标依赖项.
然后我转到创建的tests.m文件,导入我要测试的类(在它下面ReleasePlanManager,并调用它的一个方法.但链接器失败,出现如下错误:
Undefined symbols for architecture i386:
"_OBJC_CLASS_$_ReleasePlanManager", referenced from:
objc-class-ref in tests.o
ld: symbol(s) not found for architecture i386
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
所以这个类是找不到的,即使(根据我的理解)添加应用程序目标(它是其中的一部分)应该足够了吗?
任何帮助将不胜感激.谢谢!
在Objective-c中比较NSUInteger和int(例如5)的最快方法是什么?
背景 - 我注意到以下代码行给出了错误:
STAssertEquals([nsMutableArrayInstance count], 5, @"xxxx");
// gives Type Mismatch
Run Code Online (Sandbox Code Playgroud)
所以我有效地问的是如何纠正这个以修复错误...
注意:"使用GHUnit"不是这个问题的可接受答案.我知道大多数人认为GHUnit比Xcode4 OCUnit更好,但这不是我所要求的.我会另外评估一下.
我有一个从头开始在Xcode4中创建的Xcode项目,在创建过程中选中了"Include unit tests"复选框.我还包括了我在之前项目中开发的一些库.它们通过"Add Files to x ..."对话框添加到项目中,并且仅添加到应用程序目标(而不是测试目标).它们在运行应用程序时工作正常,所以我认为它们设置正确.我还为这个项目编写了许多不同的类.
我的测试文件以标准方式设置,名为[AppName] Tests.h和.m.
标题代码:
#import < SenTestingKit/SenTestingKit.h >
@interface [AppName]Tests : SenTestCase {
@private
}
@end
Run Code Online (Sandbox Code Playgroud)
实施守则:
#import "[AppName]Tests.h"
@implementation [AppName]Tests
- (void)setUp
{
[super setUp];
// Set-up code here.
}
- (void)tearDown
{
// Tear-down code here.
[super tearDown];
}
// Test methods go here
@end
Run Code Online (Sandbox Code Playgroud)
这只是基本的骨架.它在我的其他项目中工作正常,并且在此项目中,只要我不导入任何其他文件.当我从该项目导入另一个文件并使用它时,我在Xcode输出日志中看到以下错误:
The test bundle at /Users/[Me]/Library/Developer/Xcode/DerivedData/[AppName]-dwuuuwcpmdqxqmgxomoniplwhlpb/Build/Products/Debug-iphonesimulator/[AppName]Tests.octest could not be loaded because a link error occurred. It is likely that dyld cannot locate a framework framework …
我一直在关注这篇博文:将单元测试添加到现有项目中.
但是我收到了这个错误:
ld:找不到文件:Build/Products/Debug-iphoneos/MyApp.app/MyApp Command /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/clang失败,退出代码为1
我有我的测试目标属性,
Bundle Loader = $(BUILT_PRODUCTS_DIR)/MyApp.app/MyApp
测试主机= $(BUNDLE_LOADER)
(它们都等同于:build/Debug-iphoneos/MyApp.app/MyApp)
我猜测这些变量并没有指向与编译器相同的位置."build/Debug-iphoneos/..."vs"Build/Products/Debug-iphoneos/......"
我可能完全错误的猜测,但无论哪种方式,有没有人知道是什么导致了这个错误或我将如何修复这些环境变量?
谢谢你的帮助,
山姆
你如何编写第一响应者单元测试?
我正在尝试编写测试以确认方法将焦点提升到下一个文本字段.controller是...的后代UIViewController.但是这个探索性测试失败了:
- (void)testFirstResponder
{
[controller view];
[[controller firstTextField] becomeFirstResponder];
STAssertTrue([[controller firstTextField] isFirstResponder], nil);
}
Run Code Online (Sandbox Code Playgroud)
第一行导致视图被加载,以便其出口就位.文本字段是非零的.但测试从未通过.
我猜测becomeFirstResponder不会立即设置第一个响应者,而是将其安排在以后.那么有一个很好的方法来编写单元测试吗?
在接受的答案中从评论中提取答案......让事情运行一小段时间:
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate date]];
Run Code Online (Sandbox Code Playgroud)
我还发现我需要创建一个UIWindow并将视图控制器的视图放入其中,如最热门的答案中所述.
当我运行单元测试时,我想跳过一些代码(例如我不想[[UIApplication sharedApplication] openURL:..]运行).我正在寻找运行时检查我是否正在运行单元测试.
我知道我已经看过代码检查Objective-C运行时,如果单元测试正在运行,但我再也找不到它了.