Upgrade to Pro — share decks privately, control downloads, hide ads and more …

新規アプリの単体テスト戦略 / unit_tests_strategy_of_new_app

uhooi
October 28, 2022

新規アプリの単体テスト戦略 / unit_tests_strategy_of_new_app

uhooi

October 28, 2022
Tweet

More Decks by uhooi

Other Decks in Programming

Transcript

  1. ・UI: フル SwiftUI ・リアクティブ: Combine ・非同期処理: Swift Concurrency (async/await) ・アーキテクチャ:

    MVVM ・その他: SwiftPM によるマルチモジュール、KMM ※開発中なので変更される可能性が大いにあります。 新規アプリの技術選定
  2. ロジックを減らせば単体テストも減らせる View View
 Model UseCase KMM 少なくしたい 多くする : 単体テストを書かない

    : 必要に応じて単体テストを書く : 単体テストを書く View 層からロジックを なくすのが理想 ロジック
  3. View に分岐がある(Before) // Before // View 層 if viewModel.uiState.isLoading {

    Text("ロード中です。") } else { Text("ロードが完了しました。") }
  4. View から分岐をなくす(After) // After // View 層 Text(viewModel.uiState.loadingText) // ViewModel

    層 var loadingText: String { isLoading ? "ロード中です。" : "ロードが完了しました。" }
  5. View から分岐をなくす(After) // After // View 層 Text(viewModel.uiState.loadingText) // ViewModel

    層 var loadingText: String { isLoading ? "ロード中です。" : "ロードが完了しました。" } View 層の分岐を ViewModel 層に寄せる
  6. それでも View から分岐は完全にはなくせない // View 層 struct MonstersView: View {

    var body: some View { if viewModel.uiState.monsters.isEmpty { EmptyMonsterListView() } else { MonsterListView(monsters: viewModel.uiState.monsters) } } }
  7. それでも View から分岐は完全にはなくせない // View 層 struct MonstersView: View {

    var body: some View { if viewModel.uiState.monsters.isEmpty { EmptyMonsterListView() } else { MonsterListView(monsters: viewModel.uiState.monsters) } } } View の出し分けなどの 分岐はなくせない
  8. それでも View から分岐は完全にはなくせない // View 層 struct MonstersView: View {

    var body: some View { if viewModel.uiState.monsters.isEmpty { EmptyMonsterListView() } else { MonsterListView(monsters: viewModel.uiState.monsters) } } } View の出し分けなどの 分岐はなくせない monsters が空のときの UI の確認が手間
  9. UI フレームワークを View 層のみでインポートする View View
 Model UseCase KMM SwiftUI

    Combine : 単体テストを書かない : 必要に応じて単体テストを書く : 単体テストを書く View 層のみで UI を完結させる
  10. UI フレームワークを View 層のみでインポートする View View
 Model UseCase KMM SwiftUI

    Combine : 単体テストを書かない : 必要に応じて単体テストを書く : 単体テストを書く ViewModel 層以下がロジックに集中でき、 単体テストが書きやすくなる
  11. Task があると単体テストしにくい(Before) // Before // ViewModel 層 struct FooViewModel: ObservableObject

    { func didTapLoginButton() { Task { await login() } } } ログイン処理を待たずに テストが終了してしまう
  12. ViewModel 層のメソッドを非同期にする(After) // After // ViewModel 層 struct FooViewModel: ObservableObject

    { func didTapLoginButton() async { await login() } } 非同期にすると 並行処理もしやすくなる
  13. Task を View 層に書く(After) // After // View 層 struct

    FooView: View { // ... Task { await viewModel.didTapLoginButton() } // ... }
  14. まとめ View View
 Model UseCase KMM UI ロジック Task 単体テストを書かない層(View

    層)は プレビューや手動テストで品質を担保する 単体テストしにくい 単体テストしやすい