Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Riverpodでテストを書こう
Search
tokku5552
May 11, 2022
Programming
0
330
Riverpodでテストを書こう
2022/1/29 第一回FlutterGakkai登壇資料
tokku5552
May 11, 2022
Tweet
Share
More Decks by tokku5552
See All by tokku5552
他責思考で考える、EMとICの本音
tokku5552
1
140
Google CloudとAWSのコンテナ実行環境比較
tokku5552
0
220
高スループット・低レイテンシを実現する技術
tokku5552
3
15k
AWS CDKのススメ
tokku5552
1
520
Messaging APIのメッセージオブジェクトを検証できるChrome拡張機能を作った話
tokku5552
1
140
FlutterにLINEログインを仕込んで通知メッセージを送る
tokku5552
2
990
AWS CDK × Reactでliffをつくる
tokku5552
1
560
Flutterで単体テストを行う方法とGitHub Actionsを使った自動化
tokku5552
1
110
ネットワーク基礎 - WEBページが表示されるまで
tokku5552
1
280
Other Decks in Programming
See All in Programming
ID管理機能開発の裏側 高速にSaaS連携を実現したチームのAI活用編
atzzcokek
0
190
AIコーディングエージェント(Gemini)
kondai24
0
150
レイトレZ世代に捧ぐ、今からレイトレを始めるための小径
ichi_raven
0
490
『実践MLOps』から学ぶ DevOps for ML
nsakki55
2
550
認証・認可の基本を学ぼう前編
kouyuume
0
150
TVerのWeb内製化 - 開発スピードと品質を両立させるまでの道のり
techtver
PRO
3
1.4k
「文字列→日付」の落とし穴 〜Ruby Date.parseの意外な挙動〜
sg4k0
0
360
【CA.ai #3】ワークフローから見直すAIエージェント — 必要な場面と“選ばない”判断
satoaoaka
0
210
TypeScript 5.9 で使えるようになった import defer でパフォーマンス最適化を実現する
bicstone
1
1k
目的で駆動する、AI時代のアーキテクチャ設計 / purpose-driven-architecture
minodriven
11
3.9k
Media Capture and Streams: W3C仕様と現場での知見
nowaki28
0
130
All(?) About Point Sets
hole
0
260
Featured
See All Featured
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
46
7.8k
Making Projects Easy
brettharned
120
6.5k
Optimizing for Happiness
mojombo
379
70k
Designing for Performance
lara
610
69k
Why You Should Never Use an ORM
jnunemaker
PRO
60
9.6k
GraphQLの誤解/rethinking-graphql
sonatard
73
11k
How to train your dragon (web standard)
notwaldorf
97
6.4k
Building an army of robots
kneath
306
46k
How to Think Like a Performance Engineer
csswizardry
28
2.3k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.1k
Rebuilding a faster, lazier Slack
samanthasiow
84
9.3k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
61k
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通知まで設定しておくと快適に、より安全に開発が進められると思いました。 (関連記事) ご清聴ありがとうございました