Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
自動テストでモックするって、なにそれ?おいしいの?/what_is_mocking
Search
marchin
April 14, 2022
Programming
1
1k
自動テストでモックするって、なにそれ?おいしいの?/what_is_mocking
marchin
April 14, 2022
Tweet
Share
More Decks by marchin
See All by marchin
ブラックフライデーで購入したPixel9で、Gemini Nanoを動かしてみた
marchin1989
1
540
Amazon Athenaで気軽に始める データ分析/athena-data-analytics
marchin1989
0
500
WebAPI開発のためのOpenAPI入門/entry-open-api
marchin1989
1
1.1k
AWS Glueではじめるデータレイク
marchin1989
0
560
やさしく入門するOAuth2.0/easy-entry-oauth
marchin1989
7
1.3k
1時間半で克服するJavaScriptの非同期処理/async_javascript_kokufuku
marchin1989
2
1.3k
たぶんもう怖くないGit/maybe-not-afraid-of-git-anymore
marchin1989
2
2.1k
モバイルアプリで機械学習入門/introduction-to-machine-learning-in-mobile-app
marchin1989
0
410
Other Decks in Programming
See All in Programming
今年のアップデートで振り返るCDKセキュリティのシフトレフト/2024-cdk-security-shift-left
tomoki10
0
210
情報漏洩させないための設計
kubotak
2
290
PHPで作るWebSocketサーバー ~リアクティブなアプリケーションを知るために~ / WebSocket Server in PHP - To know reactive applications
seike460
PRO
2
470
見えないメモリを観測する: PHP 8.4 `pg_result_memory_size()` とSQL結果のメモリ管理
kentaroutakeda
0
380
これが俺の”自分戦略” プロセスを楽しんでいこう! - Developers CAREER Boost 2024
niftycorp
PRO
0
190
これでLambdaが不要に?!Step FunctionsのJSONata対応について
iwatatomoya
2
3.7k
ドメインイベント増えすぎ問題
h0r15h0
2
350
range over funcの使い道と非同期N+1リゾルバーの夢 / about a range over func
mackee
0
110
テスト自動化失敗から再挑戦しチームにオーナーシップを委譲した話/STAC2024 macho
ma_cho29
1
1.3k
Exploring: Partial and Independent Composables
blackbracken
0
100
なまけものオバケたち -PHP 8.4 に入った新機能の紹介-
tanakahisateru
1
120
アクターシステムに頼らずEvent Sourcingする方法について
j5ik2o
4
290
Featured
See All Featured
Automating Front-end Workflow
addyosmani
1366
200k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
111
49k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
44
9.3k
Product Roadmaps are Hard
iamctodd
PRO
49
11k
A Tale of Four Properties
chriscoyier
157
23k
How to Ace a Technical Interview
jacobian
276
23k
Six Lessons from altMBA
skipperchong
27
3.5k
RailsConf 2023
tenderlove
29
940
Agile that works and the tools we love
rasmusluckow
328
21k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
Designing on Purpose - Digital PM Summit 2013
jponch
116
7k
Making Projects Easy
brettharned
116
5.9k
Transcript
自動テストでモックするって、 なにそれ?おいしいの? 〜依存コンポーネントをコントロールして、上手なテストコードを実装しよう〜
自己紹介 - 名前: 阿部 真之 - 仕事: 株式会社ゆめみ でAndroidエンジニアしてます -
最近はサーバサイド Kotlinの仕事も始めました - 趣味 - コーヒー、ビール、アニメ、ゲーム、読書、 etc… - Twitter: @marchin_1989
アジェンダ - ユニットテストの例 - テストダブルとは - テストダブルの分類(サンプルコードで解説) - その他注意点など
ユニットテスト書いてますか?
ユニットテスト コンピュータプログラミングにおいて単体テスト(たんたいテスト)あるいはユニットテスト (英語: Unit test)とは、ソースコードの個々のユニット、すなわち、1つ以上のコンピュー タプログラムモジュールが使用に適しているかどうかを決定するために、関連する制御 データ、使用手順、操作手順とともにテストする手法である。ユニットとはアプリケーショ ンのテスト可能な最小の部品単位である、と直観的にとらえることができる。 (Wikipedia) ここでは、自動テストの文脈でユニットテストをみていきます。
ユニットテストしてみよう
- テストダブルってなに? - モック、スパイ、ダミーとか聞いたことあるけど。。 テストダブル?
テストダブルとは? - テストダブルとは、テスト実行時に、テスト対象が依存している外部のコンポーネン トと置き換わるもの。 @Test fun `テストコード`() { assertEquals(期待値, テスト対象())
} fun テスト対象(): Int { … 依存コンポーネントのメソッド() … }
本番 テスト
なぜテストダブルに置き換えたいのか テスト対象が外部のコンポーネントに依存しており、テスト環境で利用できなかったり、 利用しづらかったりなど、制約(コスト、処理時間)があるとき。 - テストに必要な結果をコントロールできない(実行するたびに値が変わる) - 実行に時間がかかる - 用意するのにお金がかかる
テストダブルにはどんなものがあるの? - xUnit Test Patternsによる定義、分類が有名 - xUnit Test Patternsとは、テスト自動化フレームワークの xUnit(JUnitやNUnitなど)を使用して自動
テストを作成するためのパターン (本)。 - 分類 - ダミー(Dummy Object) - スタブ(Test Stub) - スパイ(Test Spy) - モック(Mock Object) - フェイク(Fake Object) 出典: xUnit Test Patterns Test Double http://xunitpatterns.com/Test%20Double.html
テストダブルの分類を知っておく利点 - それぞれの役割を理解しておくと、テストダブルに対して何をやらせばいいのか明 確になる。適切なテストダブルを選べる。 - モックライブラリのAPIが何を提供しているのか理解しやすくなる。 - ただし、xUnit Test Patternsのテストダブルの分類と言葉が一致しなかったりするので要注意。
- (逆説的だが)自分が作成したいテストケースが明確になる。
以降の説明の流れ - テストダブルとその分類 - それぞれ、実際にどうやって置き換えるのか、サンプルコードで紹介(Kotlin)
テストダブルの分類
外部からの入力 外部への出力 主な役割 ダミー × × 何もしない。インスタンスが必要になる場合に利用。 スタブ ◯ ×
外部コンポーネントからの入力を操作する スパイ ◯ ◎ 外部コンポーネントへの出力を記録する 出力結果をテストコードから取り出して評価 モック ◯ ◎ 外部コンポーネントへの出力を記録する 出力の期待結果を持ち、モック内で評価 フェイク ◯ ◯ 本物ではないが、本物と同じように動作する テストダブルの分類
外部からの入力 外部への出力 主な役割 ダミー × × 何もしない。インスタンスが必要になる場合に利用。 スタブ ◯ ×
外部コンポーネントからの入力を操作する スパイ ◯ ◎ 外部コンポーネントへの出力を記録する 出力結果をテストコードから取り出して評価 モック ◯ ◎ 外部コンポーネントへの出力を記録する 出力の期待結果を持ち、モック内で評価 フェイク ◯ ◯ 本物ではないが、本物と同じように動作する テストダブルの分類 主に「外部への入出力」でテ ストダブルを分類
外部からの入力 外部への出力 主な役割 ダミー × × 何もしない。インスタンスが必要になる場合に利用。 スタブ ◯ ×
外部コンポーネントからの入力を操作する スパイ ◯ ◎ 外部コンポーネントへの出力を記録する 出力結果をテストコードから取り出して評価 モック ◯ ◎ 外部コンポーネントへの出力を記録する 出力の期待結果を持ち、モック内で評価 フェイク ◯ ◯ 本物ではないが、本物と同じように動作する テスト対象への入力 のコントロール テストダブルの分類
外部からの入力 外部への出力 主な役割 ダミー × × 何もしない。インスタンスが必要になる場合に利用。 スタブ ◯ ×
外部コンポーネントからの入力を操作する スパイ ◯ ◎ 外部コンポーネントへの出力を記録する 出力結果をテストコードから取り出して評価 モック ◯ ◎ 外部コンポーネントへの出力を記録する 出力の期待結果を持ち、モック内で評価 フェイク ◯ ◯ 本物ではないが、本物と同じように動作する テスト対象からの出 力の記録 テストダブルの分類
ダミー
ダミー(Dummy Object) - テストメソッド内で、なにもしない。 - テスト対象に影響を与えないが、コンパイルなどの都合上、用意しないといけないも の。
ダミーのサンプルコード
スタブ
スタブ(Test Stub) - 入力を操作し、任意の値をテスト対象に与える。 - 入力値をテストコード上で、事前設定し、テストを実行。
スタブのサンプルコード
スパイ
スパイ(Test Spy) - テスト対象からの出力を記録。 - テストコード上でその記録した出力を検証する。 - ただし、入力を操作することもある。つまりスタブのように振る舞うこともある。
スパイのサンプルコード
モック
モック(Mock Object) - テスト対象からの出力を記録 - テスト対象内の外部コンポーネントへの出力の期待結果(expected)をセットする - テスト対象を実行しながら、テスト対象から外部コンポーネントへの出力を取得し、 モック内部で期待結果と出力結果を比較して、成功か失敗かを判定する -
テストコードからは、モックから検証の成功 or 失敗を受け取る - スタブの機能を持つことがある
スパイとモックの違い - 両方とも、外部コンポーネントへの出力を検証するためのテストダブル。 - ただし、モックは、テスト対象のメソッドを呼び出す前に、事前に期待結果をセットす る。その後、モック内で出力の結果を評価する。 - スパイは、外部コンポーネントへの出力を保持するだけ。外部コンポーネントへの 出力結果の評価は後からテストコード上で行う。
フェイク
フェイク(Fake Object) - テスト実行中、本物ではないが、本物と同じように動作する。 - 本物がテスト環境で使えないとか、返答が遅いなどの理由で利用する。 - テストの実行環境のマシンで起動しておいて、接続先を変更するなどで置き換える - 例
- RDBに対し、同じ機能を持ったオンメモリのデータベース。 - AWSの機能をエミュレートした LocalStack。DynamoDB Local。
以上、テストダブルの分類でした
その他 - ややこしいが、テストダブルの生成を単に「モックする」ということがある。
その他 - ややこしいが、テストダブルの生成を単に「モックする」ということがある。 - 「スタブの入力値自体をテストする」のような意味のないユニットテストを書いてしま うことがあるので注意。
その他 - ややこしいが、テストダブルの生成を単に「モックする」ということがある。 - 「スタブの入力値自体をテストする」のような意味のないユニットテストを書いてしま うことがあるので注意。 - テストダブルは、まだ実装していないコードの代替となる。
その他 - ややこしいが、テストダブルの生成を単に「モックする」ということがある。 - 「スタブの入力値自体をテストする」のような意味のないユニットテストを書いてしま うことがあるので注意。 - テストダブルは、まだ実装していないコードの代替となる。 - モックライブラリで実装されている名前と、xUnit
Test Patternsのテストダブルの分 類は必ずしも一致しない
その他 - ややこしいが、テストダブルの生成を単に「モックする」ということがある。 - 「スタブの入力値自体をテストする」のような意味のないユニットテストを書いてしま うことがあるので注意。 - テストダブルは、まだ実装していないコードの代替となる。 - モックライブラリで実装されている名前と、xUnit
Test Patternsのテストダブルの分 類は必ずしも一致しない - モックライブラリによっては挙動が異なるので、利用するときはよく挙動を理解して おくこと - rspec-mocks(Ruby)のスパイは、置き換えられた本物の依存コンポーネントの処理は実行されな い - MockK(Kotlin)やJest(JavaScript)のスパイは、デフォルトだと、置き換えられた依存コンポーネン トの処理も実行される。プロキシのような挙動。
外部からの入力 外部への出力 主な役割 ダミー × × 何もしない。インスタンスが必要になる場合に利用。 スタブ ◯ ×
外部コンポーネントからの入力を操作する スパイ ◯ ◎ 外部コンポーネントへの出力を記録する 出力結果をテストコードから取り出して評価 モック ◯ ◎ 外部コンポーネントへの出力を記録する 出力の期待結果を持ち、モック内で評価 フェイク ◯ ◯ 本物ではないが、本物と同じように動作する まとめ テスト対象への入力 のコントロール テスト対象からの出 力の記録