繁体   English   中英

如何在 Flutter 中测试 Cupertino Picker

[英]How to test Cupertino Picker in Flutter

我正在编写小部件测试 Cupertino Picker 以获取用户选择的不同值。 我找不到任何好的教程。 我遵循了这个https://github.com/flutter/flutter/blob/master/packages/flutter/test/cupertino/picker_test.dart但这不适用于我的情况。 在我的情况下,当用户从picker中选择值时,测试用例应该检查用户是否选择了正确的值或默认值。

库比蒂诺选择器代码:

List<String> ages1 = ["-- select --"];

List<String> ages2 = List<String>.generate(
    45, (int index) => (21 + index).toString(),
    growable: false);

List<String> ages = [ages1, ages2].expand((f) => f).toList();
picker.dart:
  Widget _buildAgePicker(BuildContext context) {
    final FixedExtentScrollController scrollController =
        FixedExtentScrollController(initialItem: _selectedAgeIndex);

    return GestureDetector(
      key: Key("Age Picker"),
      onTap: () async {
        await showCupertinoModalPopup<void>(
          context: context,
          builder: (BuildContext context) {
            return _buildBottomPicker(
              CupertinoPicker(
                key: Key("Age picker"),
                scrollController: scrollController,
                itemExtent: dropDownPickerItemHeight,
                backgroundColor: Theme.of(context).canvasColor,
                onSelectedItemChanged: (int index) {
                  setState(() {
                    _selectedAgeIndex = index;
                    ageValue = ages[index];
                    if (ageValue == S.of(context).pickerDefaultValue) {
                      ageDividerColor = Theme.of(context).errorColor;
                      errorText = S.of(context).pickerErrorMessage;
                      ageDividerWidth = 1.2;
                    } else {
                      ageDividerColor = Colors.black87;
                      errorText = "";
                      ageDividerWidth = 0.4;
                    }
                  });
                },
                children: List<Widget>.generate(ages.length, (int index) {
                  return Center(
                    child: Text(ages[index]),
                  );
                }),
              ),
            );
          },
        );
      },
      child: _buildMenu(
        <Widget>[
          Text(
            S.of(context).Age,
            style: TextStyle(fontSize: 17.0),
          ),
          Text(
            ages[_selectedAgeIndex],
          ),
        ],
      ),
    );
  }
 Widget _buildMenu(List<Widget> children) {
    return Container(
      decoration: BoxDecoration(
        color: Theme.of(context).canvasColor,
      ),
      height: 44.0,
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 16.0),
        child: SafeArea(
          top: false,
          bottom: false,
          child: DefaultTextStyle(
            style: const TextStyle(
              color: Colors.black,
            ),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: children,
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildBottomPicker(Widget picker) {
    return Container(
      height: dropDownPickerSheetHeight,
      padding: const EdgeInsets.only(top: 6.0),
      color: Theme.of(context).canvasColor,
      child: DefaultTextStyle(
        style: const TextStyle(
          color: Colors.black,
          fontSize: 22.0,
        ),
        child: GestureDetector(
          key: Key("picker"),
          onTap: () {},
          child: SafeArea(
            top: false,
            child: picker,
          ),
        ),
      ),
    );
  }

测试代码:

testWidgets("picker test",(WidgetTester tester)async{
   await tester.tap(find.byKey(Key("Age Picker")));

   await tester.drag(find.byKey(Key("Age Picker")), Offset(0.0,70.0));

   await tester.pumpAndSettle();

   expect(ages[1], "21");
});

我在黄金测试中使用了一个类似的例子。 为了适合您的情况,我对其进行了一些修改。 然而,最重要的部分是调用这两个方法包括: flingdrag 如果您只调用其中一个,它将无法正常工作。 至少在我的情况下,事情就是这样发生的。

 testWidgets("cupertino picker test", (WidgetTester tester) async{ // Find the gesture detector that invoke the cupertino picker final gestureDetectorFinder = find.byKey(Key('Age Picker')); await tester.tap(gestureDetectorFinder); await tester.pump(); // Find the default option (the first one) final ageFinder = find.text('21').last; expect(ageFinder, findsOneWidget); // Apply an offset to scroll const offset = Offset(0, -10000); // Use both methods: fling and drag await tester.fling( ageFinder, offset, 1000, warnIfMissed: false, ); await tester.drag( ageFinder, offset, warnIfMissed: false, ); });

您收到了哪些错误? 我已经尝试从您提供的 CupertinoPicker 片段中创建一个最小的复制品,但我确实在testWidgets()遇到了一些问题。

我注意到的一些问题是CupertinoPicker将“年龄选择器”作为其键,而GestureDetector具有“年龄选择器”键集。 请注意,该键区分大小写。 由于您要测试CupertinoPicker ,因此GestureDetector上的键集似乎是不必要的。

除此之外,没有为测试构建小部件。 我建议通过 Flutter 测试的官方文档开始https://flutter.dev/docs/cookbook/testing/widget/introduction

这是我根据您提供的片段创建的再现。

用于测试小部件的代码

void main(){
  var ages = [18, 19, 20, 21, 22, 24, 24, 25];
  testWidgets("CupertinoPicker test", (WidgetTester tester) async {
    // build the app for the test
    // https://flutter.dev/docs/cookbook/testing/widget/introduction#4-build-the-widget-using-the-widgettester
    await tester.pumpWidget(MyApp());

    // key should match the key set in the widget
    await tester.tap(find.byKey(Key("Age Picker")));

    await tester.drag(find.byKey(Key("Age Picker")), Offset(0.0, 70.0));

    await tester.pumpAndSettle();

    expect(ages[3], 21);
  });
}

应用程序的示例代码

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child:
        testPicker(),
      ),
    );
  }

  var _selectedAgeIndex = 0;
  var scrollController = FixedExtentScrollController();
  var dropDownPickerItemHeight = 50.0;
  var ageValue;
  var ages = [18, 19, 20, 21, 22, 24, 24, 25];
  testPicker(){
    return CupertinoPicker(
      key: Key("Age Picker"),
      scrollController: scrollController,
      itemExtent: dropDownPickerItemHeight,
      backgroundColor: Theme.of(context).canvasColor,
      onSelectedItemChanged: (int index) {
        setState(() {
          _selectedAgeIndex = index;
          ageValue = ages[index];
          print('CupertinoPicker age[$index]: ${ages[index]}');
          // if (ageValue == S.of(context).pickerDefaultValue) {
          //   ageDividerColor = Theme.of(context).errorColor;
          //   errorText = S.of(context).pickerErrorMessage;
          //   ageDividerWidth = 1.2;
          // } else {
          //   ageDividerColor = Colors.black87;
          //   errorText = "";
          //   ageDividerWidth = 0.4;
          // }
        });
      },
      children: List<Widget>.generate(ages.length, (int index) {
        return Center(
          child: Text('${ages[index]}'),
        );
      }),
    );
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM