4.3K Views
February 29, 24
スライド概要
モダンなアプリを作ることも難しいですが、期待した結果を得られるテストを書くことも難度が高いです。特に、非同期処理を行うコードに対して読みやすい単体テストを効率よく書くことは、かなり大変だと思いませんか?
この問題に対処するために、医療関係者間コミュニケーションアプリ Join の iOS 版では Quick/Nimble というフレームワークを導入し、一般的な単体テストからビヘイビア駆動テストに切り替えました。
本登壇では、ビヘイビア駆動テストの考え方や特徴について紹介します。また、実際に Join の iOS アプリで Quick/Nimble を活用しつつ、どのようにビヘイビア駆動テストを実装しているかを具体例とともにお話しします。
DeNA が社会の技術向上に貢献するため、業務で得た知見を積極的に外部に発信する、DeNA 公式のアカウントです。DeNA エンジニアの登壇資料をお届けします。
© DeNA Co., Ltd.
⾃⼰紹介 沢海 りあ奈(Riana Soumi) 配属 アルム研究開発部Joinプロダクトグループ 担当 iOSエンジニア 趣味 旅⾏、Vlogを撮ること @riana_soumi © DeNA Co., Ltd. 2
Joinとは 医療関係者間コミュニケーションアプリ ⽇本で初めて保険診療の適⽤が認められたプログラム医療機器である iOS‧Android‧Webブラウザ対応 世界累計32か国で導⼊実績あり © DeNA Co., Ltd. 3
Joinの特徴 コミュニケーションの活性化 チャット‧画像共有‧通知‧⾳声/ビデオ通話などの多様な⼿段により、 いつでもどこでも円滑で効果的な情報共有が可能 © DeNA Co., Ltd. 4
Joinの特徴 院内システムと連携 院内システムと連携することで、クラウドサーバーにある医⽤画像をメンバー間で共有できる。 標準搭載されたDICOMビューワーを利⽤し、MRI‧CTなどの医⽤画像の表⽰や、画像上への書込み編集‧保存が可能 リアルタイム動画配信 病棟やICU、⼿術室などにカメラを設置することで、 リアルタイムに配信された映像を病院内‧外でもチェックすることができる。 © DeNA Co., Ltd. 5
この発表で伝えたいこと © DeNA Co., Ltd. 6
Quick / Nimbleを使って iOSアプリのテストを改善しよう © DeNA Co., Ltd. 7
XCTestで書いたテストは何が問題なのか? © DeNA Co., Ltd. 8
RESTServiceのメソッド © DeNA Co., Ltd. 9
RESTServiceのメソッド © DeNA Co., Ltd. XCTest 10
RESTServiceのメソッド XCTest ・分かりやすい ・読みやすい ・一つのテストに対して一つのアサーション © DeNA Co., Ltd. 11
ViewModelのメソッド © DeNA Co., Ltd. 12
ViewModelのメソッド © DeNA Co., Ltd. 13
ViewModelのメソッド ‧コードが読みにくい © DeNA Co., Ltd. 14
ViewModelのメソッド ‧コードが読みにくい ‧コメントがないと何を処理しているかわからない © DeNA Co., Ltd. 15
ViewModelのメソッド ‧コードが読みにくい ‧コメントがないと何を処理しているかわからない ‧⼀つのテストに対して複数のアサーション © DeNA Co., Ltd. 16
ViewModelのメソッド ‧コードが読みにくい ‧コメントがないと何を処理しているかわからない ‧⼀つのテストに対して複数のアサーション ‧XCTestExpectationのコードが多い © DeNA Co., Ltd. 17
どうすれば改善できるか? © DeNA Co., Ltd. 18
ビへイビア駆動テストを導⼊してみた! © DeNA Co., Ltd. 19
ビヘイビア駆動テストとは テスト対象は実装ではなく、振る舞いが対象 © DeNA Co., Ltd. 20
ビヘイビア駆動テストとは テスト対象は実装ではなく、振る舞いが対象 特徴 ‧メソッドに対してテストを書く © DeNA Co., Ltd. → 各振る舞いに対してテストを書く 21
ビヘイビア駆動テストとは テスト対象は実装ではなく、振る舞いが対象 特徴 ‧メソッドに対してテストを書く → 各振る舞いに対してテストを書く ‧テスト名がメソッド名から引っ張られている → テスト名が振る舞いに沿った名前を付ける © DeNA Co., Ltd. 22
ビヘイビア駆動テストとは テスト対象は実装ではなく、振る舞いが対象 特徴 ‧メソッドに対してテストを書く → 各振る舞いに対してテストを書く ‧テスト名がメソッド名から引っ張られている → テスト名が振る舞いに沿った名前を付ける ‧実装が変わったら、既に書いたテストを修正する → 実装が変わってもテストを修正する必要がない © DeNA Co., Ltd. 23
iOSアプリにビヘイビア駆動テストを導⼊するなら © DeNA Co., Ltd. 24
iOSアプリにビヘイビア駆動テストを導⼊するなら Quick / Nimble © DeNA Co., Ltd. 25
Quickとは テストの⽂法を提供するビヘイビア駆動テストのフレームワーク Ruby製のBDDフレームワークであるRSpecなどにインスパイアされている Nimbleとは アサーションの⽂法を提供するフレームワーク アサーションとはアプリが期待する動作をしているか確認するステップ QuickとNimbleは組み合わせで使⽤するのは⼀般的 © DeNA Co., Ltd. 26
Quick / Nimbleテストの⽂法 © DeNA Co., Ltd. 27
Quick / Nimbleテストの⽂法 ‧QuickSpecのサブクラスを作る © DeNA Co., Ltd. 28
Quick / Nimbleテストの⽂法 ‧QuickSpecのサブクラスを作る ‧spec()メソッドをオーバーライドし、テストを追加する © DeNA Co., Ltd. 29
Quick / Nimbleテストの⽂法 ‧QuickSpecのサブクラスを作る ‧spec()メソッドをオーバーライドし、テストを追加する テストの構造 ‧describe(テストのグループ化) © DeNA Co., Ltd. 30
Quick / Nimbleテストの⽂法 ‧QuickSpecのサブクラスを作る ‧spec()メソッドをオーバーライドし、テストを追加する テストの構造 ‧describe(テストのグループ化) ‧context(テストの条件) © DeNA Co., Ltd. 31
Quick / Nimbleテストの⽂法 ‧QuickSpecのサブクラスを作る ‧spec()メソッドをオーバーライドし、テストを追加する テストの構造 ‧describe(テストのグループ化) ‧context(テストの条件) ‧it(振る舞いのテスト) © DeNA Co., Ltd. 32
Quick / Nimbleテストの⽂法 ‧QuickSpecのサブクラスを作る ‧spec()メソッドをオーバーライドし、テストを追加する テストの構造 ‧describe(テストのグループ化) ‧context(テストの条件) ‧it(振る舞いのテスト) ‧beforeEach(テスト実⾏する前のセットアップ処理) © DeNA Co., Ltd. 33
Quick / Nimbleテストの⽂法 ‧QuickSpecのサブクラスを作る ‧spec()メソッドをオーバーライドし、テストを追加する テストの構造 ‧describe(テストのグループ化) ‧context(テストの条件) ‧it(振る舞いのテスト) ‧beforeEach(テスト実⾏する前のセットアップ処理) ‧afterEach(テスト実⾏された後のリセット) © DeNA Co., Ltd. 34
Quick / Nimbleテストの⽂法 ‧QuickSpecのサブクラスを作る ‧spec()メソッドをオーバーライドし、テストを追加する テストの構造 ‧describe(テストのグループ化) ‧context(テストの条件) ‧it(振る舞いのテスト) ‧beforeEach(テスト実⾏する前のセットアップ処理) ‧afterEach(テスト実⾏された後のリセット) ‧expect(…).to(期待される結果を確認する) © DeNA Co., Ltd. 35
XCTestの問題点をQuick / Nimbleで解決していく 問題点 ‧コードが読みにくい ‧コメントがないと何を処理しているかわからない ‧⼀つのテストに対して複数のアサーション ‧XCTestExpectationのコードが多い © DeNA Co., Ltd. 36
ViewModelのメソッド © DeNA Co., Ltd. 37
XCTest © DeNA Co., Ltd. 38
XCTest ← テスト⽤のセットアップ © DeNA Co., Ltd. 39
XCTest ← © DeNA Co., Ltd. resentMessageObservableは 期待されている値を発⾏することを確認 40
XCTest ← © DeNA Co., Ltd. errorsObservableは 値を発⾏しないことを確認 41
Quick / Nimble © DeNA Co., Ltd. 42
Quick / Nimble ← テスト⽤のセットアップ © DeNA Co., Ltd. 43
Quick / Nimble ← © DeNA Co., Ltd. resentMessageObservableは 期待されている値を発⾏することを確認 44
Quick / Nimble ← © DeNA Co., Ltd. errorsObservableは 値を発⾏しないことを確認 45
XCTest © DeNA Co., Ltd. Quick / Nimble 46
XCTest Quick / Nimble コードが読みにくい © DeNA Co., Ltd. コードがブロック単位で分けているので読みやすい 47
XCTest Quick / Nimble コメントがないと何を処理しているかわからない © DeNA Co., Ltd. テスト名がコメントの代わりになっているので コメントが不要 48
XCTestの問題点をQuick / Nimbleで解決していく 問題点 ✅ コードが読みにくい ✅ コメントがないと何を処理しているかわからない ‧⼀つのテストに対して複数のアサーション ‧XCTestExpectationのコードが多い © DeNA Co., Ltd. 49
XCTest © DeNA Co., Ltd. Quick / Nimble 50
XCTest © DeNA Co., Ltd. Quick / Nimble 51
XCTest © DeNA Co., Ltd. Quick / Nimble 52
XCTest Quick / Nimble テスト数が増えたが、 各テストに対して⼀つだけのアサーションがあるため、 テスト失敗の判明がしやすい © DeNA Co., Ltd. 53
XCTestの問題点をQuick / Nimbleで解決していく 問題点 ✅ コードが読みにくい ✅ コメントがないと何を処理しているかわからない ✅ ⼀つのテストに対して複数のアサーション ‧XCTestExpectationのコードが多い © DeNA Co., Ltd. 54
XCTest © DeNA Co., Ltd. 55
XCTest © DeNA Co., Ltd. Quick / Nimble 56
XCTest © DeNA Co., Ltd. Quick / Nimble 57
Async / Await © DeNA Co., Ltd. 58
Async / Await XCTest © DeNA Co., Ltd. 59
Async / Await XCTest © DeNA Co., Ltd. Quick / Nimble 60
XCTestの問題点をQuick / Nimbleで解決していく 問題点 ✅ コードが読みにくい ✅ コメントがないと何を処理しているかわからない ✅ ⼀つのテストに対して複数のアサーション ✅ XCTestExpectationのコードが多い © DeNA Co., Ltd. 61
Quick / Nimbleについてもっと知りたい場合、下記のURLをご確認ください ‧Quick (⽇本語もあり) ‧Nimble © DeNA Co., Ltd. 62
まとめ Quick / Nimbleを使うと ‧コードが読みやすくなる ‧コメントがほぼ不要になる ‧テスト失敗の時に原因が判明しやすくなる ‧⾮同期処理のテストがより簡潔になる © DeNA Co., Ltd. 63