Fra*_*cca 4 testing dart flutter widget-test-flutter
赏金信息:如果出现以下情况,我会接受您的回答:
\ndo this instead\n\n[编辑:07/02/21] 在flutter 社区 上关注 Miyoyo#5957 ,\ndiscord
\n\n@iapicca Convert widget position to global, get width height, add both, and see if the resulting bottom right position is on screen?并使用以下答案作为参考:
给出下面的代码示例(也可以在 dartpad 上运行)
\nimport \'package:flutter_test/flutter_test.dart\';\nimport \'package:flutter/material.dart\';\n\nfinal _testKey = GlobalKey();\nconst _fabKey = ValueKey(\'fab\');\nfinal _onScreen = ValueNotifier<bool>(true);\n\nvoid main() => runApp(_myApp);\n\nconst _myApp = MaterialApp(\n home: Scaffold(\n body: MyStage(),\n floatingActionButton: MyFAB(),\n ),\n);\n\nclass MyFAB extends StatelessWidget {\n const MyFAB() : super(key: const ValueKey(\'MyFAB\'));\n\n @override\n Widget build(BuildContext context) => FloatingActionButton(\n key: _fabKey,\n onPressed: () => _onScreen.value = !_onScreen.value,\n );\n}\n\nclass MyStage extends StatelessWidget {\n const MyStage() : super(key: const ValueKey(\'MyStage\'));\n\n @override\n Widget build(BuildContext context) => Stack(\n children: [\n ValueListenableBuilder(\n child: FlutterLogo(\n key: _testKey,\n ),\n valueListenable: _onScreen,\n builder: (context, isOnStage, child) => AnimatedPositioned(\n top: MediaQuery.of(context).size.height *\n (_onScreen.value ? .5 : -1),\n child: child,\n duration: const Duration(milliseconds: 100),\n ),\n ),\n ],\n );\n}\n\nRun Code Online (Sandbox Code Playgroud)\n我想测试的是小部件off screen\n这里是到目前为止的测试代码
void main() {\n testWidgets(\'...\', (tester) async {\n await tester.pumpWidget(_myApp);\n final rect = _testKey.currentContext.findRenderObject().paintBounds;\n\n expect(tester.getSize(find.byKey(_testKey)), rect.size,\n reason: \'size should match\');\n\n final lowestPointBefore = rect.bottomRight.dy;\n print(\'lowest point **BEFORE** $lowestPointBefore ${DateTime.now()}\');\n expect(lowestPointBefore > .0, true, reason: \'should be on-screen\');\n\n await tester.tap(find.byKey(_fabKey));\n await tester.pump(const Duration(milliseconds: 300));\n final lowestPointAfter =\n _testKey.currentContext.findRenderObject().paintBounds.bottomRight.dy;\n\n print(\'lowest point **AFTER** $lowestPointAfter ${DateTime.now()}\');\n expect(lowestPointAfter > .0, false, reason: \'should be off-screen\');\n });\n}\n\n\nRun Code Online (Sandbox Code Playgroud)\n和产生的日志
\n00:03 +0: ... \nlowest point **BEFORE** 24.0 2021-02-07 16:28:08.715558\nlowest point **AFTER** 24.0 2021-02-07 16:28:08.850733\n\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1 EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK \xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\nThe following TestFailure object was thrown running a test:\n Expected: <false>\n Actual: <true>\n\nWhen the exception was thrown, this was the stack:\n#4 main.<anonymous closure> (file:///home/francesco/projects/issue/test/widget_test.dart:83:5)\n<asynchronous suspension>\n<asynchronous suspension>\n(elided one frame from package:stack_trace)\n...\n\nThis was caught by the test expectation on the following line:\n file:///home/francesco/projects/issue/test/widget_test.dart line 83\nThe test description was:\n ...\n\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\n00:03 +0 -1: ... [E] \n Test failed. See exception logs above.\n The test description was: ...\n \n00:03 +0 -1: Some tests failed. \nRun Code Online (Sandbox Code Playgroud)\n我不确定我的方法是否正确,打印中的时间表明我
\nlowest point **BEFORE** 24.0 2021-02-07 16:28:08.715558\nlowest point **AFTER** 24.0 2021-02-07 16:28:08.850733\nRun Code Online (Sandbox Code Playgroud)\n建议我\n await tester.pumpAndSettle(Duration(milliseconds: 300));\n不做我认为的事情
问题是:
解决方案:
在代码本身中添加了注释
testWidgets('...', (tester) async {
await tester.pumpWidget(MyApp);
//check screen width height - here I'm checking for scaffold but you can put some other logic for screen size or parent widget type
Rect screenRect = tester.getRect(find.byType(Scaffold));
print("screenRect: $screenRect");
//checking previous position of the widget - on our case we are animating widget position via AnimatedPositioned
// which in itself is a statefulwidget and has Positioned widget inside
//also if we have multiple widgets of same type give them uniqueKey
AnimatedPositioned widget =
tester.firstWidget(find.byType(AnimatedPositioned));
double topPosition = widget.top;
print(widget);
print("AnimatedPositioned topPosition: $topPosition}");
expect(
screenRect.bottom > topPosition && screenRect.top < topPosition, true,
reason: 'should be on-screen');
//click button to animate the widget and wait
await tester.tap(find.byKey(fabKey));
//this will wait for animation to settle or call pump after duration
await tester.pumpAndSettle(const Duration(milliseconds: 300));
//check after position of the widget
AnimatedPositioned afterAnimationWidget =
tester.firstWidget(find.byType(AnimatedPositioned));
double afterAnimationTopPosition = afterAnimationWidget.top;
Rect animatedWidgetRect = tester.getRect(find.byType(AnimatedPositioned));
print("rect of widget : $animatedWidgetRect");
expect(
screenRect.bottom > afterAnimationTopPosition &&
screenRect.top < afterAnimationTopPosition,
false,
reason: 'should be off-screen');
});
Run Code Online (Sandbox Code Playgroud)
注意:从代码中替换 _ ,因为它从测试文件中隐藏了对象。
输出:
screenRect: Rect.fromLTRB(0.0, 0.0, 800.0, 600.0)
fab clicked
rect of widget : Rect.fromLTRB(0.0, -600.0, 24.0, -576.0)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2443 次 |
| 最近记录: |