Cocoaのユニットテスト

Xcodeと統合された単体テストを作成するためのフレームワークであるOCUnitの使用の基本を以下に説明します。 説明したことを視覚的に試すために、コードをすぐにダウンロードできます。 彼はXcode 4の時代の前に書いたので、写真は少し時代遅れです。



したがって、たとえば、標準のNSStringクラスを拡張し、そのコンテンツを反転するメソッドを追加する特定のカテゴリがあります。

//ExtendedString.h #import <Cocoa/Cocoa.h> @interface NSString (Extended) - (NSString *)invert; @end 

 //ExtendedString.m #import "ExtendedString.h" @implementation NSString (Extended) - (NSString *)invert { NSUInteger length = [self length]; NSMutableString *invertedString = [NSMutableString stringWithCapacity: length]; while (length > (NSUInteger)0) { unichar c = [self characterAtIndex: --length]; [invertedString appendString: [NSString stringWithCharacters: &c length: 1]]; } return invertedString; } @end 

プロジェクトに新しいターゲットを追加します。 「テスト」と呼びましょう。





プロジェクトに単体テスト用の特別なフレームワーク、SenTestingKitを追加します。



テストターゲットにのみ追加する必要があります。



Testsというソース用のグループを作成し、新しいテストファイルを追加します。 ところで、プロジェクトフォルダーにTests物理サブフォルダーも作成し、そこにテストのソースを配置するのが最善です。





わかりやすい方法-ExtendedString_Test.m-で呼び出して、Testsターゲットに追加します。



さらに、Testsターゲットは、テストだけでなく、テスト対象のクラス自体のソースコードを追加する必要があります。 その結果、プロジェクトのターゲット構造は次のようになります。



テストコードは次のとおりです。必要なコメントを提供します。

 //ExtendedString_Test.h #import <SenTestingKit/SenTestingKit.h> //   //       ,   , //        - : //@class MyClass; //  Mylass    ExtendedString_Test //,   NSString @interface ExtendedString_Test : SenTestCase // -    { NSString *_string; } @end 

 //ExtendedString_Test.m #import "ExtendedString_Test.h" #import "ExtendedString.h" //     @implementation ExtendedString_Test - (void)setUp //  ,        { _string = [[NSString alloc] initWithString: @"Hello world!"]; STAssertNotNil(_string, @"Construct error!"); // ,     } - (void)tearDown //  ,    { [_string release]; } - (void)testInvertString //    { STAssertEqualObjects(@"Hello world!", _string, @"String is not initialized!"); //  STAssertEqualObjects(@"!dlrow olleH", [_string invert], @"String is not inverted!"); //  } @end 

すべてが正常であれば、Testsターゲットのアセンブリは単に成功します。 アサーションのいずれかが無効な場合、ビルド中にコンパイルエラーであるかのようにエラーが表示されます。 このようなもの:



このキッチンはどのように機能しますか?

テストターゲットのアセンブリ中に、octest拡張機能を持つ特別なバンドルが作成されます。 このターゲットをアセンブルする次の手順は、次の内容でスクリプトを実行することです。

$ {SYSTEM_DEVELOPER_DIR} /ツール/ RunUnitTests
これにより、ネストされたスクリプトが実行されますが、特定のパラメーターを使用して/ Developer / Tools / otestを呼び出すことになります。 後者は、テストバンドルを自分自身にロードし、そこでSenTestCaseの下位クラスを見つけ、最初にsetUpメソッドを、最後にtearDownをプルし、それらの間で名前が「test」で始まるすべてのメソッドを呼び出します。 はい、Objective-Cではこれが可能です:)

したがって、すべてのテストは接頭辞「test」で開始する必要があります。

ところで、octestは手動で起動できます。 たとえば、次のように:

export OBJC_DISABLE_GC=YES # Garbage Collector
arch -i386 /Developer/Tools/otest ~/InvertString/build/Debug/Tests.octest # (i386),

出力は次のようになります。

objc[22721]: GC: forcing GC OFF because OBJC_DISABLE_GC is set
objc[22721]: GC: forcing GC OFF because OBJC_DISABLE_GC is set
Test Suite '/Users/ium/InvertString/build/Debug/Tests.octest(Tests)' started at 2011-07-01 18:46:45 +0300
Test Suite 'ExtendedString_Test' started at 2011-07-01 18:46:45 +0300
/Users/ium/InvertString/Tests/ExtendedString_Test.m:21: error: -[ExtendedString_Test testInvertString] : 'Hello world' should be equal to 'Hello world!' String is not initialized!
2011-07-01 18:46:45.240 otest[22721:80f] !dlrow olleH
/Users/ium/InvertString/Tests/ExtendedString_Test.m:22: error: -[ExtendedString_Test testInvertString] : '!dlrow olle' should be equal to '!dlrow olleH' String is not inverted!
Test Case '-[ExtendedString_Test testInvertString]' failed (0.003 seconds).
Test Suite 'ExtendedString_Test' finished at 2011-07-01 18:46:45 +0300.
Executed 1 test, with 2 failures (0 unexpected) in 0.003 (0.003) seconds

Test Suite '/Users/ium/InvertString/build/Debug/Tests.octest(Tests)' finished at 2011-07-01 18:46:45 +0300.
Executed 1 test, with 2 failures (0 unexpected) in 0.003 (0.010) seconds

もちろん、これはエラーオプションの場合です。 ちなみに(Build> Build Results)、すべてログに記録されます。

アセンブリ中にsdterrでこれを受信すると、Xcodeはすぐに解析し、ファイル名と行番号が前に付いたキーワード「error:」を見つけ、前の図のようにエラーを美しく強調します。

クレームを検証するためのマクロのセットは次のとおりです。

 STFail(description, ...) //      ,  ,     STAssertNil(a1, description, ...) STAssertNotNil(a1, description, ...) STAssertTrue(expression, description, ...) STAssertFalse(expression, description, ...) STAssertEqualObjects(a1, a2, description, ...) //    ,    STAssertEquals(a1, a2, description, ...) //    STAssertEqualsWithAccuracy(left, right, accuracy, description, ...) STAssertThrows(expression, description, ...) STAssertThrowsSpecific(expression, specificException, description, ...) STAssertThrowsSpecificNamed(expr, specificException, aName, description, ...) STAssertNoThrow(expression, description, ...) STAssertNoThrowSpecific(expression, specificException, description, ...) STAssertNoThrowSpecificNamed(expr, specificException, aName, description, ...) STAssertTrueNoThrow(expression, description, ...) STAssertFalseNoThrow(expression, description, ...) 

コメントされたものを除いて、名前はそれ自身で語っています。 省略記号は、記述形式文字列のパラメーター置換として機能します。 いつものように、パーセント記号があります。

私の知識を深めるために、公式文書これを読むことをお勧めします。

頑張って

Source: https://habr.com/ru/post/J129896/


All Articles