読者です 読者をやめる 読者になる 読者になる

swiftでテストモジュールから,アプリケーションモジュールのクラスを呼び出す

iOS swift プログラミング

swiftでのテスト界隈だと,Quickなんかが最近期待されていますね.


[Swift] Quick で振る舞いテストをしてみよう | Developers.IO


でもそんなことを無視して,従来通りのXCTestでユニットテストを組んでいます.

swift名前空間

いずれにしろぶつかる問題として,普通に書こうとすると,テストコード内でアプリケーションのクラスが呼び出せない,というのがあります.



テストターゲットからアプリターゲットを参照する #Swift - Qiita

SwiftのコードはXcodeのターゲット単位がモジュール=ネームスペースとして扱われるようです。



Swiftでテストケースを書く際の疑問 - まさたか日記

名前空間がモジュール別なので、ターゲットモジュールとテストモジュールが別ということはテストケースからテスト対象が見えない。。。

というように,swiftにおいては,プロジェクトのターゲットモジュールがそれぞれ名前空間になっています.
そのため,アプリケーションモジュールとテストモジュールでは名前空間が別ということになります.
そりゃ,当然テストモジュール側から,そのままではアプリケーションモジュールのクラスが参照できるはずがないですね.



上記記事では,importにより呼び出しをかけていますが,この対応方法ではpublicクラスでないと呼び出せないという問題があります.

テストを書くために,テストターゲットを全部publicにするって,それはなんかおかしいんでない?


Target Membershipを広げれば良い

importするんじゃない方法で呼び出せないかなぁーと悩んでいたのですが,いけました.

アプリケーションモジュールの各クラスの,Target MembershipにTestsを含めるように変更します.

f:id:h3poteto:20150225162125p:plain

こうすることで,テスト側からでも全てのクラスが参照できるようになります.

必要なライブラリを入れる

外部から取り込んだFrameworksを取り込んでやる必要があります.
ここではあくまで,cocoapods経由以外のライブラリのみの話をしています.
cocoapodsについては後述.


Projectの設定画面で,Tests Targetを選んで,Build Phase->Link binary With Librariesに必要なライブラリを突っ込みます.

f:id:h3poteto:20150225162116p:plain

cocoapodsも動くように

BridgingHeaderの設定

cocoapodsでObjective-Cのソースを読み込むために,BridgingHeaderの設定をしている場合は,それを先に行います.

これをやらないと,podで読み込んでいるObjective-Cのソースがみつけられないので,

Use of undeclared type 'hogehoge'

と,いっぱい怒られます.

Projectの設定画面で,Tests Targetを選びます.
Build Settings->Swift Compiler - Code Generation->Objective-C Bridging HeaderにアプリケーションのBridgingHeaderを指定します.

f:id:h3poteto:20150225162121p:plain

cocoapodsの設定

次に,cocoapodsを使えるようにします.

これをやらないと,BridingHeader内で呼び出すライブラリや,importしているライブラリがみつけられないので,

'hogehoge.h' file not found
failed to import bridging header 'BridgingHeader.h'

と言われます.



Projectの設定画面で,Projectを選びます.
Info->Configurations->Debug->ApplicationName->ApplicationNameTestsにPod.debugを指定します.

f:id:h3poteto:20150225162040p:plain


これで,ようやくTestsのプロジェクトが正常に動くようになるので,存分にテストコードを書くことができます.
ちなみにTargetを複数にしたということは,環境変数を設定しているような場合も,同じくTests側に設定してやる必要があります.