小部件测试以断言文本小部件样式

Posted

技术标签:

【中文标题】小部件测试以断言文本小部件样式【英文标题】:Widget testing to assert Text widgets style 【发布时间】:2021-08-13 18:08:49 【问题描述】:

我正在构建一个任务/待办事项小部件。 Task 小部件是使用 ListTileCheckbox 小部件实现的。

class _TaskListItemState extends State<TaskListItem> 
  @override
  Widget build(BuildContext context) 
    return InkWell(
      onTap: _goToTaskScreen,
      child: ListTile(
        leading: Checkbox(
            value: widget.task.isComplete, onChanged: _toggleTaskComplete),
        title: Text(
          widget.task.title,
          style: TextStyle(
              decoration: widget.task.isComplete
                  ? TextDecoration.lineThrough
                  : null,
              color: widget.task.isComplete ? Colors.grey : null),
        ),
      ),
    );
  

  void _goToTaskScreen() ...

  void _toggleTaskComplete(bool? value) ...);
  

我正在尝试测试小部件,如果任务完成,那么小部件的文本样式装饰应该是删除线,否则正常。

testWidgets(
    'if the isCompleted is true, then title text should be strikethrough',
    (WidgetTester tester) async 
  // Arrange
  const testKey = ValueKey('my-key-1');
  const testTitle = 'Demo title';
  const testProjectID = 555;
  final DateTime testDueDate = DateTime.now();
  const testIsComplete = true;

  final Task taskComplete = Task(
      title: testTitle,
      projectID: testProjectID,
      dueDate: testDueDate,
      isComplete: testIsComplete);

  await tester.pumpWidget(MaterialApp(
    home: Material(
      child: TaskListItem(key: testKey, task: taskComplete),
    ),
  ));

  final textFinder = find.byType(Text);
  final textWidget = tester.firstWidget(textFinder);

  expect(textWidget.style.decoration, TextDecoration.lineThrough);
);

运行flutter run时应用运行良好。

但是在运行flutter test时会引发错误:

est/widgets/task_list_item_test.dart:57:25: 错误:getter 'style' 没有为“Widget”类定义。

'Widget' 来自'package:flutter/src/widgets/framework.dart' ('/C:/flutter/packages/flutter/lib/src/widgets/framework.dart')。尝试 将名称更正为现有 getter 的名称,或定义一个 getter 或名为“样式”的字段。 期望(textWidget.style.decoration,TextDecoration.lineThrough); ^^^^^

我知道我错过了一些东西,因为我学习 Flutter 才一个多星期。你能帮我如何执行小部件测试来断言文本小部件样式。谢谢!

【问题讨论】:

【参考方案1】:

您可以尝试将firstWidget 方法转换为Text,如下所示:

final textFinder = find.byType(Text);
final textWidget = tester.firstWidget<Text>(textFinder);

为确保类型存储在textWidget 对象中。

【讨论】:

【参考方案2】:

在我自己遇到这个问题并研究了在Text 小部件上测试/断言样式的解决方案后,我发现find.byWidgetPredicate 方法最有效地实现了这一目标。

对于你的情况,你可以像这样使用byWidgetPredicate

// Define your finder with specific conditions here:
final textWithStrikeThrough = find.byWidgetPredicate(
  (widget) =>
    widget is Text &&
    widget.style.decoration == TextDecoration.lineThrough,
  description: '`Text` widget with strike through',
);

// Now you can use this finder like other finders.
expect(
  textWithStrikeThrough,
  findsOneWidget,
);

【讨论】:

以上是关于小部件测试以断言文本小部件样式的主要内容,如果未能解决你的问题,请参考以下文章

吐司消息样式变化?只有 Toast 消息没有 Snackbar 其他没有小部件

小部件库捕获的异常。 (断言失败)

Dojo 选择小部件验证

Flutter 小部件测试点击 - 不会在指定的小部件上进行测试

如何在 tkinter Text 小部件中突出显示文本

如何测试 Flutter 小部件的固有大小