pmi*_*ara 7 dart flutter flutter-test
我正在尝试测试我的习惯SearchDelegate。示例测试将检查在有多少个字符后它开始给出建议。
我编写了两个示例测试,它们以某种方式相互影响。它们都是相同的,但是当我一起运行它们时,代码中后面出现的测试总是失败。
\n\n在调试时,我发现FutureBuilder方法buildSuggestions不会等待searchEngine.search(query)未来完成,但它只发生在第二次测试中。
我已经尝试在点击搜索图标后添加一个test.runAsyncwith Future.delayedinside 。另外,我简化了案例以使其更具可读性。
您可以在这里找到完整的代码:https://github.com/pmiara/search-delegate-test-fail \也可以在下面查看。
\n\n申请代码:
\n\nimport \'dart:convert\';\n\nimport \'package:flutter/material.dart\';\nimport \'package:flutter/services.dart\';\n\nclass Entity {\n final String value;\n\n Entity.fromJson(Map<String, dynamic> json) : value = json[\'value\'];\n}\n\nclass MySearchDelegate extends SearchDelegate {\n final MySearchEngine searchEngine;\n\n MySearchDelegate({@required this.searchEngine});\n\n @override\n List<Widget> buildActions(BuildContext context) {\n return [];\n }\n\n @override\n Widget buildLeading(BuildContext context) {\n return IconButton(\n icon: Icon(Icons.arrow_back),\n onPressed: () {\n close(context, null);\n },\n );\n }\n\n @override\n Widget buildResults(BuildContext context) {\n return FutureBuilder<List<Entity>>(\n future: searchEngine.search(query),\n builder: (BuildContext context, AsyncSnapshot<List<Entity>> snapshot) {\n if (snapshot.connectionState == ConnectionState.done &&\n snapshot.hasData) {\n final entities = snapshot.data;\n return ListView.builder(\n itemCount: entities.length,\n itemBuilder: (context, index) => ListTile(\n title: Text(entities[index].value),\n onTap: () => close(context, entities[index]),\n ),\n );\n } else {\n return Column();\n }\n },\n );\n }\n\n @override\n Widget buildSuggestions(BuildContext context) {\n return FutureBuilder<List<Entity>>(\n future: searchEngine.search(query),\n builder: (BuildContext context, AsyncSnapshot<List<Entity>> snapshot) {\n if (snapshot.connectionState == ConnectionState.done &&\n snapshot.hasData) {\n final entities = snapshot.data;\n return ListView.builder(\n itemCount: entities.length,\n itemBuilder: (context, index) => ListTile(\n title: Text(entities[index].value),\n onTap: () {\n query = entities[index].value;\n showResults(context);\n },\n ),\n );\n } else {\n return Column();\n }\n },\n );\n }\n}\n\nclass MySearchEngine {\n Future<List<Entity>> search(String query) async {\n final jsonEntities =\n await rootBundle.loadString(\'test_resources/entities.json\');\n final entities = jsonDecode(jsonEntities)\n .map<Entity>((json) => Entity.fromJson(json))\n .toList();\n return entities;\n }\n}\n\nclass TestHomePage extends StatelessWidget {\n final MySearchDelegate delegate;\n\n const TestHomePage({@required this.delegate});\n\n @override\n Widget build(BuildContext context) {\n return MaterialApp(\n home: Builder(\n builder: (BuildContext context) {\n return Scaffold(\n body: Center(\n child: IconButton(\n icon: Icon(Icons.search),\n onPressed: () async {\n showSearch(\n context: context,\n delegate: delegate,\n );\n },\n ),\n ),\n );\n },\n ),\n );\n }\n}\n\n/// Run to see what tests should "see"\nvoid main() => runApp(\n TestHomePage(\n delegate: MySearchDelegate(\n searchEngine: MySearchEngine(),\n ),\n ),\n );\nRun Code Online (Sandbox Code Playgroud)\n\n测试文件:
\n\nimport \'package:flutter/material.dart\';\nimport \'package:flutter_test/flutter_test.dart\';\nimport \'package:search_delegate_test/search_delegate_problem.dart\';\n\nvoid main() {\n testWidgets(\'First test\', (WidgetTester tester) async {\n final delegate = MySearchDelegate(\n searchEngine: MySearchEngine(),\n );\n await tester.pumpWidget(\n TestHomePage(\n delegate: delegate,\n ),\n );\n await tester.tap(find.byIcon(Icons.search));\n await tester.pumpAndSettle();\n await tester.enterText(find.byType(TextField), \'query\');\n await tester.pumpAndSettle();\n\n expect(find.byType(ListTile), findsNWidgets(3));\n });\n\n testWidgets(\'Second test\', (WidgetTester tester) async {\n final delegate = MySearchDelegate(\n searchEngine: MySearchEngine(),\n );\n await tester.pumpWidget(\n TestHomePage(\n delegate: delegate,\n ),\n );\n await tester.tap(find.byIcon(Icons.search));\n await tester.pumpAndSettle();\n await tester.enterText(find.byType(TextField), \'query\');\n await tester.pumpAndSettle();\n\n expect(find.byType(ListTile), findsNWidgets(3));\n });\n}\nRun Code Online (Sandbox Code Playgroud)\n\npubsec.yaml:
\n\nname: search_delegate_test\ndescription: A new Flutter application.\n\nversion: 1.0.0+1\n\nenvironment:\n sdk: ">=2.2.2 <3.0.0"\n\ndependencies:\n flutter:\n sdk: flutter\n\ndev_dependencies:\n flutter_test:\n sdk: flutter\n test: any\n\nflutter:\n assets:\n - test_resources/\n\n uses-material-design: true\nRun Code Online (Sandbox Code Playgroud)\n\ntest_resources/entities.json:
\n\n[\n {\n "value": "abc"\n },\n {\n "value": "abc123"\n },\n {\n "value": "123def"\n }\n]\nRun Code Online (Sandbox Code Playgroud)\n\n结果flutter doctor(我正在使用 Android Studio):
Doctor summary (to see all details, run flutter doctor -v):\n[\xe2\x9c\x93] Flutter (Channel stable, v1.7.8+hotfix.4, on Linux, locale pl_PL.UTF-8)\n\n[\xe2\x9c\x93] Android toolchain - develop for Android devices (Android SDK version 28.0.3)\n[\xe2\x9c\x93] Android Studio (version 3.4)\n[!] IntelliJ IDEA Ultimate Edition (version 2019.1)\n \xe2\x9c\x97 Flutter plugin not installed; this adds Flutter specific functionality.\n \xe2\x9c\x97 Dart plugin not installed; this adds Dart specific functionality.\n[!] IntelliJ IDEA Community Edition (version 2019.1)\n \xe2\x9c\x97 Flutter plugin not installed; this adds Flutter specific functionality.\n \xe2\x9c\x97 Dart plugin not installed; this adds Dart specific functionality.\n[\xe2\x9c\x93] Connected device (1 available)\n\n! Doctor found issues in 2 categories.\nRun Code Online (Sandbox Code Playgroud)\n\n我得到的错误:
\n\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: exactly 3 matching nodes in the widget tree\n Actual: ?:<zero widgets with type "ListTile" (ignoring offstage widgets)>\n Which: means none were found but some were expected\n\nWhen the exception was thrown, this was the stack:\n#4 main.<anonymous closure> (file:///path/to/project/search_delegate_test/test/serach_delegate_problem_test.dart:37:5)\n<asynchronous suspension>\n#5 testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:118:25)\n<asynchronous suspension>\n#6 TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:630:19)\n<asynchronous suspension>\n#9 TestWidgetsFlutterBinding._runTest (package:flutter_test/src/binding.dart:613:14)\n#10 AutomatedTestWidgetsFlutterBinding.runTest.<anonymous closure> (package:flutter_test/src/binding.dart:1010:24)\n#16 AutomatedTestWidgetsFlutterBinding.runTest (package:flutter_test/src/binding.dart:1007:15)\n#17 testWidgets.<anonymous closure> (package:flutter_test/src/widget_tester.dart:116:22)\n#18 Declarer.test.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart:168:27)\n<asynchronous suspension>\n#19 Invoker.waitForOutstandingCallbacks.<anonymous closure> (package:test_api/src/backend/invoker.dart:250:15)\n<asynchronous suspension>\n#24 Invoker.waitForOutstandingCallbacks (package:test_api/src/backend/invoker.dart:247:5)\n#25 Declarer.test.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart:166:33)\n#30 Declarer.test.<anonymous closure> (package:test_api/src/backend/declarer.dart:165:13)\n<asynchronous suspension>\n#31 Invoker._onRun.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/invoker.dart:400:25)\n<asynchronous suspension>\n#45 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:382:19)\n#46 _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:416:5)\n#47 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:172:12)\n(elided 28 frames from class _FakeAsync, package dart:async, package dart:async-patch, and package stack_trace)\n\nThis was caught by the test expectation on the following line:\n file:///path/to/project/search_delegate_test/test/serach_delegate_problem_test.dart line 37\nThe test description was:\n Second test\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\n\nTest failed. See exception logs above.\nThe test description was: Second test\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
1118 次 |
| 最近记录: |