0
0

More than 1 year has passed since last update.

ViewInspectorを使用したWebViewテストの雛形

Last updated at Posted at 2023-08-25

ViewInspectorでWebViewのテストを書こうとしてハマったので備忘録。

作成したサンプルコード

どの辺でハマったか。

UIViewControllerに処理を書かないと始まらない。

UIViewControllerviewDidLoadを実行するには、view.loadViewIfNeeded()を実行しないと処理が始まらない。
当然ViewInspectorもUIViewControllerを取り出さないと処理が始まらない。

sut.on(\.didAppear) { view in
  let uiView = try view.view(WebUIViewControllerRepresentable.self).actualView().viewController()
  uiView.loadViewIfNeeded()
}

Viewに書いたdidAppearが機能しなくなる

ContentViewにenvironmentObjectを設定するとdidAppearでエラーが出るようになりました。

struct ContentView: View {
  var didAppear: ((Self) -> Void)?
  var body: some View {
    VStack {
      WebUIViewControllerRepresentable()
    }
    .padding()
  }
}
// こう書くとdidAppearが機能しない
var sut = ContentView().environmentObject(param)

// 正しくはこうする
var sut = ContentView()
ViewHosting.host(view: sut.environmentObject(param))

処理の完了通知を受け取りたい

もう少しいい方法あるだろうけど簡易なもので。

// ObservableObjectでVoidを作成
class Param: ObservableObject {
  @Published var exception: (String) -> Void = { _ in }
}

// テスト完了通知のクロージャーを作成
let exp = XCTestExpectation(description: "didAppear")
let param = Param()
param.exception = { message in
  XCTAssertEqual(message, "complete")
  exp.fulfill()
}

// HTMLを読み込んだら完了通知
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    if isRunningTests() {
      parent.param.exception("complete")
    }
}

おわりに

以上です。
ViewInspectorでWebViewのサンプルコードを見かけなかったので書いて見ました。
無駄に時間を使う人が減れば幸いです。

追記

UIViewControllerUIViewControllerRepresentableに統合して最適化したところ、loadViewIfNeededを呼ばなくても動作するようになった。
それでいいのか?

コード

ファイル数が少ないので掲載。
小さいコードに構造まとめるの大事ですね。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0