2017-10-17 9 views
4

私はXCTestの@testableの裏で何が起こっていますか?

@testable import MyModule 

は(「testTarget」で構築された)「テスト」モジュールMyModuleTestsからMyModuleの非パブリックメンバーを探索する能力を与えることを知っています。

"非テスト"モジュールで同じ機能が必要です。本番環境ではなく、デバッグモードです。

私の質問です:あなたはこれを行う方法を知っていますか?

関連性があります(私は難しいと思います)。@testableの後ろには実際にどのような魔法が起こっていますか?

+0

*実際には@ testableの後ろで何が起こっているのですか?コンパイラのように見えません。 – Caleb

+0

私は裏で起こっていることに答えることができる唯一の人はアップルの従業員だと思います。 – JAL

答えて

13

あなたの質問に答えるために、デバッグの目的でこれを実際に使用することができます。たとえば、ワークスペースがMyAwesomeWkspace、プロジェクトがMyAwesomeProjectであるとします。

今度はMyAwesomeModuleと呼ばれるmoduleという新しいframeworkを作成します。そのモジュールの中でPersonと呼ばれる非公開クラスを作成します。

あなたがimport MyAwesomeModuleを行うことによってMyAwesomeProject内のクラスPersonを使用しようと、その後let p = Person()のようなもの場合は、エラーになります。

しかし、@testable import MyAwesomeModuleを実行すると、魔法が発生し、クラスを使用できるようになります。

基本的に@testableは、あなたが公表しなかったものをテストすることができます。この注釈はimportと表示されます(here参照)。

したがって、非公開のメンバーにアクセスできるように、ターゲットは-enable-testingでコンパイルされます。デフォルトでは、debugビルド構成が-enable-testing、私はあなたが動作する示した例でコンパイルされている、ので、少なくともhere

何に基づきます。しかし、ビルドの設定をreleaseに変更すると、releaseの設定がフラグで構築されていないので、エラーはModule .. was not compiled for testingと表示されます。スウィフトプログラミング言語のアクセス制御 部(スイフト4)に記載のように

スウィフトアクセス制御モデル、アプリ またはフレームワークに内部として宣言何にアクセス 外部エンティティを防止します。デフォルトでは、 テストコードからこれらのアイテムにアクセスできるようにするには、アクセスレベルを少なくとも に上げる必要があり、Swiftのタイプセーフティのメリットはありません。

Xcodeのは、この問題には2部構成のソリューションを提供します:あなたは、テストのために、デフォルトで 真実であるはい]に設定を有効にテスタビリティのビルドを設定すると、新しいプロジェクトで構築し

、Xcodeは -enable-を含みコンパイル中にフラグをテストします。これにより、コンパイルされたモジュールで宣言されたSwiftエンティティは、より高いレベルのアクセスに適しています。 テストを有効にしてコンパイルした モジュールのインポートステートメントに@testable属性を追加すると、そのスコープ内のそのモジュールに対して昇格アクセス が有効になります。 内部または公開としてマークされたクラスおよびクラスメンバは、openとマークされているかのように動作します。他のエンティティ は、内部としてマークされているかのように、publicとして宣言されています。

もっとhere

後期編集:SWIFTのクールな部分の1つは、それがオープンソースです。もしあなたが "魔法"に深く没頭したいのであれば、それをチェックしてみてください:https://github.com/apple/swift

関連する問題