如何在Flutter集成测试中等待Finder可见以进行下一次代码执行



信息:
我创建了一个Flutter单元测试示例,用于测试我有电子邮件和;密码作为输入字段和登录按钮。

要求:
需要测试错误案例,为此,我按照以下步骤编写了代码。

  1. 打开main.dart
  2. 填写邮件&密码字段
  3. onTap事件在登录按钮上完成。在这里,API将被调用,加载程序将显示在屏幕上,直到API获得成功或失败响应
  4. 需要检查故障对话框是否显示消息

发布/查询:
现在,当API正在调用时,我希望等待加载程序可见,直到加载程序消失。所以,到目前为止,我只是手动延迟执行下一个代码,但我想让它变得动态。那么,让我知道我们如何让基于加载程序的动态延迟可见?

代码:

void main() {
group('App Test', () {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
testWidgets('Login Fail Test', (WidgetTester tester) async {
await app.main();
await tester.pumpAndSettle();
await tester.pump(new Duration(seconds: 2));
final emailField = find.byType(TextFormField).first;
final passwordField = find.byType(TextFormField).last;
final loginButton = find.byType(RaisedButton).first;
await tester.enterText(emailField, 'Test');
await tester.pumpAndSettle();
await tester.pump(new Duration(seconds: 1));
await tester.enterText(passwordField, 'Test123');
await tester.pumpAndSettle();
await tester.pump(new Duration(seconds: 1));
await tester.tap(loginButton);
await tester.pumpAndSettle();
await tester.pump(new Duration(seconds: 3));

final dialog = find.byType(AlertDialog).first;
await tester.element(dialog);
await tester.pumpAndSettle();
await tester.pump(new Duration(seconds: 1));
final dialogButton = find.byType(FlatButton).first;
await tester.tap(dialogButton);
await tester.pumpAndSettle();
await tester.pump(new Duration(seconds: 2));
});
}

我有一个名为utils.dart的文件,用于实现这样的功能。在这种情况下,我使用以下功能,它将基本上轮询,直到查找器是有效的

// utils.dart
Future<void> pumpUntilFound(
WidgetTester tester,
Finder finder, {
Duration timeout = const Duration(seconds: 10),
}) async {
bool timerDone = false;
final timer = Timer(timeout, () => timerDone = true);
while (timerDone != true) {
await tester.pump();
final found = tester.any(finder);
if (found) {
timerDone = true;
}
}
timer.cancel();
}

如果超时,你也可以让它抛出一个异常,但错误消息没有帮助,所以我通常会用expect来跟踪它

看起来像

// my_test.dart
final fab = find.byKey(const ValueKey('fab'));
await pumpUntilFound(widgetTester, fab);
expect(fab, findsOneWidget);

尝试这样包装:

testWidgets('test',
(WidgetTester tester) async {
await tester.runAsync(() async {
// test code here
});
});

如果您使用:

await tester.pumpAndSettle();

然后:

final widget = find.byKey(Key('whatever'));

它通常会发现

最新更新