web-dev-qa-db-ja.com

Xcodeプロジェクトは、プログラムでターゲットを検出する方法、またはenvvarsを使用する方法

いくつかのjsonを解析し、コアデータに保存し、いくつかのオブジェクトを読み取るアプリケーションテストを実行したいと思います。

コードがテストの一部として実行されているのか、通常の実行として実行されているのかをコードで知るにはどうすればよいですか? 「私たちはテストターゲットにいますか」を知るための何らかの方法はありますか?アプリが起動すると、サーバーからの情報をコアデータに入力するための一連のリクエストが開始されます。テスト中にこれを実行したくありません。アプリを起動し、ファイルからHARDCODED jsonを読み取り、これを他の方法と同じ方法でcoredataに保存し、結果を確認します。

アプリ内から読み取ることができる特定のキーと値のペアをターゲットごとに渡す方法を誰かが説明できれば、さらに嬉しく思います。

30
jpswain

気にしないでください...これを設定するのは「スキーム」にあることがわかりました。

たとえば、テスト中にTARGET = TESTを使用可能にして、実行中にTARGET = RUNを表示したい場合は、Scheme> Environment Variables> Name/Valueで設定します。

次に、あなたのアプリから次のことができます:

[[[NSProcessInfo processInfo] environment] objectForKey:@"TARGET"]

プリプロセッサマクロでビルド設定を使用するDID私には機能しませんb/c私のテストターゲット(アプリケーション/統合テスト用)は私のメイン(テストではない)ターゲットに依存しているため、メインターゲットがビルドされます最初にそれが実行され、実行したターゲットで定義されたマクロよりも後であっても、最終的にメインターゲットプリプロセッサマクロになります。ここで何かを見逃した場合は、誰かが自由に説明してください。

34
jpswain

「テストターゲット」とは、ユニットテスト(つまり、Product > Testまたは⌘U)を意味する場合、プリプロセッサマクロをターゲットに追加し、コード内でそのマクロを確認できます。これにより、次のようなことが可能になります。

#ifdef TEST
  // Load the hard-coded data.
#else
  // Load data from the server.
#endif

これを行うには、プロジェクトナビゲータでプロジェクトファイルをクリックし、テストターゲットを選択し、[Build Settings]タブをクリックして、「マクロ」を検索し、Preprocessor Macrosオプションをダブルクリックして、追加します。

10
Chris Doble

対処すべき状況は2つあります。

  1. Testsなどの特定のターゲットが選択されている場合は、コードを実行し、
  2. 条件付きで#importTestsなどの特定のターゲットの一部のファイル。

テストターゲットのターゲットコード:

次のように、ProjectName-Prefix.pchファイルにマクロを作成します。

#define IsTestTarget [[[[NSProcessInfo processInfo] environment][@"XCInjectBundle"] pathExtension] isEqualToString:@"xctest"]

次に、アプリ内の任意の場所で呼び出します。

if (IsTestTarget) {
    //Do something specific for test target;
} else {
    //Otherwise do something else
}

条件付き#import

Testsターゲットが選択されているときに特定のファイルを#importするには、Preprocessor MacroTestターゲットに追加して次のように使用する必要があります。

#ifdef APPTESTS
    #import "TestSpecificFile.h"
#else
    #import "SomeOtherFile.h"
#endif 

Preprocessor Macroを追加する方法は次のとおりです。

enter image description here

6
Yas T.

以下の機能が利用できます。

+(BOOL)  isRunningTests
{
    NSDictionary* environment = [[NSProcessInfo processInfo] environment];
    NSString* injectBundle = environment[@"XCInjectBundle"];
    return [[injectBundle pathExtension] isEqualToString:@"xctest"];
}
5
muzz

通常、単体テストでは、プログラマーはモッククラスと機能を使用しています。テストターゲットのターゲットメンバーシップonlyを持つクラスを作成できます。

@interface MockClass : NSObject

@end

Target Membership Screenshot

次に、アプリケーションコードで、NSClassFromString関数を使用してクラスが存在するかどうかを確認できます(この場合、クラスのターゲットメンバーシップに含まれていないターゲット(この場合は、非テストターゲット)に対してNilを返します)。

if (NSClassFromString(@"MockClass")) {
    //Test Target
} else {
    //App Target
}

そしてあなたはそれを呪うことができます

BOOL isUnitTest(){
    return NSClassFromString(@"MockClass") != Nil;
}
0