TSR*_*TSR 6 testing unit-testing dart flutter
在部署我的 Flutter 应用程序之前,我想在多个屏幕尺寸上对其进行测试,以检查是否有Renderflex overflow适用于较小屏幕的应用程序。
但是当我在小部件测试期间第一次修改屏幕尺寸以匹配我在开发期间使用的设备时,我意识到小部件测试已经抛出Render overflow错误,即使它在真实设备上没有这样的错误。所以我问了这个问题How to fix A RenderFlex overflowed during Widget Test
但我在进一步调查并使用 Flutter 黄金功能测试后,将 png 从小部件测试中提取出来,我将问题缩小到文本大小的差异。
您可以在可重复步骤清楚地看到下面的窗口小部件文本中的文字是更强壮(右侧)比在真实设备的实际文本(左侧)。
Widget 测试期间较大的文本大小会导致RenderFlex error我的应用程序中出现 。
flutter runlib/main.dart
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: TextScaleComparaison(),
),
);
}
class TextScaleComparaison extends StatelessWidget {
@override
Widget build(BuildContext context) {
final widget = Scaffold(
body: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
final width = MediaQuery.of(context).size.width;
final height = MediaQuery.of(context).size.height;
final dpr = MediaQuery.of(context).devicePixelRatio;
final textScale = MediaQuery.of(context).textScaleFactor;
final vi = MediaQuery.of(context).viewInsets;
final vip = MediaQuery.of(context).viewPadding;
final font = DefaultTextStyle.of(context).style.fontFamily;
print("width is $width and height is $height and dpi is $dpr txtScale is $textScale vi is $vi vip is $vip font is $font");
return Center(child: Text("This cannot be that long!!"));
},
),
);
return widget;
}
}
Run Code Online (Sandbox Code Playgroud)
对我来说,我得到了:
I/flutter (27450): width is 411.42857142857144 and height is 797.7142857142857 and dpi is 2.625 txtScale is 1.1 vi is EdgeInsets.zero vip is EdgeInsets(0.0, 24.0, 0.0, 0.0) font is Roboto
屏幕复制width和height并textScale和devicePixelRatio在下面的代码中的下一个步骤。
test/test.dart
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:my_app/main.dart';
void main() {
testWidgets(
"Emulate real screen size",
(WidgetTester tester) async {
// Adjust these to match your actual device screen specs
final width = 414;
final height = 846;
tester.binding.window.devicePixelRatioTestValue = (2.625);
tester.binding.window.textScaleFactorTestValue = (1.1);
final dpi = tester.binding.window.devicePixelRatio;
tester.binding.window.physicalSizeTestValue = Size(width * dpi, height * dpi);
await tester.pumpWidget(
MediaQuery(
data: MediaQueryData(),
child: MaterialApp(
home: TextScaleComparaison(),
),
),
);
await expectLater(
find.byType(TextScaleComparaison),
matchesGoldenFile("text.png"),
);
},
);
}
Run Code Online (Sandbox Code Playgroud)
运行test.dart与flutter test --update-goldens test/test.dart
这将在以下位置创建一个 png 文件 test/text.png
检查日志:对我来说它打印:
width is 414.0 and height is 846.0 and dpi is 2.625 txtScale is 1.1 vi is EdgeInsets.zero vip is EdgeInsets.zero font is Roboto
TSR*_*TSR 10
这是因为所使用的字体差异的flutter test和flutter run。
Roboto如果您没有更改其他字体,则Flutter 的默认字体适用于 Android。
Roboto字体和 iOS:San Francisco字体1) 或 2) 这些字体flutter test默认不可用。Flutter 测试故意使用一种名为的字体Ahem,该字体由您在屏幕截图中看到的方形块组成。
这是预览:
Ahem字体方块比您使用的正常字体要大得多。因此,它导致RenderFlex overflow error
要在您的设备中实现近乎完美的模拟,您flutter test必须下载字体数据,然后加载您正在使用的确切字体。
要在小部件测试中加载字体,您应该在testWidgets函数内部执行或setUp:
final flamante = rootBundle.load('assets/fonts/Flamante-Roma-Medium.ttf');
await FontLoader('FlamanteRoma')
..addFont(flamante)
..load();
Run Code Online (Sandbox Code Playgroud)
然后将此字体添加到ThemeData抽小部件之前。
theme: ThemeData(
fontFamily: 'FlamanteRoma',
),
Run Code Online (Sandbox Code Playgroud)
最终的 test.dart 代码是:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:example/test/compare_test_size.dart';
void main() {
testWidgets(
"Emulate real screen size",
(WidgetTester tester) async {
final flamante = rootBundle.load('assets/fonts/Flamante-Roma-Medium.ttf');
await FontLoader('FlamanteRoma')
..addFont(flamante)
..load();
// Adjust these to match your actual device screen specs
final width = 411.4;
final height = 797.7;
tester.binding.window.devicePixelRatioTestValue = (2.625);
tester.binding.window.textScaleFactorTestValue = (1.1);
final dpi = tester.binding.window.devicePixelRatio;
tester.binding.window.physicalSizeTestValue = Size(width * dpi, height * dpi);
await tester.pumpWidget(
MediaQuery(
data: MediaQueryData(),
child: MaterialApp(
home: TextScaleComparaison(),
theme: ThemeData(
fontFamily: 'FlamanteRoma',
),
),
),
);
await expectLater(
find.byType(TextScaleComparaison),
matchesGoldenFile("text.png"),
);
},
);
}
Run Code Online (Sandbox Code Playgroud)
现在重新生成黄金测试并检查png。您将看到真正的文本,而不是框:
test/test.png
并且不要忘记在 main.dart 中添加相同的字体
runApp(
MaterialApp(
home: TextScaleComparaison(),
theme: ThemeData(
fontFamily: 'FlamanteRoma',
),
),
);
Run Code Online (Sandbox Code Playgroud)
并且不要忘记更新pubspec.yaml和运行flutter pub get
- family: FlamanteRoma
fonts:
- asset: assets/fonts/Flamante-Roma-Medium.ttf
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1951 次 |
| 最近记录: |