web-dev-qa-db-ja.com

XCTestCaseのsetUpメソッドの目的は何ですか?

XCTestCaseに関するsetUpのデフォルトテンプレート内のコメントに従って:

Put setup code here; it will be run once, before the first test case.

ただし、XCTestCase.hでは、上記のコメントsetUpは別の表現です。

Setup method called before the invocation of each test method in the class.

実際の動作を確認するために、NSLog within setUpを呼び出して、それが呼び出された回数をカウントします。

static int count = 0;

- (void)setUp
{
    [super setUp];
    count++;

    NSLog(@"Call Count = %d", count);
}

これにより、すべてのテストメソッドの前にsetUpメソッドが呼び出されました(XCTestCase.hに関するコメントを確認)。

setUpメソッドを使用してテスト/モックオブジェクトonceを作成したかった(たとえば、Core Dataテストスタックをセットアップしたい)。これらを何度も作成すると、プロセッサに負荷がかかり、非常に遅くなる可能性があります。

そう、

1)setUpは実際に何のために使用することを意図していますか?確かに開発者はその中にオブジェクトを何度も作成していませんか?

2)XCTestCase内でこれらのオブジェクトのみonceを作成するにはどうすればよいですか?

38
JRG-Developer

ここで説明するポイントは2つあります。setUpメソッドの動作、および一般的なベストテストプラクティスです。

実際には2つsetUpメソッドがあります。

_+ (void)setUp;
- (void)setUp;
_

クラスメソッド(+ (void)setUp)は、テスト実行全体で1回だけ実行されます。

インスタンスメソッド(- (void)setUp)は、デフォルトテンプレートのメソッドです。すべてのテストの前に実行されます。うまくいけば、Xcodeの仮想的な将来のバージョンでは、このコメントは_// Put setup code here. This method is called before the invocation of each test method in the class._ WINK WINKに変更されます

したがって、これら2つの方法を使用すると、説明した両方の動作が可能になります。

コメントについて:

「開発者はその中にオブジェクトを何度も作成していませんか?」

私の答えは「はい、通常そうです」です。 「良い」ユニットテストの人気の頭字語は最初です:

  • 速い
  • 孤立した
  • 繰り返し可能
  • 自己検証
  • タイムリーな

Isolatedはこの議論の鍵です:テストは、他のテストによって残された以前の状態に依存すべきではありません。理想的には、テストごとにメモリ内のコアデータスタックを破棄して再作成する必要があります。そうすることで、白紙の状態から始めることがわかります。良い例は Graham Leeによるこの投稿 です。インメモリスタックを使用したいのは、a)簡単に捨てることができること、b)インメモリスタックであり、ディスクにヒットしないため、非常に高速であることです。

Ifこの結果、テストの実行が遅いことがわかります(時期尚早に最適化しないでください)。次のステップとして、+ (void)setUpにスタックを作成するのが妥当だと思います。メソッドですが、- (void)setUpメソッドで毎回新しいコンテキストを作成します。

87
James Frost

私はほぼ同じ問題でここに来ました:setUpを実行する方法一度だけ、Swiftで。これが解決策です:

override class func setUp() {
    super.setUp()    
    // ...
}

override class func tearDown() {    
    // ...
    super.tearDown()
}

現在、私はまだasynchronoussetUp!の解決策を探しています。

4
Zeb