環境
訳あって最新版を使っていません(macをCatalinaにアップデートできない==Xcodeの最新版を入れられないので)。
従って、バージョン違いによる不動作などあるかも知れません。お気づきの点があったら是非コメント下さい。
$ flutter --version
Flutter 1.12.13+hotfix.5 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 27321ebbad (4 months ago) • 2019-12-10 18:15:01 -0800
Engine • revision 2994f7e1e6
Tools • Dart 2.7.0
現象
WidgetTestで、pumpWidget(MyApp())
しているテストを、他のテストと連続実行したときのみ、以下のエラーが出る。
単独実行したときは、出ない。
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following UnsupportedError was thrown building MediaQuery(MediaQueryData(size: Size(800.0,
600.0), devicePixelRatio: 3.0, textScaleFactor: 1.0, platformBrightness: Brightness.light, padding:
EdgeInsets.zero, viewPadding: EdgeInsets.zero, viewInsets: EdgeInsets.zero, physicalDepth:
1.7976931348623157e+308, alwaysUse24HourFormat: false, accessibleNavigation: false, highContrast:
false,disableAnimations: false, invertColors: false, boldText: false)):
Unsupported operation: Cannot set value in unmodifiable Map
原因
どうやら、ローカライゼーション用の設定が悪さをしているようです。
Flutterをそのまま実行すると、日本語フォントがおかしくありませんか?それを解消するため、MaterialApp
に次のように指定していました。
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
// 日本語フォント設定
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
Locale('ja', ''), // Japanese
],
....
これの設定を無くすと、大丈夫でした。
このテストの前に実行するテストでは、
return MaterialApp(
home: HomePage(),
);
としてダミーのMaterialApp
を起動していて、どうやらそのクラスはテストの間で再作成していないらしく、MyApp
の設定でImuutableなMapを上書きしようとして怒られているようです。
group
を変えてみても同じでした。
解決策
1.MyAppを起動するテストを先に持ってくる
未設定のプロパティは、特に値が上書きされることはないようなので、
MyApp
→ダミーMaterialApp
の順の起動になれば、エラーが起きなくなります。
なので、テストの順番をそのように変えます。
JUnitと違い、Dartのテストは書いた順番に実行されますから、メソッドをカット&ペースとして動かすだけです。
2.TestAppクラスを作ってローカライゼーション設定を入れる
ダミーのMaterialAppを作っていたのを、TestApp
クラスとして次のようにします。
class TestApp extends StatelessWidget {
TestApp(this.widget);
final Widget widget;
@override
Widget build(BuildContext context) {
return MaterialApp(
// 日本語フォント設定
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
Locale('ja', ''), // Japanese
],
home: widget,
);
}
}
///テストコード
await tester.pumpWidget(TestApp(HomePage()));
でも、テスト時にフォントは関係ないしなあ・・・
ということで、悩ましいですが、いったん1の対応を取っています。
なお、テストファイルが違う場合は、作り直されるみたいです。というかファイル毎に別スレッドでテストしているようなログの出方をしていますので、当然ながらファイルが違うテストは全部別インスタンスでしょうね。
というかFlutterのテストレポート見づらい・・・