objective-c – 为什么我的OCUnit测试失败了“代码138”?

前端之家收集整理的这篇文章主要介绍了objective-c – 为什么我的OCUnit测试失败了“代码138”?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试使用XCode 3.1学习 objective-c.我一直在做一个小程序,决定添加单元测试.

我按照苹果开发者页面Automated Unit Testing with
Xcode 3 and Objective-C
上的步骤.当我添加了我的第一个测试,当测试失败时,它工作正常,但是当我更正测试时,构建失败. Xcode报告以下错误

error: Test host ‘/Users/joe/Desktop/OCT/build/Debug/OCT.app/Contents/MacOS/OCT’ exited abnormally with code 138 (it may have crashed).

试图隔离我的错误,我重新遵循上面的单元测试示例中的步骤,并且示例工作.当我添加了我的代码和测试用例的简化版本时,返回错误.

这是我创建的代码

Card.h

  1. #import <Cocoa/Cocoa.h>
  2. #import "CardConstants.h"
  3.  
  4. @interface Card : NSObject {
  5. int rank;
  6. int suit;
  7. BOOL wild ;
  8. }
  9.  
  10. @property int rank;
  11. @property int suit;
  12. @property BOOL wild;
  13.  
  14. - (id) initByIndex:(int) i;
  15.  
  16. @end

Card.m

  1. #import "Card.h"
  2.  
  3. @implementation Card
  4.  
  5. @synthesize rank;
  6. @synthesize suit;
  7. @synthesize wild;
  8.  
  9. - (id) init {
  10. if (self = [super init]) {
  11. rank = JOKER;
  12. suit = JOKER;
  13. wild = false;
  14. }
  15. return [self autorelease];
  16. }
  17.  
  18. - (id) initByIndex:(int) i {
  19. if (self = [super init]) {
  20. if (i > 51 || i < 0) {
  21. rank = suit = JOKER;
  22. } else {
  23. rank = i % 13;
  24. suit = i / 13;
  25. }
  26. wild = false;
  27. }
  28. return [self autorelease];
  29. }
  30.  
  31. - (void) dealloc {
  32. NSLog(@"Deallocing card");
  33. [super dealloc];
  34. }
  35.  
  36. @end

CardTestCases.h

  1. #import <SenTestingKit/SenTestingKit.h>
  2.  
  3. @interface CardTestCases : SenTestCase {
  4. }
  5. - (void) testInitByIndex;
  6. @end

CardTestCases.m

  1. #import "CardTestCases.h"
  2. #import "Card.h"
  3.  
  4. @implementation CardTestCases
  5.  
  6. - (void) testInitByIndex {
  7. Card *testCard = [[Card alloc] initByIndex:13];
  8. STAssertNotNil(testCard,@"Card not created successfully");
  9. STAssertTrue(testCard.rank == 0,@"Expected Rank:%d Created Rank:%d",testCard.rank);
  10. [testCard release];
  11. }
  12. @end

解决方法

我自己遇到过这么多次,而且总是很讨厌.基本上,这通常意味着您的单元测试会崩溃,但并不能帮助隔离错误.如果单元测试在崩溃之前生成输出(打开Build> Build Results),通常至少可以了解发生问题时运行的是什么测试,但这通常不是太有帮助.

跟踪原因的最好的一般建议是调试您的单元测试.使用OCUnit时,不幸的是选择Run>调试.但是,您正在使用的教程有一个附近的标题为“使用调试器与OCUnit”的部分,该部分解释了如何在Xcode中创建自定义可执行文件,以便调试器附加的方式执行单元测试.当你这样做时,调试器将停止错误发生的位置,而不是在火焰中下降时得到神秘的“代码138”.

虽然我可能无法猜到导致错误的原因,但我确实有一些建议…

从来没有,EVER会在init方法自动释放自己 – 它违反了保留释放内存规则.如果对象意外释放,那将导致崩溃.例如,在testInitByIndex方法中,testCard会自动释放,因此,最后一行的[testCard release]可以保证崩溃.
>我建议您将initByIndex:方法重命名为initWithIndex :,甚至切换到initWithSuit:(int)suit rank((int)),以便您可以传递两个值,而不是单个int(或NSUInteger,这将消除测试< 0)你必须处理.
>如果你真的想要一个返回自动释放对象的方法,你也可以创建一个方便的方法,如(Card *)cardWithSuit:(int)suit rank:(int)rank.该方法只返回一行alloc / init / autorelease组合的结果.
>(Minor)完成调试完毕后,可以摆脱调用super的dealloc.如果你想要找到永远不会被释放的内存,那么使用仪器的方法要容易得多.
>(Niggle)对于您的测试方法,请考虑使用STAssetEquals(testCard.rank,…).它测试同样的事情,但任何导致的错误有点容易理解.
>(Trivial)您不必在@interface中声明单元测试方法. OCUnit为您动态运行任何格式的方法 – (void)test ….宣告他们并不痛,但是如果你只是省略它们,那么你可以自己节省一些打字.在相关的说明中,我通常只有一个.m文件进行单元测试,并将@interface部分放在该文件的顶部.这是非常好的,因为没有其他人需要包括我的单元测试界面.
>(Simplicity)除非你将CardTestCases子类化,否则只需删除.h文件,并将@interface放在.m文件的顶部就可以了.当多个文件需要包含声明时,头文件是必需的,但单元测试通常不是这样.

以下是这些建议的测试文件可能是这样的:

CardTest.m

  1. #import <SenTestingKit/SenTestingKit.h>
  2. #import "Card.h"
  3.  
  4. @interface CardTest : SenTestCase
  5. @end
  6.  
  7. @implementation CardTest
  8.  
  9. - (void) testInitWithIndex {
  10. Card *testCard = [[Card alloc] initWithIndex:13];
  11. STAssertNotNil(testCard,@"Card not created successfully");
  12. STAssertEquals(testCard.rank,@"Unexpected card rank");
  13. [testCard release];
  14. }
  15. @end

猜你在找的C&C++相关文章