狠狠撸

狠狠撸Share a Scribd company logo
Riverpodでテストを書こう
FlutterGakkai 2022/1/29
目次
● 贵濒耻迟迟别谤でのテストことはじめ
● サンプルプロジェクトの解説
● 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_noti?er + freezedでのドメイン駆動設計
4
贵濒耻迟迟别谤でのテストことはじめ
Flutterにおけるテストの種類
Flutterには3種類のテストがある
公式ページ:https://?utter.dev/docs/cookbook/testing
?Unit Test   
?Widget Test 
?Integration Test
いわゆる単体テスト。関数、メソッド、クラスの検証を行う
Widgetが正しく生成されるかのテスト。
結合テスト。シナリオを書いてエミュレータ上で自動操作によるテス
トが行える。
6
Unit Testの準備
?パッケージの導入
 pubspec.yamlに?utter_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 - 実行
● ?nd.textで描画されたWidgetの
中のテキストを探す。
?ndsOneWidgetは「それが1つ
あること」という意味になる。
● tester.tapなどで、特定のIcon
などを探してボタンをタップさせ
ることもできる。
21
まとめ
● Riverpodで記述するときは、Repositoryをあとからoverrideできるため、わざわざ
抽象クラスを作っておいて、DIできるようにドメインクラスを実装する必要がない
● Unit Testのほうが比較的簡単に、最低限のロジックのテストが書きやすい
● CI組んでおけば、快適にTDDできそう
● Widget Testまで書いて、Codecovなどを使ってカバレッジを可視化して、CI組んで
Slack通知まで設定しておくと快適に、より安全に開発が進められると思いました。
(関連記事)
ご清聴ありがとうございました

More Related Content

What's hot (20)

こわくない Git
こわくない Gitこわくない Git
こわくない Git
Kota Saito
?
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
Moriharu Ohzu
?
骋辞のサーハ?サイト?実装におけるレイヤ设计とレイヤ内実装について考える
骋辞のサーハ?サイト?実装におけるレイヤ设计とレイヤ内実装について考える骋辞のサーハ?サイト?実装におけるレイヤ设计とレイヤ内実装について考える
骋辞のサーハ?サイト?実装におけるレイヤ设计とレイヤ内実装について考える
pospome
?
奥别产础蝉蝉别尘产濒测の奥别产以外のことぜんぶ话す
奥别产础蝉蝉别尘产濒测の奥别产以外のことぜんぶ话す奥别产础蝉蝉别尘产濒测の奥别产以外のことぜんぶ话す
奥别产础蝉蝉别尘产濒测の奥别产以外のことぜんぶ话す
Takaya Saeki
?
骋辞による奥别产アプリ开発のキホン
骋辞による奥别产アプリ开発のキホン骋辞による奥别产アプリ开発のキホン
骋辞による奥别产アプリ开発のキホン
Akihiko Horiuchi
?
碍辞迟濒颈苍アンチパターン
碍辞迟濒颈苍アンチパターン碍辞迟濒颈苍アンチパターン
碍辞迟濒颈苍アンチパターン
Recruit Lifestyle Co., Ltd.
?
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説
murachue
?
Cloud runのオートスケールを検証してみる
Cloud runのオートスケールを検証してみるCloud runのオートスケールを検証してみる
Cloud runのオートスケールを検証してみる
虎の穴 開発室
?
Dockerfile を書くためのベストプラクティス解説編
Dockerfile を書くためのベストプラクティス解説編Dockerfile を書くためのベストプラクティス解説編
Dockerfile を書くためのベストプラクティス解説編
Masahito Zembutsu
?
例外设计における大罪
例外设计における大罪例外设计における大罪
例外设计における大罪
Takuto Wada
?
搁耻蝉迟に触れて私の笔测迟丑辞苍はどう変わったか
搁耻蝉迟に触れて私の笔测迟丑辞苍はどう変わったか搁耻蝉迟に触れて私の笔测迟丑辞苍はどう変わったか
搁耻蝉迟に触れて私の笔测迟丑辞苍はどう変わったか
ShunsukeNakamura17
?
贵濒耻迟迟别谤移行の苦労と、乗り越えた先に得られたもの
贵濒耻迟迟别谤移行の苦労と、乗り越えた先に得られたもの贵濒耻迟迟别谤移行の苦労と、乗り越えた先に得られたもの
贵濒耻迟迟别谤移行の苦労と、乗り越えた先に得られたもの
Recruit Lifestyle Co., Ltd.
?
イミュータブルデータモデル(入门编)
イミュータブルデータモデル(入门编)イミュータブルデータモデル(入门编)
イミュータブルデータモデル(入门编)
Yoshitaka Kawashima
?
Python におけるドメイン駆動設計(戦術面)の勘どころ
Python におけるドメイン駆動設計(戦術面)の勘どころPython におけるドメイン駆動設計(戦術面)の勘どころ
Python におけるドメイン駆動設計(戦術面)の勘どころ
Junya Hayashi
?
関数型?オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門
関数型?オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門関数型?オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門
関数型?オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門
Tadahiro Ishisaka
?
テストコードの DRY と DAMP
テストコードの DRY と DAMPテストコードの DRY と DAMP
テストコードの DRY と DAMP
Yusuke Kagata
?
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
sairoutine
?
オブジェクト指向プログラミングのためのモデリング入门
オブジェクト指向プログラミングのためのモデリング入门オブジェクト指向プログラミングのためのモデリング入门
オブジェクト指向プログラミングのためのモデリング入门
増田 亨
?
REST API のコツ
REST API のコツREST API のコツ
REST API のコツ
pospome
?
Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方
Taku Miyakawa
?
こわくない Git
こわくない Gitこわくない Git
こわくない Git
Kota Saito
?
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
Moriharu Ohzu
?
骋辞のサーハ?サイト?実装におけるレイヤ设计とレイヤ内実装について考える
骋辞のサーハ?サイト?実装におけるレイヤ设计とレイヤ内実装について考える骋辞のサーハ?サイト?実装におけるレイヤ设计とレイヤ内実装について考える
骋辞のサーハ?サイト?実装におけるレイヤ设计とレイヤ内実装について考える
pospome
?
奥别产础蝉蝉别尘产濒测の奥别产以外のことぜんぶ话す
奥别产础蝉蝉别尘产濒测の奥别产以外のことぜんぶ话す奥别产础蝉蝉别尘产濒测の奥别产以外のことぜんぶ话す
奥别产础蝉蝉别尘产濒测の奥别产以外のことぜんぶ话す
Takaya Saeki
?
骋辞による奥别产アプリ开発のキホン
骋辞による奥别产アプリ开発のキホン骋辞による奥别产アプリ开発のキホン
骋辞による奥别产アプリ开発のキホン
Akihiko Horiuchi
?
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説
murachue
?
Cloud runのオートスケールを検証してみる
Cloud runのオートスケールを検証してみるCloud runのオートスケールを検証してみる
Cloud runのオートスケールを検証してみる
虎の穴 開発室
?
Dockerfile を書くためのベストプラクティス解説編
Dockerfile を書くためのベストプラクティス解説編Dockerfile を書くためのベストプラクティス解説編
Dockerfile を書くためのベストプラクティス解説編
Masahito Zembutsu
?
例外设计における大罪
例外设计における大罪例外设计における大罪
例外设计における大罪
Takuto Wada
?
搁耻蝉迟に触れて私の笔测迟丑辞苍はどう変わったか
搁耻蝉迟に触れて私の笔测迟丑辞苍はどう変わったか搁耻蝉迟に触れて私の笔测迟丑辞苍はどう変わったか
搁耻蝉迟に触れて私の笔测迟丑辞苍はどう変わったか
ShunsukeNakamura17
?
贵濒耻迟迟别谤移行の苦労と、乗り越えた先に得られたもの
贵濒耻迟迟别谤移行の苦労と、乗り越えた先に得られたもの贵濒耻迟迟别谤移行の苦労と、乗り越えた先に得られたもの
贵濒耻迟迟别谤移行の苦労と、乗り越えた先に得られたもの
Recruit Lifestyle Co., Ltd.
?
イミュータブルデータモデル(入门编)
イミュータブルデータモデル(入门编)イミュータブルデータモデル(入门编)
イミュータブルデータモデル(入门编)
Yoshitaka Kawashima
?
Python におけるドメイン駆動設計(戦術面)の勘どころ
Python におけるドメイン駆動設計(戦術面)の勘どころPython におけるドメイン駆動設計(戦術面)の勘どころ
Python におけるドメイン駆動設計(戦術面)の勘どころ
Junya Hayashi
?
関数型?オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門
関数型?オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門関数型?オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門
関数型?オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門
Tadahiro Ishisaka
?
テストコードの DRY と DAMP
テストコードの DRY と DAMPテストコードの DRY と DAMP
テストコードの DRY と DAMP
Yusuke Kagata
?
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
sairoutine
?
オブジェクト指向プログラミングのためのモデリング入门
オブジェクト指向プログラミングのためのモデリング入门オブジェクト指向プログラミングのためのモデリング入门
オブジェクト指向プログラミングのためのモデリング入门
増田 亨
?
REST API のコツ
REST API のコツREST API のコツ
REST API のコツ
pospome
?
Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方
Taku Miyakawa
?

Similar to 搁颈惫别谤辫辞诲て?テストを书こう (20)

Goji とレイヤ化アーキテクチャ
Goji とレイヤ化アーキテクチャGoji とレイヤ化アーキテクチャ
Goji とレイヤ化アーキテクチャ
Shiroyagi Corporation
?
はてなにおける継続的デプロイメントの現状と Docker の導入
はてなにおける継続的デプロイメントの現状と Docker の導入はてなにおける継続的デプロイメントの現状と Docker の導入
はてなにおける継続的デプロイメントの現状と Docker の導入
Yu Nobuoka
?
VSCodeで始めるAzure Static Web Apps開発
VSCodeで始めるAzure Static Web Apps開発VSCodeで始めるAzure Static Web Apps開発
VSCodeで始めるAzure Static Web Apps開発
Yuta Matsumura
?
Multibranch Pipeline with Docker 入門編
Multibranch Pipeline with Docker 入門編Multibranch Pipeline with Docker 入門編
Multibranch Pipeline with Docker 入門編
kimulla
?
ドリコムのインフラ颁滨
ドリコムのインフラ颁滨ドリコムのインフラ颁滨
ドリコムのインフラ颁滨
Go Sueyoshi (a.k.a sue445)
?
n9te9_introdection_gg-executor(go-graphql).pptx
n9te9_introdection_gg-executor(go-graphql).pptxn9te9_introdection_gg-executor(go-graphql).pptx
n9te9_introdection_gg-executor(go-graphql).pptx
keink
?
顿尝搁言语による厂颈濒惫别谤濒颈驳丑迟プログラミング
顿尝搁言语による厂颈濒惫别谤濒颈驳丑迟プログラミング顿尝搁言语による厂颈濒惫别谤濒颈驳丑迟プログラミング
顿尝搁言语による厂颈濒惫别谤濒颈驳丑迟プログラミング
terurou
?
顿补谤迟笔补诲+颁辞诲别笔别苍で、贵濒耻迟迟别谤を体験してみよう
顿补谤迟笔补诲+颁辞诲别笔别苍で、贵濒耻迟迟别谤を体験してみよう顿补谤迟笔补诲+颁辞诲别笔别苍で、贵濒耻迟迟别谤を体験してみよう
顿补谤迟笔补诲+颁辞诲别笔别苍で、贵濒耻迟迟别谤を体験してみよう
cch-robo
?
厂飞补驳驳别谤と础笔滨のデザイン
厂飞补驳驳别谤と础笔滨のデザイン厂飞补驳驳别谤と础笔滨のデザイン
厂飞补驳驳别谤と础笔滨のデザイン
Kazuhiro Hara
?
How to run P4 BMv2
How to run P4 BMv2How to run P4 BMv2
How to run P4 BMv2
Kentaro Ebisawa
?
Pyconjp2014_implementations
Pyconjp2014_implementationsPyconjp2014_implementations
Pyconjp2014_implementations
masahitojp
?
Groovy Bootcamp 2015 by JGGUG
Groovy Bootcamp 2015 by JGGUGGroovy Bootcamp 2015 by JGGUG
Groovy Bootcamp 2015 by JGGUG
Uehara Junji
?
JavaScript And Keywords
JavaScript And KeywordsJavaScript And Keywords
JavaScript And Keywords
uupaa
?
20151029 ヒカラホ?講演資料
20151029 ヒカラホ?講演資料20151029 ヒカラホ?講演資料
20151029 ヒカラホ?講演資料
Daisuke Ando
?
株式会社waja 安藤様 登壇資料
株式会社waja 安藤様 登壇資料株式会社waja 安藤様 登壇資料
株式会社waja 安藤様 登壇資料
leverages_event
?
RgGen ご紹介
RgGen ご紹介RgGen ご紹介
RgGen ご紹介
Taichi Ishitani
?
第8回 福岡西区勉強会
第8回 福岡西区勉強会第8回 福岡西区勉強会
第8回 福岡西区勉強会
Shinya Kinoshita
?
惭补办别骋辞辞诲で快适なテスト駆动开発を
惭补办别骋辞辞诲で快适なテスト駆动开発を惭补办别骋辞辞诲で快适なテスト駆动开発を
惭补办别骋辞辞诲で快适なテスト駆动开発を
Atsuhiro Kubo
?
CI/CD Pipeline を考える ?KubeCon 2017 + CyberAgent の最大公倍数?
CI/CD Pipeline を考える ?KubeCon 2017 + CyberAgent の最大公倍数?CI/CD Pipeline を考える ?KubeCon 2017 + CyberAgent の最大公倍数?
CI/CD Pipeline を考える ?KubeCon 2017 + CyberAgent の最大公倍数?
Masaya Aoyama
?
RSpec Performance Turning
RSpec Performance TurningRSpec Performance Turning
RSpec Performance Turning
Go Sueyoshi (a.k.a sue445)
?
Goji とレイヤ化アーキテクチャ
Goji とレイヤ化アーキテクチャGoji とレイヤ化アーキテクチャ
Goji とレイヤ化アーキテクチャ
Shiroyagi Corporation
?
はてなにおける継続的デプロイメントの現状と Docker の導入
はてなにおける継続的デプロイメントの現状と Docker の導入はてなにおける継続的デプロイメントの現状と Docker の導入
はてなにおける継続的デプロイメントの現状と Docker の導入
Yu Nobuoka
?
VSCodeで始めるAzure Static Web Apps開発
VSCodeで始めるAzure Static Web Apps開発VSCodeで始めるAzure Static Web Apps開発
VSCodeで始めるAzure Static Web Apps開発
Yuta Matsumura
?
Multibranch Pipeline with Docker 入門編
Multibranch Pipeline with Docker 入門編Multibranch Pipeline with Docker 入門編
Multibranch Pipeline with Docker 入門編
kimulla
?
n9te9_introdection_gg-executor(go-graphql).pptx
n9te9_introdection_gg-executor(go-graphql).pptxn9te9_introdection_gg-executor(go-graphql).pptx
n9te9_introdection_gg-executor(go-graphql).pptx
keink
?
顿尝搁言语による厂颈濒惫别谤濒颈驳丑迟プログラミング
顿尝搁言语による厂颈濒惫别谤濒颈驳丑迟プログラミング顿尝搁言语による厂颈濒惫别谤濒颈驳丑迟プログラミング
顿尝搁言语による厂颈濒惫别谤濒颈驳丑迟プログラミング
terurou
?
顿补谤迟笔补诲+颁辞诲别笔别苍で、贵濒耻迟迟别谤を体験してみよう
顿补谤迟笔补诲+颁辞诲别笔别苍で、贵濒耻迟迟别谤を体験してみよう顿补谤迟笔补诲+颁辞诲别笔别苍で、贵濒耻迟迟别谤を体験してみよう
顿补谤迟笔补诲+颁辞诲别笔别苍で、贵濒耻迟迟别谤を体験してみよう
cch-robo
?
厂飞补驳驳别谤と础笔滨のデザイン
厂飞补驳驳别谤と础笔滨のデザイン厂飞补驳驳别谤と础笔滨のデザイン
厂飞补驳驳别谤と础笔滨のデザイン
Kazuhiro Hara
?
Pyconjp2014_implementations
Pyconjp2014_implementationsPyconjp2014_implementations
Pyconjp2014_implementations
masahitojp
?
Groovy Bootcamp 2015 by JGGUG
Groovy Bootcamp 2015 by JGGUGGroovy Bootcamp 2015 by JGGUG
Groovy Bootcamp 2015 by JGGUG
Uehara Junji
?
JavaScript And Keywords
JavaScript And KeywordsJavaScript And Keywords
JavaScript And Keywords
uupaa
?
20151029 ヒカラホ?講演資料
20151029 ヒカラホ?講演資料20151029 ヒカラホ?講演資料
20151029 ヒカラホ?講演資料
Daisuke Ando
?
株式会社waja 安藤様 登壇資料
株式会社waja 安藤様 登壇資料株式会社waja 安藤様 登壇資料
株式会社waja 安藤様 登壇資料
leverages_event
?
第8回 福岡西区勉強会
第8回 福岡西区勉強会第8回 福岡西区勉強会
第8回 福岡西区勉強会
Shinya Kinoshita
?
惭补办别骋辞辞诲で快适なテスト駆动开発を
惭补办别骋辞辞诲で快适なテスト駆动开発を惭补办别骋辞辞诲で快适なテスト駆动开発を
惭补办别骋辞辞诲で快适なテスト駆动开発を
Atsuhiro Kubo
?
CI/CD Pipeline を考える ?KubeCon 2017 + CyberAgent の最大公倍数?
CI/CD Pipeline を考える ?KubeCon 2017 + CyberAgent の最大公倍数?CI/CD Pipeline を考える ?KubeCon 2017 + CyberAgent の最大公倍数?
CI/CD Pipeline を考える ?KubeCon 2017 + CyberAgent の最大公倍数?
Masaya Aoyama
?

搁颈惫别谤辫辞诲て?テストを书こう