📑

Swift Unit Testで"Undefined symbol"が流れるときの原因と実践対処ノート

に公開

はじめに

SwiftUIプロジェクトでUnit Testを実行した際、以下のようなリンカーエラーが発生しました。

Undefined symbol: type metadata for <AppModule>.<EnumName>
Undefined symbol: <AppModule>.<ViewModelName>.<PropertyName>.getter
Undefined symbol: <AppModule>.<ViewModelName>.<MethodName>() -> ()
...
Linker command failed with exit code 1

https://developer.apple.com/documentation/xcode/testing_your_apps_in_xcode


原因を深掘りする

1. Test PlanにTest Targetが含まれていない

なぜ起こる?

  • 自動生成された.xctestplanファイルはデフォルトで空の状態。明示的にターゲットを追加しない限り、テスト対象が存在しない扱いになる。

何が問題?

  • 実行時に「No Tests」と表示され、Unit Test自体が走らない。

対処法

  • .xctestplanファイルを開き、「Choose Targets」でUnit/UI Testターゲットを選択して保存する。

https://developer.apple.com/documentation/xcode/adding-tests-to-your-xcode-project


2. Defines Moduleが無効になっている

なぜ起こる?

  • Swiftのモジュールは、Defines Module = Yesにしないと、外部から型情報を認識できない仕様になっている。

何が問題?

  • @testable importを使った際、Appターゲットの型情報が見えず、Undefined Symbolエラーが発生する。

対処法

  • AppターゲットのBuild Settingsで「Defines Module」をYesに設定する。

https://developer.apple.com/documentation/xcode/build-settings-reference#Defines-Module


3. Host Applicationの設定がされていない

なぜ起こる?

  • Unit Testターゲットでは、実行対象のアプリケーション(Host Application)を指定しないと、リンクエラーになる。

何が問題?

  • テスト対象のクラスや関数にアクセスできず、ビルド失敗に直結する。

対処法

  • TestターゲットのGeneralタブで、正しいAppターゲットをHost Applicationとして設定する。

https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/UnitTesting/02-Setting_Up_Unit_Tests_in_a_Project/setting_up.html


4. Build Phasesにソースファイルが含まれていない

なぜ起こる?

  • 新規追加した.swiftファイルがTarget Membershipには追加されても、Build PhasesのCompile Sourcesに入っていない場合がある。

何が問題?

  • リンク対象に含まれないため、実行時にシンボル解決エラーが発生する。

対処法

  • AppターゲットのBuild Phases > Compile Sourcesに対象.swiftファイル(例: <ViewModelName>.swift)を手動で追加する。

https://developer.apple.com/documentation/xcode/customizing-the-build-phases-of-a-target


実際に行った対処まとめ

  • Test Planにターゲットを追加する
  • Defines ModuleをYesに設定する
  • Host Applicationを正しく設定する
  • Build Phaseに必要なソースファイルを追加する
  • クリーンビルド(Shift + Command + K)を実施する

まとめ:Unit Test地雷マップ

  • Target Membershipだけで安心しない
  • Defines ModuleとHost Applicationの設定を必ず確認する
  • Swift Package Manager導入時とのビルド挙動の違いに注意する

特に**@testable import**を多用する環境では、モジュール設定やホストアプリ設定を少しでもミスすると、Undefined Symbolエラーが頻発するので要注意です。

これを読んだ誰かが、同じ地雷を踏まずに済むことを願って。


参考リンク

https://developer.apple.com/documentation/xcode/defining_modules_in_xcode
https://developer.apple.com/documentation/xcode/testing_your_apps_in_xcode
https://developer.apple.com/documentation/xcode/adding-tests-to-your-xcode-project
https://developer.apple.com/documentation/xcode/customizing-the-build-phases-of-a-target
https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/UnitTesting/02-Setting_Up_Unit_Tests_in_a_Project/setting_up.html

Discussion