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
Riverpodでテストを書こう
Search
tokku5552
May 11, 2022
Programming
0
250
Riverpodでテストを書こう
2022/1/29 第一回FlutterGakkai登壇資料
tokku5552
May 11, 2022
Tweet
Share
More Decks by tokku5552
See All by tokku5552
Google CloudとAWSのコンテナ実行環境比較
tokku5552
0
140
高スループット・低レイテンシを実現する技術
tokku5552
3
8.1k
AWS CDKのススメ
tokku5552
1
450
Messaging APIのメッセージオブジェクトを検証できるChrome拡張機能を作った話
tokku5552
1
110
FlutterにLINEログインを仕込んで通知メッセージを送る
tokku5552
2
860
AWS CDK × Reactでliffをつくる
tokku5552
1
480
Flutterで単体テストを行う方法とGitHub Actionsを使った自動化
tokku5552
1
83
ネットワーク基礎 - WEBページが表示されるまで
tokku5552
1
230
インフラエンジニアのお仕事(オンプレ)
tokku5552
0
110
Other Decks in Programming
See All in Programming
Laravel や Symfony で手っ取り早く OpenAPI のドキュメントを作成する
azuki
2
120
聞き手から登壇者へ: RubyKaigi2024 LTでの初挑戦が 教えてくれた、可能性の星
mikik0
1
130
ピラミッド、アイスクリームコーン、SMURF: 自動テストの最適バランスを求めて / Pyramid Ice-Cream-Cone and SMURF
twada
PRO
10
1.3k
ふかぼれ!CSSセレクターモジュール / Fukabore! CSS Selectors Module
petamoriken
0
150
Creating a Free Video Ad Network on the Edge
mizoguchicoji
0
120
Quine, Polyglot, 良いコード
qnighy
4
650
ECS Service Connectのこれまでのアップデートと今後のRoadmapを見てみる
tkikuc
2
250
リアーキテクチャxDDD 1年間の取り組みと進化
hsawaji
1
220
macOS でできる リアルタイム動画像処理
biacco42
9
2.4k
WebフロントエンドにおけるGraphQL(あるいはバックエンドのAPI)との向き合い方 / #241106_plk_frontend
izumin5210
4
1.4k
RubyLSPのマルチバイト文字対応
notfounds
0
120
광고 소재 심사 과정에 AI를 도입하여 광고 서비스 생산성 향상시키기
kakao
PRO
0
170
Featured
See All Featured
It's Worth the Effort
3n
183
27k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
93
16k
Optimising Largest Contentful Paint
csswizardry
33
2.9k
Faster Mobile Websites
deanohume
305
30k
Side Projects
sachag
452
42k
Music & Morning Musume
bryan
46
6.2k
Building Your Own Lightsaber
phodgson
103
6.1k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
6.8k
The Art of Programming - Codeland 2020
erikaheidi
52
13k
Measuring & Analyzing Core Web Vitals
bluesmoon
4
130
BBQ
matthewcrist
85
9.3k
5 minutes of I Can Smell Your CMS
philhawksworth
202
19k
Transcript
Riverpodでテストを書こう FlutterGakkai 2022/1/29
目次 • Flutterでのテストことはじめ • サンプルプロジェクトの解説 • Unit Test • Widget
Test • まとめ 2
自己紹介 とっく(@tokkuu) • 都内AdTech企業のWebエンジニア • php/python/TypeScript • AWS周り 3-tierからサーバレスまで •
元々はSIerのインフラエンジニア • Flutter歴は1年半くらい 3
はじめに • 説明すること ◦ Riverpodでのユニットテストの書き方 ◦ RiverpodでのWidgetテストの書き方 • 説明しないこと ◦
DIを用いたProviderでのテストの書き方 ◦ Integration Testについて ◦ CIへの組み込みやDDDについて • Providerでのテストについて ◦ Flutterで単体テストを行う方法とGitHub Actionsを使った自動化 • DDDの説明(同じサンプルを使用) ◦ hooks_riverpod + state_notifier + freezedでのドメイン駆動設計 4
Flutterでのテストことはじめ
Flutterにおけるテストの種類 Flutterには3種類のテストがある 公式ページ:https://flutter.dev/docs/cookbook/testing ・Unit Test ・Widget Test ・Integration Test いわゆる単体テスト。関数、メソッド、クラスの検証を行う
Widgetが正しく生成されるかのテスト。 結合テスト。シナリオを書いてエミュレータ上で自動操作によるテス トが行える。 6
Unit Testの準備 ・パッケージの導入 pubspec.yamlにflutter_testが追加されていること 7
Unitテストの書き方と実行方法 プロジェクトルートの testフォルダの下に XXX_test.dartファイルを作成 import 'package:flutter_test/flutter_test.dart' ; import 'package:todo_app_sample_flutter/data/todo_item.dart' ;
void main() { group('TodoItemのゲッターのテスト ', () { final TodoItem todoItem = TodoItem( id: 0, title: 'title', body: 'body', createdAt: DateTime (2020, 1, 1), updatedAt: DateTime (2020, 1, 1), isDone: true, ); test('idのテスト', () { expect (todoItem.getId, 0); }); 8
Unitテストの書き方と実行方法 プロジェクトルートの testフォルダの下に XXX_test.dartファイルを作成 import 'package:flutter_test/flutter_test.dart' ; import 'package:todo_app_sample_flutter/data/todo_item.dart' ;
void main() { group('TodoItemのゲッターのテスト ', () { final TodoItem todoItem = TodoItem( id: 0, title: 'title', body: 'body', createdAt: DateTime (2020, 1, 1), updatedAt: DateTime (2020, 1, 1), isDone: true, ); test('idのテスト', () { expect (todoItem.getId, 0); }); main関数の中に 実際のテストを記載 test(‘テストケース名’,(){ 実際のテスト処理 expect(結果,期待する値); }); group()でテストケースを まとめることが出来る。 9
テスト実行 1. テストファイルを右クリック 2. Run ‘test in <テストファイル>’ デバッグの画面が開いて 結果が表示される
10
サンプルプロジェクトの解説
サンプルプロジェクトの説明 • DDDぽく書いている • application層の todo_app_service.dartがdomain層の classを使う形 • ビジネスロジックのテストという文脈で は、todo_app_service.dartを
テストすれば十分 • このプロジェクト自体の解説は Qiitaの記事参照 • 全体のコードはこちら 12
サンプルプロジェクトの説明 - TodoAppService • todo_app_serviceは todoListRepositoryに依存して いる • todoListRepositoryはFirebase との通信を担う
• DDDじゃない場合、MVVM + Repositoryのパターンなどで は、View Modelでテストすれば 良い 13
テストの準備 - TodoListRepositoryのモックを作る • TodoListRepositoryを実装した TodoListRepositoryMemを作 る • TodoListRepositoryMemでは Firebaseとの通信を行わず、テ
スト用に一時的にデータを貯め れるように実装しておく • コード 14
テストの準備 - ProviderContainerでoverrideする • Riverpodでは ProviderContainerを使ってモッ ク用のクラスを宣言することで、 Providerを上書きできる。 • 右のように
TodoListRepositoryMemを 宣言しておくことで このコンテナから呼び出したリ ポジトリやサービスでは 上書きされたモック用クラスが 呼び出される様になる。 15
Unit Test
Unit Test - 宣言 • Widgetの生成が絡まない ロジックをテストする • setUpやtearDownが使える ので、先程のコンテナの宣言や
データのセットが行える。 • Null Safetyなバージョンの Flutterであれば、コンテナや モックはlateで宣言しておくこと でnon-nullableに扱える 17
Unit Test - 実行 1. 空のTodoItemを_repositoryに セットし、自動生成され 割り当てられたnextIdを取得 2. テスト対象のクラスを
インスタンス化 3. テスト対象のメソッドを 実行し結果を expectメソッドで比較 2. 3. 1. 18
Widget Test
WidgetTest - 宣言 • モック用クラスは引き続き containerから取得 • Widgetを生成するために、 tester.pumpWidgetの中で ProviderScopeを宣言し、モック
にoverride • childの中でテスト対象Widget の描画に必要なWidget、 MaterialAppなどを宣言した上 で対象のWidgetを宣言 20
WidgetTest - 実行 • find.textで描画されたWidgetの 中のテキストを探す。 findsOneWidgetは「それが1つ あること」という意味になる。 • tester.tapなどで、特定のIcon
などを探してボタンをタップさせ ることもできる。 21
まとめ • Riverpodで記述するときは、Repositoryをあとからoverrideできるため、わざわざ 抽象クラスを作っておいて、DIできるようにドメインクラスを実装する必要がない • Unit Testのほうが比較的簡単に、最低限のロジックのテストが書きやすい • CI組んでおけば、快適にTDDできそう •
Widget Testまで書いて、Codecovなどを使ってカバレッジを可視化して、CI組んで Slack通知まで設定しておくと快適に、より安全に開発が進められると思いました。 (関連記事) ご清聴ありがとうございました