我正在尝试编写一个小部件测试,以确保向用户显示AlertDialog
。
我有一个小例子来重现这个。当用户手动使用时,小部件会显示AlertDialog,但在小部件测试中无法显示。
我尝试了几件事:
- 使用不同的方法检索按钮:
find.byKey
,find.byIcon
, - 使用不同的方法按下按钮:
tester.tap
、tester.press
- 在按下按钮后使用一些任意延迟:
await tester.pumpAndSettle(const Duration(milliseconds: 1000));
- 检查不同的预期元素:
expect(find.byElementType(AlertDialog), findsOneWidget);
,将一个不同的图标,例如pokeball和得到它:expect(find.byIcon(Icons.catching_pokemon), findsOneWidget)
- 设置
useDialog
的useRootNavigator:false
- 提示:如果运行
flutter run main.dart
,它将在设备屏幕上可视地运行测试 - 技巧2:你可以通过注解掉一些代码来运行应用程序(参见
main
函数)
简短示例
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart';
const buttonKey = Key("button");
const alertDialogKey = Key("alertDialog");
class MyApp extends StatelessWidget {
showAppDialog(BuildContext context) async {
print("Showing app dialog");
await showDialog(
context: context,
builder: (context) {
return AlertDialog(
key: alertDialogKey,
title: const Text(
"You can see this dialog, but you can't catch it with WidgetTester.",
),
icon: const Icon(Icons.catching_pokemon),
actions: [
TextButton(
onPressed: () {
// Navigator.of(context).pop();
},
child: const Text("Oops"),
),
],
);
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Dialog',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(body: SafeArea(child: Builder(builder: (context) {
return TextButton(
key: buttonKey,
child: const Text("Show dialog"),
onPressed: () async => await showAppDialog(context),
);
}))),
);
}
}
void mainTest() {
testWidgets(
"When button is pressed, dialog is shown.",
(tester) async {
final widget = MyApp();
await tester.pumpWidget(widget);
final button = find.byKey(buttonKey);
expect(button, findsOneWidget);
await tester.press(button);
await tester.pumpAndSettle();
// None of these work:
expect(find.byKey(alertDialogKey), findsOneWidget);
expect(find.byIcon(Icons.catching_pokemon), findsOneWidget);
expect(find.byElementType(AlertDialog), findsOneWidget);
},
);
}
void main() {
// Uncomment to run the app manually
// runApp(MyApp());
// Comment out to run the app manually.
mainTest();
}
2条答案
按热度按时间rfbsl7qr1#
我需要做两件事:
await tester.runAsync(() async {})
内部的按钮,因为showDialog
是一个异步函数。默认情况下,出于性能原因,Flutter在测试中实际上并不运行异步工作。🤓tester.tap
而不是tester.press
,因为press
实际上不会释放按钮,所以**.press
不会触发onPressed
回调**😈。**额外提示:**在设备上运行测试,以可视化正在发生的事情。运行
flutter run test/name_of_test.dart
。这可以帮助您了解问题所在:比如说是AlertDialog
没有显示,还是find.byType
没有找到AlertDialog
?wqlqzqxt2#
我有一个非常类似的问题,所有我需要做的是删除'等待'时,我'showDialog'。这似乎是因为pumpAndSettle在继续之前等待对话框关闭,而实际上它并没有关闭。