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
0
820
自動テストでモックするって、なにそれ?おいしいの?/what_is_mocking
marchin
April 14, 2022
Tweet
Share
More Decks by marchin
See All by marchin
Amazon Athenaで気軽に始める データ分析/athena-data-analytics
marchin1989
0
430
WebAPI開発のためのOpenAPI入門/entry-open-api
marchin1989
1
900
AWS Glueではじめるデータレイク
marchin1989
0
420
やさしく入門するOAuth2.0/easy-entry-oauth
marchin1989
6
1.2k
1時間半で克服するJavaScriptの非同期処理/async_javascript_kokufuku
marchin1989
2
1.2k
たぶんもう怖くないGit/maybe-not-afraid-of-git-anymore
marchin1989
2
1.7k
モバイルアプリで機械学習入門/introduction-to-machine-learning-in-mobile-app
marchin1989
0
330
Other Decks in Programming
See All in Programming
FigmaとPHPで作る1ミリたりとも表示崩れしない最強の帳票印刷ソリューション
ttskch
43
19k
try! Swift Tokyo 初参加報告LT
hinakko2
0
220
Azure OpenAI Serviceのプロンプトエンジニアリング入門
tomokusaba
3
710
Apache Hive 4 on Treasure Data
ryukobayashi
0
340
PHP8.3の機能を振り返る / Review of PHP 8.3 features
seike460
PRO
1
110
Build Apps for iOS, Android & Desktop in 100% Kotlin With Compose Multiplatform (mDevCamp 2024)
zsmb
0
340
Kotlin Multiplatform at Stable and Beyond (Android Makers 2024)
zsmb
0
290
Hanami and htmx
bkuhlmann
0
210
単体テストを書かない技術 #phpcon_odawara
o0h
PRO
27
8.3k
R言語の環境構築と基礎 Tokyo.R 112
bob3bob3
0
270
Zero Waste, Radical Magic, and Italian Graft – Quarkus Efficiency Secrets
hollycummins
0
230
Netty Chicago Java User Group 2024-04-17
sullis
0
180
Featured
See All Featured
Navigating Team Friction
lara
178
13k
StorybookのUI Testing Handbookを読んだ
zakiyama
13
4.6k
The Illustrated Children's Guide to Kubernetes
chrisshort
31
46k
Scaling GitHub
holman
457
140k
Happy Clients
brianwarren
92
6.4k
Building Flexible Design Systems
yeseniaperezcruz
319
37k
Product Roadmaps are Hard
iamctodd
44
9.7k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
352
28k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
25
2.3k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
2
1.3k
Automating Front-end Workflow
addyosmani
1356
200k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
21
1.6k
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)のスパイは、デフォルトだと、置き換えられた依存コンポーネン トの処理も実行される。プロキシのような挙動。
外部からの入力 外部への出力 主な役割 ダミー × × 何もしない。インスタンスが必要になる場合に利用。 スタブ ◯ ×
外部コンポーネントからの入力を操作する スパイ ◯ ◎ 外部コンポーネントへの出力を記録する 出力結果をテストコードから取り出して評価 モック ◯ ◎ 外部コンポーネントへの出力を記録する 出力の期待結果を持ち、モック内で評価 フェイク ◯ ◯ 本物ではないが、本物と同じように動作する まとめ テスト対象への入力 のコントロール テスト対象からの出 力の記録