Skip to content

Compose Multiplatform UI 測試環境設定與疑難排解

Yu-Chan (Henry) Huang edited this page May 22, 2026 · 3 revisions

在重構 OmniHub 專案並導入 runComposeUiTest 時,我們在 WasmJS 與 Android Host Test 平台上遇到了一些環境配置導致的測試失敗。本文件記錄了這些問題的原因與修復方法。

1. WasmJS: 編譯與 Webpack 警告

為什麼會錯?

WasmJS 平台在執行測試時,會透過 Webpack 進行打包。由於 Compose 的圖形引擎 (Skiko) 使用了動態依賴載入,導致 Webpack 無法進行靜態分析並噴出警告。此外,Kotlin 2.0+ 對於 WasmJS 的互操作性 (Interop) 有更嚴格的實驗性 API 限制。

錯誤訊息

  • Critical dependency: the request of a dependency is an expression
  • This declaration needs opt-in. Its usage should be marked with '@kotlin.js.ExperimentalWasmJsInterop'

如何解決?

  1. 忽略 Webpack 警告: 在 shared/src/wasmJsMain/resources/webpack.config.d/config.js 加入腳本,強制 Webpack 忽略 Skiko 引起的動態依賴警告。
  2. 開啟編譯器許可: 在 shared/build.gradle.kts 的 wasmJs 區塊中加入編譯參數:
    wasmJs {
        compilerOptions {
            freeCompilerArgs.add("-opt-in=kotlin.js.ExperimentalWasmJsInterop")
        }
    }

2. Android Host Test: Robolectric 環境配置

為什麼會錯?

當 UI 測試寫在 commonTest 並在 Android Target 上執行時,如果是在電腦的 JVM 上跑(而非實體機),這被稱為 Host Test。純 JVM 並不具備 Android 的系統屬性與 Activity 執行環境。

錯誤訊息

  1. NPE: Cannot invoke "String.toLowerCase()" because "android.os.Build.FINGERPRINT" is null
    • 原因:runComposeUiTest 試圖讀取 Android 系統資訊,但純 JVM 環境沒有這些資料。
  2. RuntimeException: Unable to resolve activity for Intent { ... ComponentActivity }
    • 原因:測試環境找不到可以承載 UI 的 Activity 宣告。

如何解決?

Clone this wiki locally