【Flutter】長押しでドラッグ可能になるWidgetのWidgetTest
IT技術
はじめに
FlutterのWidgetTesterにはlongPress のようなメソッドや、drag などのドラッグ用のメソッドが用意されているのですが、長押しでドラッグ可能になってから動かすlongPressDrag のようなものはメソッドは用意されていません。
そこで、DraggableのWidgetTestを参考に長押しをしたあとにドラッグ可能になるWidgetのWidgetTestを書いてみたメモを残そうと思います。
同じようなテストを書こうと思った方の参考になれば幸いです。
開発環境
開発環境は下記のとおりです。
Flutter | 3.3.2 |
使用パッケージ
0.5.0
| |
2.0.0-dev.9
| |
mockito |
5.3.1
|
build_runner |
2.2.1
|
テスト実装
テスト対象Widget
今回「長押しでドラッグ可能になるWidget」として並び替えができるreorderablesパッケージのReorderableColumn とReorderableWidget を使ったWidgetのテストを書いてみます。
対象のWidgetのファイルは下記の通りです。
1import 'package:flutter/material.dart';
2import 'package:flutter_riverpod/flutter_riverpod.dart';
3import 'package:reorderables/reorderables.dart';
4
5final draggableListProvider = Provider<DraggableListController>((ref) {
6 return const DraggableListController();
7});
8
9class DraggableListController {
10 const DraggableListController();
11
12 void onReorder(int oldIndex, int newIndex) {
13 print('oldIndex: $oldIndex');
14 print('newIndex: $newIndex');
15 }
16}
17
18class DraggableList extends ConsumerWidget {
19 const DraggableList({super.key});
20
21 @override
22 Widget build(BuildContext context, WidgetRef ref) {
23 return ReorderableColumn(
24 onReorder: (oldIndex, newIndex) {
25 ref.read(draggableListProvider).onReorder(oldIndex, newIndex);
26 },
27 children: List.generate(10, (index) {
28 return ReorderableWidget(
29 key: Key(index.toString()),
30 reorderable: true,
31 child: Text(index.toString()),
32 );
33 }),
34 );
35 }
36}
余談ですが、今回は並び替えたときに任意の処理が正しく実行されることを確認したいので、DraggableListController というクラスを用意し、Provider の値をテスト時にオーバーライドできるようにしています。
Widget Test
それでは、上記のWidgetのテストを書いていきます。
テストで確認したいことは「並び替えを行った場合 並び替え時の処理が実行されること」なので、「0というテキストが表示されているWidgetを9というテキストが表示されている箇所まで移動したら、任意の処理が実行されること」が確認できればよさそうです。
今回のメインである長押ししてドラッグする動きをテストで表す方法ですが、テスト用のジェスチャーを生成するstartGesture というメソッドを使います。
具体的には、
1 // ジェスチャーの開始地点を決定
2 final firstLocation = tester.getCenter(find.text('0'));
3 final gesture = await tester.startGesture(firstLocation);
4
5 // ドラッグ可能になるまで待機
6 await tester.pump(const Duration(seconds: 1));
7
8 // 対象の箇所まで開始地点から移動
9 await gesture.moveTo(tester.getCenter(find.text('9')));
10 await tester.pump();
という形で書くことで長押しドラッグが実現できます。
以下、テストコード全体です。
1import 'package:flutter/material.dart';
2import 'package:flutter_riverpod/flutter_riverpod.dart';
3import 'package:flutter_test/flutter_test.dart';
4import 'package:long_press_draggable_widget_test_sample/draggable_list.dart';
5import 'package:mockito/annotations.dart';
6import 'package:mockito/mockito.dart';
7
8import 'widget_test.mocks.dart';
9
10@GenerateMocks([
11 DraggableListController,
12])
13void main() {
14 testWidgets('並び替えを行った場合 並び替え時の処理が実行されること', (WidgetTester tester) async {
15 final controller = MockDraggableListController();
16 await tester.pumpWidget(
17 ProviderScope(
18 overrides: [
19 draggableListProvider.overrideWithValue(controller),
20 ],
21 child: const MaterialApp(
22 home: Scaffold(
23 body: DraggableList(),
24 ),
25 ),
26 ),
27 );
28
29 // ジェスチャーの開始地点を決定
30 final firstLocation = tester.getCenter(find.text('0'));
31 final gesture = await tester.startGesture(firstLocation);
32
33 // ドラッグ可能になるまで待機
34 await tester.pump(const Duration(seconds: 1));
35
36 // 対象の箇所まで開始地点から移動
37 await gesture.moveTo(tester.getCenter(find.text('9')));
38 await tester.pump();
39
40 // ジェスチャーを解除
41 await gesture.up();
42 await tester.pump();
43
44 // 並び替え処理が呼び出されたことを確認
45 verify(controller.onReorder(0, 9)).called(1);
46 });
47}
まとめ
今回は長押しでドラッグ可能になるWidgetのWidgetTestを書いてみました。
Flutterリポジトリ内のテストコードを見ていると勉強になることも多いので、これからもちょこちょこ覗いてみようと思います!
ライトコードでは、エンジニアを積極採用中!
ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。
採用情報へ
「好きを仕事にするエンジニア集団」の(株)ライトコードです! ライトコードは、福岡、東京、大阪の3拠点で事業展開するIT企業です。 現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。 いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。 システム開発依頼・お見積もり大歓迎! また、現在「WEBエンジニア」「モバイルエンジニア」「営業」「WEBデザイナー」「WEBディレクター」を積極採用中です! インターンや新卒採用も行っております。 以下よりご応募をお待ちしております! https://rightcode.co.jp/recruit