40

単体テストを使用して新しいプロジェクトを作成する場合、Xcodeはビルド構成をテストスキームのデバッグに設定します(実行スキームの場合も同じです)。

実行(Command-R)スキームとテスト(Command-U)スキームを区別する必要がありますか?

つまり、Testという新しいビルド構成を作成し、それにプリプロセッサマクロTEST = 1を追加して、代わりにTestスキームのビルド構成として使用する必要がありますか?または、実行とテストの両方をデバッグとして保持する必要がありますか?

私はRuby/Railsのバックグラウンドを持っており、通常、テスト、開発、および実稼働環境があります。デバッグは開発のようなもので、リリースは本番のようなものだと私には思えますが、テストが不足しているため、テストを追加するのが理にかなっていると思います。

コメント?意見?提案?

Test用に何かをコンパイルしたいので、私は特にこれを求めています:

#ifdef TEST
// Do something when I test.
#endif

これもデバッグ用にコンパイルしても問題ないと思います。だから、私は本当にすることができました:

#ifdef DEBUG
// Do something when I run or test.
#endif

しかし、私は実際には今のところテストのためにそれをするつもりです。だから、私はデバッグとテストを区別する必要があると思っているのですが、なぜXcodeがデフォルトでそれを行わないのか疑問に思っていますか?Appleはあなたがそれらを区別すべきではないと思いますか?

4

11 に答える 11

35

プリプロセッサマクロは機能しません。実行時に環境を確認する必要があります。

Objective-c

static BOOL isRunningTests(void)
{
    NSDictionary* environment = [[NSProcessInfo processInfo] environment];
    return (environment[@"XCTestConfigurationFilePath"] != nil);
}

迅速

var unitTesting : Bool 
{
    return ProcessInfo.processInfo.environment["XCTestConfigurationFilePath"] != nil
}

(Xcode 11用に更新)

于 2014-01-15T14:53:41.957 に答える
30

新しいビルド構成を追加することを検討してください。

xcode 4で、左側のナビゲーターでプロジェクトをクリックします。

メインウィンドウでプロジェクトをクリックし、[情報]タブを選択します。

「+」ボタンをクリックして、新しい構成を追加します(必要に応じて「テスト」と呼ぶことができます)。

次に、ターゲットをクリックして、[ビルド設定]タブに移動します。

「プリプロセッサマクロ」を検索する

ここで、新しいビルド構成のプリプロセッサマクロを追加できます。

新しい「テスト」構成をダブルクリックして、TESTING=1を追加するだけです。

最後に、ビルドスキームを編集します。スキームのテストオプションを選択します。「ビルド構成」ドロップダウンメニューがあるはずです。「テスト」構成を選択します。

于 2013-02-05T23:27:50.040 に答える
25

テストビルド構成を作成する代わりに、次のようにします。

  1. Tests-Prefix.pchファイルを作成しました:

    #define TEST 1
    #import <SenTestingKit/SenTestingKit.h>
    #import "CocoaPlant-Prefix.pch"
    
  2. Testsターゲットのビルド設定のPrefixHeaderフィールドにパスを入力しました。

  3. MyAppDefines.h私が作成した、インポートされたファイルの先頭に次のコードを追加しましたMyApp-Prefix.pch

    #ifdef TEST
    #define TEST_CLASS NSClassFromString(@"AppDelegateTests") // any test class
    #define BUNDLE [NSBundle bundleForClass:TEST_CLASS]
    #define APP_NAME @"Tests"
    #else
    #define BUNDLE [NSBundle mainBundle]
    #define APP_NAME [[BUNDLE infoDictionary] objectForKey:(NSString *)kCFBundleNameKey]
    #endif
    

これにより、私がBUNDLE意味するところならどこでも使用でき、[NSBundle mainBundle]テストを実行するときにも機能させることができます。

また、SenTestingKitをインポートするTests-Prefix.pchと、SenTestingKitフレームワークのコンパイルが高速化され、#import <SenTestingKit/SenTestingKit.h>すべてのテストファイルの先頭から除外できるようになります。

于 2011-07-20T14:34:34.470 に答える
16

Robertが行ったisRunningTests()の提案を使用する代わりに、コード自体に環境変数のチェックを追加することにしました。

  1. 現在のスキーム(製品/スキーム/スキームの編集)またはCommand+<を編集します
  2. テスト構成をクリックします
  3. [引数]をクリックし、[実行アクションの引数と環境変数を使用する]のチェックを外します
  4. [環境変数]セクションを展開し、値YESで変数TESTINGを追加します
  5. これをコードのどこかに追加すると、必要なときにいつでも呼び出すことができます。
 + (BOOL) isTesting
    {
        NSDictionary* environment = [[NSProcessInfo processInfo] environment];
        return [environment objectForKey:@"TESTING"] != nil;
    }

完了すると、画面は次のようになります。

画面は次のようになります

上記のコードは、テストモードまたはアプリケーションモードで実行しているときにTESTING環境変数を検出します。このコードは、単体テストファイルではなく、アプリケーションに含まれます。使用できます

#ifdef DEBUG
...
#endif

コードが本番環境で実行されないようにするため。

于 2014-08-29T01:29:01.943 に答える
6

テストビルド構成を作成してから、ターゲットの「その他のSwiftフラグ」プロパティを「-DTEST」に設定すると、迅速なコードで機能するTESTマクロが定義されます。アプリのSwiftコードで使用できるように、アプリターゲットのビルド設定で設定してください。

DEBUGおよびTESTのその他のSwiftフラグ設定

次に、このセットを使用して、次のようにコードをテストできます。

func testMacro() {
   #if !TEST 
       // skipping over this block of code for unit tests
   #endif
}
于 2018-06-10T22:12:05.670 に答える
5

SWIFT 3.0でのロバートの答え:

func isRunningTests() -> Bool {
    let environment = ProcessInfo().environment
    return (environment["XCInjectBundleInto"] != nil);
}
于 2017-04-02T11:00:55.347 に答える
3

私は非常に長い間テストし、結果を見つけました:

preproessorマクロを単体テストターゲットに追加するだけでなく( 単体テスト専用の変数を使用する多くのメソッドを使用でき、@ MattDiPasqualeメソッドに従うことができます)、

ただし、テストターゲットに条件準拠ファイルを追加する必要があります。このファイルには新しいプリプロセッサマクロがあるため、このファイルを再コンパイルする必要がありますが、このファイルには、プリプロセッサマクロが設定されていないときにアプリケーションターゲットが組み込まれています。

これがお役に立てば幸いです。

于 2012-12-18T07:43:46.137 に答える
2

Xcode10用に更新:

static let isRunningUnitTests: Bool = {
    let environment = ProcessInfo().environment
    return (environment["XCTestConfigurationFilePath"] != nil)
}()
于 2018-11-26T17:15:54.920 に答える
0

環境変数を調べて、単体テストが実行されているかどうかを確認します。ロバートの答えに似ていますが、パフォーマンスのために一度だけチェックします。

+ (BOOL)isRunningTests {
   static BOOL runningTests;
   static dispatch_once_t onceToken;

   // Only check once
   dispatch_once(&onceToken, ^{
      NSDictionary* environment = [[NSProcessInfo processInfo] environment];
      NSString* injectBundle = environment[@"XCInjectBundle"];
      NSString* pathExtension = [injectBundle pathExtension];
      runningTests = ([pathExtension isEqualToString:@"octest"] ||
                      [pathExtension isEqualToString:@"xctest"]);
   });
   return runningTests;
}
于 2014-11-06T20:01:20.877 に答える
0

iOSでは、単体テストの実行中[UIApplication sharedApplication]に戻ります。nil

于 2015-11-18T18:45:09.350 に答える
0

Xcode8.3.2で機能するKevの回答の修正バージョン

+(BOOL)isUnitTest {

    static BOOL runningTests;
    static dispatch_once_t onceToken;

    // Only check once
    dispatch_once(&onceToken, ^{
        NSDictionary* environment = [[NSProcessInfo processInfo] environment];
        if (environment[@"XCTestConfigurationFilePath"] != nil && ((NSString *)environment[@"XCTestConfigurationFilePath"]).length > 0) {
            runningTests = true;
        } else {
            runningTests = false;
        }
    });
    return runningTests;
}
于 2017-08-13T17:55:37.790 に答える