Download free for 30 days
Sign in
Upload
Language (EN)
Support
Business
Mobile
Social Media
Marketing
Technology
Art & Photos
Career
Design
Education
Presentations & Public Speaking
Government & Nonprofit
Healthcare
Internet
Law
Leadership & Management
Automotive
Engineering
Software
Recruiting & HR
Retail
Sales
Services
Science
Small Business & Entrepreneurship
Food
Environment
Economy & Finance
Data & Analytics
Investor Relations
Sports
Spiritual
News & Politics
Travel
Self Improvement
Real Estate
Entertainment & Humor
Health & Medicine
Devices & Hardware
Lifestyle
Change Language
Language
English
Español
Português
Français
Deutsche
Cancel
Save
Submit search
EN
Uploaded by
Shinnosuke Tokuda
PDF, PPTX
11,825 views
Flutterで単体テストを行う方法とGitHub Actionsを使った自動化
Flutterでの単体テスト実施方法と、テスタブルなコードにリファクタリングするためのテクニック. またそれをGitHub Actionsで自動化してカバレッジを可視化する方法
Software
◦
Related topics:
Software Testing Insights
•
Read more
0
Save
Share
Embed
Embed presentation
Download
Download as PDF, PPTX
1
/ 42
2
/ 42
3
/ 42
4
/ 42
5
/ 42
6
/ 42
7
/ 42
8
/ 42
9
/ 42
10
/ 42
11
/ 42
12
/ 42
13
/ 42
14
/ 42
15
/ 42
16
/ 42
17
/ 42
18
/ 42
19
/ 42
20
/ 42
21
/ 42
22
/ 42
23
/ 42
24
/ 42
25
/ 42
26
/ 42
27
/ 42
28
/ 42
29
/ 42
30
/ 42
31
/ 42
32
/ 42
33
/ 42
34
/ 42
35
/ 42
36
/ 42
37
/ 42
38
/ 42
39
/ 42
40
/ 42
41
/ 42
42
/ 42
More Related Content
PDF
Riverpodでテストを書こう
by
Shinnosuke Tokuda
PDF
hooks riverpod + state notifier + freezed でのドメイン駆動設計
by
Shinnosuke Tokuda
PDF
【BS4】時は来たれり。今こそ .NET 6 へ移行する時。
by
日本マイクロソフト株式会社
PPTX
世界一わかりやすいClean Architecture
by
Atsushi Nakamura
PDF
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
by
Koichiro Matsuoka
PPTX
テストコードの DRY と DAMP
by
Yusuke Kagata
PDF
Dockerからcontainerdへの移行
by
Kohei Tokunaga
PDF
こわくない Git
by
Kota Saito
Riverpodでテストを書こう
by
Shinnosuke Tokuda
hooks riverpod + state notifier + freezed でのドメイン駆動設計
by
Shinnosuke Tokuda
【BS4】時は来たれり。今こそ .NET 6 へ移行する時。
by
日本マイクロソフト株式会社
世界一わかりやすいClean Architecture
by
Atsushi Nakamura
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
by
Koichiro Matsuoka
テストコードの DRY と DAMP
by
Yusuke Kagata
Dockerからcontainerdへの移行
by
Kohei Tokunaga
こわくない Git
by
Kota Saito
What's hot
ODP
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
by
pospome
PDF
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
by
Jun-ichi Sakamoto
PDF
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
by
Y Watanabe
PDF
DDDはオブジェクト指向を利用してどのようにメンテナブルなコードを書くか
by
Koichiro Matsuoka
PDF
ドメイン駆動設計 失敗したことと成功したこと
by
BIGLOBE Inc.
PDF
ドメイン駆動設計 モデリング_実装入門勉強会_2020.3.8
by
Koichiro Matsuoka
PDF
現場で役立つシステム設計の原則
by
増田 亨
PDF
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
by
Koichiro Matsuoka
PDF
マルチテナントのアプリケーション実装〜実践編〜
by
Yoshiki Nakagawa
PDF
ドメインオブジェクトの見つけ方・作り方・育て方
by
増田 亨
PDF
REST API のコツ
by
pospome
PDF
ソーシャルゲームのためのデータベース設計
by
Yoshinori Matsunobu
PPTX
境界付けられたコンテキスト 概念編 (ドメイン駆動設計用語解説シリーズ)
by
Koichiro Matsuoka
PDF
なぜ、いま リレーショナルモデルなのか(理論から学ぶデータベース実践入門読書会スペシャル)
by
Mikiya Okuno
PDF
MySQLで論理削除と正しく付き合う方法
by
yoku0825
PDF
デキるプログラマだけが知っているコードレビュー7つの秘訣
by
Masahiro Nishimi
PPTX
Redisの特徴と活用方法について
by
Yuji Otani
PDF
日本語テストメソッドについて
by
kumake
PDF
Fluentdのお勧めシステム構成パターン
by
Kentaro Yoshida
PPTX
関数型・オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門
by
Tadahiro Ishisaka
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
by
pospome
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
by
Jun-ichi Sakamoto
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
by
Y Watanabe
DDDはオブジェクト指向を利用してどのようにメンテナブルなコードを書くか
by
Koichiro Matsuoka
ドメイン駆動設計 失敗したことと成功したこと
by
BIGLOBE Inc.
ドメイン駆動設計 モデリング_実装入門勉強会_2020.3.8
by
Koichiro Matsuoka
現場で役立つシステム設計の原則
by
増田 亨
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
by
Koichiro Matsuoka
マルチテナントのアプリケーション実装〜実践編〜
by
Yoshiki Nakagawa
ドメインオブジェクトの見つけ方・作り方・育て方
by
増田 亨
REST API のコツ
by
pospome
ソーシャルゲームのためのデータベース設計
by
Yoshinori Matsunobu
境界付けられたコンテキスト 概念編 (ドメイン駆動設計用語解説シリーズ)
by
Koichiro Matsuoka
なぜ、いま リレーショナルモデルなのか(理論から学ぶデータベース実践入門読書会スペシャル)
by
Mikiya Okuno
MySQLで論理削除と正しく付き合う方法
by
yoku0825
デキるプログラマだけが知っているコードレビュー7つの秘訣
by
Masahiro Nishimi
Redisの特徴と活用方法について
by
Yuji Otani
日本語テストメソッドについて
by
kumake
Fluentdのお勧めシステム構成パターン
by
Kentaro Yoshida
関数型・オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門
by
Tadahiro Ishisaka
Similar to Flutterで単体テストを行う方法とGitHub Actionsを使った自動化
PPTX
ひと漕ぎで二度おいしい!? Flutterを使ったモバイルアプリ開発への期待と実態と付き合い方(NTTデータ テクノロジーカンファレンス 2020 発表資料)
by
NTT DATA Technology & Innovation
PDF
マッチングアプリ『Omiai』の Flutter へのリプレイスの挑戦 (FlutterKaigi 2024)
by
Kosuke Saigusa
PDF
ケーススタディ/実装 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第46回】
by
Tomoharu ASAMI
PDF
TestFlight自動化でらくらくチームテスト
by
Yoichiro Sakurai
PDF
Pythonを含む多くのプログラミング言語を扱う処理フレームワークとパターン、鷲崎弘宜、PyConJP 2016 招待講演
by
Hironori Washizaki
PDF
BNN CAMP vol.3 インタラクションデザインの現在―プログラミング初心者のためのopenFrameworks入門 1
by
Atsushi Tadokoro
PDF
デジタルアートセミナー#2 openFrameworksで学ぶ、 クリエイティブ・コーディング Session 1: openFrameworks入門
by
Atsushi Tadokoro
PDF
ケーススタディ/テスト 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第47回】
by
Tomoharu ASAMI
PDF
技育祭2025秋 サボろうとする生成AIの傾向と対策 登壇資料(フューチャー渋川)
by
Yoshiki Shibukawa
PDF
Code complete ch22_developper_test
by
Sho Shimauchi
PDF
実務者のためのかんたんScalaz
by
Tomoharu ASAMI
PPTX
JaSST'16 Tokyo モバイルセッション
by
mirer
PDF
Building a Flutter Development Environment with VSCode and Useful Extensions
by
Shotaro Suzuki
PDF
実装(1) 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第30回】
by
Tomoharu ASAMI
PPT
オブジェクト指向入門8
by
Kenta Hattori
PDF
Flutterを体験してみませんか
by
cch-robo
PDF
テスト 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第33回】
by
Tomoharu ASAMI
PDF
実装(3) 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第32回】
by
Tomoharu ASAMI
PDF
設計/原理 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第28回】
by
Tomoharu ASAMI
PPT
オブジェクト指向入門9
by
Kenta Hattori
ひと漕ぎで二度おいしい!? Flutterを使ったモバイルアプリ開発への期待と実態と付き合い方(NTTデータ テクノロジーカンファレンス 2020 発表資料)
by
NTT DATA Technology & Innovation
マッチングアプリ『Omiai』の Flutter へのリプレイスの挑戦 (FlutterKaigi 2024)
by
Kosuke Saigusa
ケーススタディ/実装 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第46回】
by
Tomoharu ASAMI
TestFlight自動化でらくらくチームテスト
by
Yoichiro Sakurai
Pythonを含む多くのプログラミング言語を扱う処理フレームワークとパターン、鷲崎弘宜、PyConJP 2016 招待講演
by
Hironori Washizaki
BNN CAMP vol.3 インタラクションデザインの現在―プログラミング初心者のためのopenFrameworks入門 1
by
Atsushi Tadokoro
デジタルアートセミナー#2 openFrameworksで学ぶ、 クリエイティブ・コーディング Session 1: openFrameworks入門
by
Atsushi Tadokoro
ケーススタディ/テスト 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第47回】
by
Tomoharu ASAMI
技育祭2025秋 サボろうとする生成AIの傾向と対策 登壇資料(フューチャー渋川)
by
Yoshiki Shibukawa
Code complete ch22_developper_test
by
Sho Shimauchi
実務者のためのかんたんScalaz
by
Tomoharu ASAMI
JaSST'16 Tokyo モバイルセッション
by
mirer
Building a Flutter Development Environment with VSCode and Useful Extensions
by
Shotaro Suzuki
実装(1) 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第30回】
by
Tomoharu ASAMI
オブジェクト指向入門8
by
Kenta Hattori
Flutterを体験してみませんか
by
cch-robo
テスト 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第33回】
by
Tomoharu ASAMI
実装(3) 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第32回】
by
Tomoharu ASAMI
設計/原理 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第28回】
by
Tomoharu ASAMI
オブジェクト指向入門9
by
Kenta Hattori
Flutterで単体テストを行う方法とGitHub Actionsを使った自動化
1.
Flutterで単体テストを行う方法とGitHub Actionsを使った自動化 KBOYのFlutter大学 勉強会 2021/02/24
2.
はじめに このスライドの内容は以下の記事をかみ砕いて説明するものになります。 ・Flutterで単体テストを書く : https://qiita.com/tokkun5552/items/ede8460bef4892f48e37 ・【Flutter】Providerで最低限のDIを行ってテスタブルなコードにリファクタリングする : https://qiita.com/tokkun5552/items/7af34769104e94f50745 ・【Flutter】GitHubActionsでテストと静的解析を自動化する https://qiita.com/tokkun5552/items/2eb6793501c152dabf33 ・サンプルコードの
GitHubリポジトリ tokku5552/TODOAppSample-Flutter: A sample Todo App with Provider
3.
なぜテストするのか 結論:ソフトウェアの品質を高めるため ソフトウェアの品質が下がる要因 ・人間が書いているので間違いや考慮漏れは起こる→仕方がないこと ・ある場所に変更を加えることで、別の場所に影響を及ぼしバグが生まれる テストが品質を上げる理由 ・考慮漏れや間違いが起きにくくなる(客観的に見ることが出来る) ・変更時にテストして、動きが変わっていないことを確かめる
4.
品質向上とリリースのスピードはトレードオフ 「Done is better
than perfect」 → 完璧を目指すよりもまず終わらせろ とはいえ全く動かさずにリリースするわけにはいかない 品質の落としどころ ・ベータ版としてリリース → ユーザにテストしてもらう ・モンキーテスト → テストケースを決めずに適当にクリックしたり入力したりしてみる 選択肢として ビジネスロジックの自動テストを考えてみる
5.
Flutterでのテストことはじめ
6.
Flutterにおけるテストの種類 Flutterには3種類のテストがある 公式ページ:https://flutter.dev/docs/cookbook/testing ・Unit Test ・Widget Test ・Integration
Test いわゆる単体テスト。関数、メソッド、クラスの検証を行う Widgetが正しく生成されるかのテスト。 結合テスト。シナリオを書いてエミュレータ上で自動操作によるテス トが行える。
7.
Flutterにおけるテストの種類 Flutterには3種類のテストがある 公式ページ:https://flutter.dev/docs/cookbook/testing ・Unit Test ・Widget Test ・Integration
Test いわゆる単体テスト。関数、メソッド、クラスの検証を行う Widgetが正しく生成されるかのテスト。 結合テスト。シナリオを書いてエミュレータ上で自動操作によるテス トが行える。 今回は主に、実装コストと効果の バランスが一番よさそうな Unit Testを扱う
8.
UnitTestの準備 ・パッケージの導入 pubspec.yamlにflutter_testが追加されていること ※実際はtestパッケージがあれば良いが、 flutter_testパッケージに含まれる
9.
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); });
10.
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()でテストケースを まとめることが出来る。
11.
テスト実行 1. テストファイルを右クリック 2. 実行→tests
in XXXX デバッグの画面が開いて 結果が表示される
12.
ここからが本題 class MemoDetailModel extends
ChangeNotifier { final FirebaseAuth auth = FirebaseAuth.instance; final FirebaseFirestore firestore = FirebaseFirestore.instance; Future addMemo() async { final memo = Memo( ~~ ); ~~何かデータ追加前にチェックしたりとか~~ final collection = firestore.collection('users'); final user = auth.currentUser; if (user != null) { collection.doc(user.uid).collection('memos').add({ 'title': memo.title, 'updatedAt': memo.updatedAt, 'happenedAt': memo.happenedAt, }); } notifyListeners(); } } よくありそうなChangeNotifierを 継承したドメインモデル ビジネスロジックを実装しているので 単体テストを行いたいが、 右のような状態ではテスト出来ない。 どこが問題?
13.
なぜテスト出来ない? ・FirebaseAuthやFirestoreの インスタンスを生成している ※main()内でイニシャライズが必要 ・addMemo()ではバリデーションや、 データ追加前の正当性チェックなどを 行っているが、同時に Firebaseの 通信処理も行ってしまっている class MemoDetailModel
extends ChangeNotifier { final FirebaseAuth auth = FirebaseAuth.instance; final FirebaseFirestore firestore = FirebaseFirestore.instance; Future addMemo() async { final memo = Memo( ~~ ); ~~何かデータ追加前にチェックしたりとか~~ final collection = firestore.collection('users'); final user = auth.currentUser; if (user != null) { collection.doc(user.uid).collection('memos').add({ 'title': memo.title, 'updatedAt': memo.updatedAt, 'happenedAt': memo.happenedAt, }); } notifyListeners(); } }
14.
テストを行いやすくするために ・初期化が必要な外部パッケージ(DBやFirebaseなど)を 直接使っているclassはテストしにくい。 ※できないわけではない: cloud_firestore_mocks (https://pub.dev/packages/cloud_firestore_mocks) ・でもビジネスロジックなので、データをUI等から受け取って、 加工して追加・更新 という処理になるのは必至では・・・?
15.
テストを行いやすくするために ・初期化が必要な外部パッケージ(DBやFirebaseなど)を 直接使っているclassはテストしにくい。 ※できないわけではない: cloud_firestore_mocks (https://pub.dev/packages/cloud_firestore_mocks) ・でもビジネスロジックなので、データをUI等から受け取って、 加工して追加・更新 という処理になるのは必至では・・・? 解決策:分離して疎結合にする!
16.
ソフトウェアアーキテクチャの話
17.
ビジネスロジックの集約と依存関係の分離 ・例えばUIのクラスにすべてのロ ジックを詰め込んで実装すること もできるが、それをやってしまうと 一つのクラスが肥大化してしまう ・肥大化したクラスはメンテナンス しづらく、読みにくく、テストしにく い Robert C. Martin著 Clean
Architecture 達人に学ぶソフトウェアの構造と設計
18.
ビジネスロジックの集約と依存関係の分離 ・例えばUIのクラスにすべてのロ ジックを詰め込んで実装すること もできるが、それをやってしまうと 一つのクラスが肥大化してしまう ・肥大化したクラスはメンテナンス しづらく、読みにくく、テストしにく い Robert C. Martin著 Clean
Architecture 達人に学ぶソフトウェアの構造と設計 テスタブルなコードにするために 考えを少しだけ取り入れることにする
19.
オブジェクト指向の話 ・オブジェクト指向とは何か?と言う話はしません ・オブジェクト指向っぽいプログラミングのテクニックを少し使って 今までテストできなくなってしまっていたコードを リファクタリングすることに注力します キーワード:インターフェース、実装、抽象クラス、継承 【Flutter】Providerで最低限のDIを行ってテスタブルなコードにリファクタリングする https://qiita.com/tokkun5552/items/7af34769104e94f50745
20.
インターフェース ・メソッドの実装を強制する仕組み ・メソッドだけ定義して実際の処理は書かない →内部でDB、Firebase等の処理を書くこともない。 (依存しない) ・インターフェースを実装したクラスは、 インターフェースに定義されているメソッドを 実装しなければならない →メソッドだけを外部から見ると、全く同じ動きをする interface Hoge{ void doHoge(); } class
HogeImpl implements Hoge{ @override public void doHoge() { // 実際の処理 } } インターフェース(Javaでの例) インターフェースを実装した例
21.
インターフェース ・メソッドの実装を強制する仕組み ・メソッドだけ定義して実際の処理は書かない →内部でDB、Firebase等の処理を書くこともない。 (依存しない) ・インターフェースを実装したクラスは、 インターフェースに定義されているメソッドを 実装しなければならない →メソッドだけを外部から見ると、全く同じ動きをする interface Hoge{ void doHoge(); } class
HogeImpl implements Hoge{ @override public void doHoge() { // 実際の処理 } } インターフェース(Javaでの例) インターフェースを実装した例 ただしDartにはインターフェースが ないので、今回はabstract というのを使う ※implicit interfaceという便利な機能があるが 話がややこしくなるので割愛
22.
インターフェースの使い方 ・コンストラクタで インターフェースを受け取る ・インターフェースにはメソッドの 決まりが書いてあるので、 記載のあるメソッドは そのまま使うことが出来る class TodoItemDetailModel extends
ChangeNotifier { TodoItemDetailModel ({ @required TodoItemRepository todoItemRepository , }) : _todoItemRepository = todoItemRepository ; final TodoItemRepository _todoItemRepository ; Future <void> add() async { if (todoTitle == null || todoTitle .isEmpty) { final Error error = ArgumentError ('タイトルを入力してください。 '); throw error; } await _todoItemRepository .create( ~~ ); notifyListeners (); } https://github.com/tokku5552/TODOAppSample-Flutter/blob/v1.3/lib/presentation/todo_item_detail/todo_item_detail_model.dart
23.
インターフェースの使い方 ・コンストラクタで インターフェースを受け取る ・インターフェースにはメソッドの 決まりが書いてあるので、 記載のあるメソッドは そのまま使うことが出来る class TodoItemDetailModel extends
ChangeNotifier { TodoItemDetailModel ({ @required TodoItemRepository todoItemRepository , }) : _todoItemRepository = todoItemRepository ; final TodoItemRepository _todoItemRepository ; Future <void> add() async { if (todoTitle == null || todoTitle .isEmpty) { final Error error = ArgumentError ('タイトルを入力してください。 '); throw error; } await _todoItemRepository .create( ~~ ); notifyListeners (); } https://github.com/tokku5552/TODOAppSample-Flutter/blob/v1.3/lib/presentation/todo_item_detail/todo_item_detail_model.dart 外部通信など(DBやFirebaseを使う処理)はリ ポジトリーというクラスに集約して、 ビジネスロジックから切り離す ビジネスロジックはインターフェースに 依存する。(具体的な実装に依存しない。)
24.
では、実際の処理はどう呼ばれる?
25.
依存関係とDIの話 ・ここで登場するのがDI(Dependency Injection) よく「依存性の注入」と訳されるが、 「依存オブジェクトの注入」と考えた方が分かりやすい。 ・先の例のように依存するオブジェクトを コンストラクタなどで外から受け取るように実装する
26.
依存関係とDIの話 TodoItemDetailModel field TodoItemRepository Interface TodoItemRepository TodoItemRepositoryImpl 依存 注入 実装
27.
ProviderでDIする ・注入の処理をまとめて書くためのクラスをDIコンテナーと言う ・Flutterの場合get_itというDIコンテナーがある get_it | pub.dev
: https://pub.dev/packages/get_it ・get_itを使っても良いが、Providerの機能でもDIのようなことは出来るので、 今回はProviderを使う
28.
ProviderでDIする ・例えばmainの直下などで、 右図のように定義する ・providersの中はProviderでも、 StreamProviderでも、 ChangeNotifierProviderでも 定義できる。 ・create:でImplの方を渡す void main() { runApp( MultiProvider ( providers:
[ Provider <TodoItemRepository >( create: (_) => TodoItemRepositoryImpl (), ) ], child: App (), ), ); }
29.
ProviderでDIする ・modelを生成する場所(例えば page内のChangeNotifierProvider) でコンストラクタに渡す。 ・先ほどmainで定義した Providerは、定義した場所より 下の階層のcontextから context.read<型>() で呼び出せる ChangeNotifierProvider <TodoItemDetailModel >( create:
(_) => TodoItemDetailModel ( todoItemRepository: context .read<TodoItemRepository >(), ), Providerの詳細 参考:https://qiita.com/kabochapo/items/a90d8438243c27e2f6d9
30.
Flutterにおけるcontext ・FlutterはWidgetをツリー状に連ねて書いていく ・そのツリーの中で自分が今いる場所を表す ・HogeWidgetのbuildで引数として受け取るBuildContextには Scaffoldやそれより先祖の情報は入っているが、 FugaWidgetの情報は入ってない ・今回の例だとcontext.read<>()を記載するよりも 先祖でProviderを呼ばなければいけない main Material App Scaffold Hoge Widget FugaW idget
31.
DIを行うと、テストの時に差し替えられる ・アプリで使用するリポジトリの実装 と、テストでの実装を別々に書ける ・test側の実装は、DBを呼ばず インメモリのDBとして記述する ・XXX_test.dartの中で直接渡せばよい
32.
テスト用Repositoryの実装の例 ・DBのインスタンスは生成しない ・実際のデータは_data ・アプリ側と同様に TodoItemRepositoryを実装する class TodoItemRepositoryMemImpl implements
TodoItemRepository { final _data = <int, TodoItem>{}; ~~ @override Future<TodoItem> find({@required int id}) { return Future.value(_data[id]); } ~~
33.
テスト側で使う例 ・テスト用のrepositoryを 直接インスタンス化する ・それを直接modelに渡す ・テストの中でrepositoryを 直接操作することが可能 void main() { final
repository = TodoItemRepositoryMemImpl (); final model = TodoItemDetailModel (todoItemRepository: repository ); final dummyDate = DateTime.now();
34.
テスタブルなコードにするまとめ ・テストを行いたいclassから依存オブジェクトを排除する。 例:Firestore 、 FirebaseAuth、sqflite
、SharedPreferences ・上記のようなものを扱うRepositoryを定義して、 インターフェースと実装に分ける ・Providerでrepositoryの実装をコンストラクタで渡す ・テスト用のrepositoryを書く
35.
テスト実行を自動化しよう
36.
テスト自動化のメリット ・ローカルで毎回テストしてもいいが面倒くさい ・テストの結果がGitHub上に残る ・後になってバグが見つかった時に、どの時点まで正しかったのか追える ・プルリクをレビューする際の目安になる ・ビジネスロジックのレビューは単体テストだけ見れば正しいかどうかわかる ・ロジックに考慮漏れがあれば、レビュアーがテストを追加して 担当者がテストを通過できるように修正する とかも可能
37.
GitHub Actionsでテスト自動化 ・プロジェクト直下に.github/workflowsというフォルダを作成し、その中にyamlファイル を置いていきます。 テスト用yamlファイル↓ yamlの詳しい解説↓ flutter test の実行を行ってる https://qiita.com/tokkun5552/items/2eb6793501c152dabf33#%E3%83 %86%E3%82%B9%E3%83%88%E8%87%AA%E5%8B%95%E5%8C%96 https://qiita.com/sensuikan1973/items/0c5efb93e5db54f9d8a2
41.
Codecovやlcovでカバレッジの可視化 ・右画像のように、テスト出来ていない ところが分かる ・やり方は以下 https://qiita.com/tokkun5552/items/2eb6793501c152dabf 33#codecov%E3%81%A7%E3%82%AB%E3%83%90%E3%83 %AC%E3%83%83%E3%82%B8%E5%8F%AF%E8%A6%96%E5 %8C%96 ・実際の画面を見てみましょう
42.
まとめ ・単体テストの基本的な書き方と実行の仕方が分かった ・modelから外部処理をRepositoryに分離する方法が分かった ・RepositoryをProviderでDIする方法が分かった ・GitHub Actionsでテストを自動実行する方法が分かった ・Codecovでカバレッジを可視化する方法がわかった ご清聴ありがとうございました
Download