はじめに
テスト、書いてますか(ニコッ
私は転職してからテストをたくさん書くようになりました。
Integration Testを実装中にTextfield周りでハマってしまい、
FlutterのIssuesを漁ってようやくそれっぽいものを見つけて解決したので、
日本語の記事も特になかった為せっかくなら記事にしようと思った次第です。
ある程度Flutterの知識がある前提で進めていきます。
今回の問題
検索画面のテストの実装で、TextFieldに文字をInsertしてonEditingCompletedを呼ぼうとしたが
Flutter Driverだけではキーボード周りのメソッドを呼ぶことはできないためonEditingCompletedが発火しない。
キーボードの検索を押す以外にも別で検索ボタンみたいなものがあれば問題なかったんですけどね...
ないものはないので、頑張って実装しないといけません。
実装
flutter_testの機能を使うことにしました。
hoge.dart側でenableFlutterDriverExtension()
を呼び出す際に引数に、
flutter_testのキーボード周りの処理を用意してDataHandlerを渡しておきます。
hoge_test.dart側でFlutterDriverのrequestData(message)
メソッドを使って、
DataHandlerに用意してあるメソッドを呼び出します。
コードは以下になります。
void main() {
final textInput = TestTextInput();
final handler = (String message) {
switch (message) {
case 'prepare':
textInput.register();
break;
case 'enterText':
textInput.enterText('hoge');
textInput.receiveAction(TextInputAction.done);
textInput.unregister();
break;
default:
break;
}
};
enableFlutterDriverExtension(handler: handler);
app.main();
}
test('', () async {
driver = await FlutterDriver.connect();
await driver.requestData('prepare');
await Future<void>.delayed(const Duration(seconds: 3));
await driver.tap(find.byValueKey('TextField')); // onEditingCompletedを実装済みのもの
await Future<void>.delayed(const Duration(seconds: 3));
await driver.requestData('enterText');
await Future<void>.delayed(const Duration(seconds: 5));
});
await driver.tap(find.byValueKey('TextField'));
で対象のTextFieldをFocusしておきます。
その後driver.requestData('enterText')
でhandlerに用意してある以下のコードを呼び出して、
無理やりキーボードの検索を押した際の処理を行います。
case 'enterText':
textInput.enterText('hoge'); // TextFieldにhogeを入力
// TextFieldに完了を通知 => onEditingCompletedが発火
textInput.receiveAction(TextInputAction.done);
textInput.unregister();
break;
上記みたいなコードを書いてflutter drive
コマンドを叩くと、
いい感じにテストが進んでいってonEditingCompletedを動かすことができました。
結構ざっくりとした感じになってしまいましたが以上です。
最後に
久しぶりに文章を書きました。日本語難しいですね。