Flutter自动测试:点击抽屉中的按钮不起作用

vof42yt1  于 2022-12-05  发布在  Flutter
关注(0)|答案(6)|浏览(202)

我正在尝试使用flutter进行一些TDD测试,当测试运行时,如果按钮在抽屉里,点击按钮是不起作用的。
在下面的例子中,我们按下两个按钮,在控制台中打印一条消息。下面是操作:
找到并点击支架上的按钮:好的
打开抽屉:好的
在抽屉中定位按钮:好的
轻触抽屉按钮:"什么都没发生"

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('Test that drawer is apparing and we can click on button',
  (WidgetTester tester) async {
final scaffoldKey = GlobalKey<ScaffoldState>();

await tester.pumpWidget(new MaterialApp(
  title: 'Where Assistant',
  home: Scaffold(
    key: scaffoldKey,
    body: Column(
      children: <Widget>[
        Text('test text'),
        RaisedButton(
          onPressed: () {
            print('OK on main screen');
          },
          child: Icon(Icons.access_alarm),
        ),
      ],
    ),
    drawer: Drawer(
      // Add a ListView to the drawer. This ensures the user can scroll
      // through the options in the Drawer if there isn't enough vertical
      // space to fit everything.
      child: ListView(
        // Important: Remove any padding from the ListView.
        padding: EdgeInsets.zero,
        children: <Widget>[
          DrawerHeader(
            child: Text('Drawer Header'),
            decoration: BoxDecoration(
              color: Colors.blue,
            ),
          ),
          ListTile(
            title: Text('Item 2'),
            onTap: () {
              // Update the state of the app
              // ...
            },
          ),
          RaisedButton(
            onPressed: () {
              print('OK drawer');
            },
            child: Icon(Icons.add),
          )
        ],
      ),
    ),
  ),
));

await tester.pump();

expect(find.text('test text'), findsOneWidget);
expect(find.byIcon(Icons.access_alarm), findsOneWidget);
await tester.tap(find.byIcon(Icons.access_alarm));
expect(find.byIcon(Icons.add), findsNothing);

scaffoldKey.currentState.openDrawer();
await tester.pump(); // drawer should appear

expect(find.text('Item 2'), findsOneWidget);
expect(find.byIcon(Icons.add), findsOneWidget);
await tester.tap(find.byIcon(Icons.add));
print('end of test');
  });
}
lztngnrs

lztngnrs1#

我也遇到了类似的问题。
测试人员能够在抽屉中找到FlatButton:

expect(find.byType(FlatButton), findsOneWidget);

tap似乎不工作:

await tester.tap(find.byType(FlatButton));

但是Flutter issue中提到的解决方案确实起作用了:

FlatButton button = find.widgetWithText(FlatButton, 'TextExample').evaluate().first.widget;
button.onPressed();
vatpfxk5

vatpfxk52#

终于找到了一个解决办法:只需要在敲抽屉之前加一些延迟。
所以我加了一句

await tester.pump(const Duration(milliseconds: 100));

在点击按钮之前

vjrehmav

vjrehmav3#

我还没有玩过WidgetTest,但我能够实现点击抽屉内的按钮,与Flutter驱动程序。

test('test button tap in drawer', () async {

    final SerializableFinder drawerOpenButton = find.byTooltip('Open navigation menu');
    final SerializableFinder btn = find.byValueKey('firstButton');

    await driver.waitFor(drawerOpenButton);
    await driver.tap(drawerOpenButton);
    await driver.waitFor(btn);
    await driver.tap(btn);
    print('tapped');
    });

main.dart中,我使用了key属性作为要点击的RaisedButton

fhg3lkii

fhg3lkii4#

我的问题是GestureDetectoronTap回调在Widget树中太深,
我最终创建了一个新的stateless Widget类型,它直接 Package GestureListener并将必要的数据传递到那里。
所以find.byWidgetPredicate((widget) => widget is ActionClickableButton).first起作用了。

ecr0jaav

ecr0jaav5#

等待抽屉 * 完全打开 *

抽屉打开是一个动画,随着时间的推移滑出。
在抽屉完全展开之前,我们不应该尝试测试里面的小部件。
pumpAndSettle()或启动.openDrawer()后的“双泵”是两种解决方案。
pumpAndSettle()

final ScaffoldState scafState = tester.firstState(find.byType(Scaffold));
scafState.openDrawer();
await tester.pumpAndSettle();
// do taps below here
  • 如果您在测试过程中运行了其他动画,则在 * 所有 * 动画完成或10分钟(默认超时)后,才会“稳定”/返回。

...或

pump()

final ScaffoldState scafState = tester.firstState(find.byType(Scaffold));
scafState.openDrawer();
await tester.pump(); // 99% of Drawer still offstage
await tester.pump(const Duration(seconds: 1)); // ←- This is important
// do taps below here

scaffoldState.openDrawer();

  • 已“请求”打开抽屉
  • 但舞台上还没有任何变化(没有建造/布置/粉刷),抽屉100%离开舞台
  • 抽屉小部件不在台上/无法点击

泵送和沉降()

await tester.pumpAndSettle();

  • 当(任何)动画正在进行时,每100 ms泵一帧
  • 在100 ms等待之间,这不执行任何操作
  • binder.hasScheduledFrame为false时返回(没有更多动画帧,从抽屉打开***或其他动画***)

双泵()

await tester.pump();

  • 触发构建/布局/绘画,开始动画
  • 此处仅为抽屉打开动画的***第一***帧
  • 99%的抽屉内容仍在后台且不可点击
  • 命中目标不在舞台上/无法点击

await tester.pump(const Duration(seconds: 1);

  • 在调用pump()(再次)“渲染”当前情况的一帧之前,***会等待一整秒。(这不能单独用于启动和等待动画完成,因为这会等待1秒过去***然后***调用pump()一次。这只会 * 启动 * 动画。)
  • 由前一个pump()启动的动画有1000毫秒(大部分跳过的帧)要完成
  • 抽屉应完全打开,抽屉内的所有物品应全部放在台上
  • 现在应该可以查找/点击抽屉按钮小部件
  • a Flutter框架本身的支架测试和Drawer tests使用了该技术
bf1o4zei

bf1o4zei6#

试试这个代码..这是工作抽屉点击..

class DrawerItem {
 String title;
 IconData icon;

 DrawerItem(this.title, this.icon);
}

 class MyHomeScreenStateFull extends StatefulWidget {
 // here define drawer item
 final drawerItems = [
 new DrawerItem("Home", Icons.save),
 new DrawerItem("Event", Icons.local_pizza)

];

@override
State<StatefulWidget> createState() {
// TODO: implement createState
return MyHomeScreenState();
}
}

class MyHomeScreenState extends State<MyHomeScreenStateFull> {
int selectedDrawerIndex = 0;
// here define other screen.
 getDrawerItemWidget(int pos) {
 switch (pos) {
  case 0:
    return new FirstFragmentStateFull();
  case 1:
    return new SecondFragmentStateFull();

  default:
    return new Text("Error");
 }
 }

 onSelectItem(int index) {
setState(() => selectedDrawerIndex = index);
Navigator.of(context).pop(); // close the drawer
}

@override
Widget build(BuildContext context) {
var drawerOptions = <Widget>[];
for (var i = 0; i < widget.drawerItems.length; i++) {
  var d = widget.drawerItems[i];
  drawerOptions.add(new ListTile(
    leading: new Icon(d.icon),
    title: new Text(
      d.title,
      style: TextStyle(fontSize: 15),
    ),
    selected: i == selectedDrawerIndex,
    onTap: () => onSelectItem(i),
  ));
  }

  return Scaffold(
  appBar: AppBar(
    title: new Text(widget.drawerItems[selectedDrawerIndex].title),
  ),
  /*body: Center(
    child: Text("Welcome To Home"),
  ),*/
  drawer: Drawer(
    child: Column(
      children: <Widget>[
        new UserAccountsDrawerHeader(
          decoration: BoxDecoration(color: Colors.blue),
          accountName: Text("Vikas Pandey "),
          accountEmail: null,
          currentAccountPicture: Container(
            decoration: BoxDecoration(
                shape: BoxShape.circle,
                image: DecorationImage(
                    fit: BoxFit.fill,
                    image: NetworkImage(
                        "https://via.placeholder.com/600/92c952"))),
          ),
        ),
        new Column(
          children: drawerOptions,
        )
      ],
    ),
  ),
  body: getDrawerItemWidget(selectedDrawerIndex),
);
}
}

相关问题