Flutter - 测试

测试是应用程序开发生命周期中非常重要的阶段。它确保应用程序具有高质量。测试需要仔细的规划和执行。它也是开发中最耗时的阶段。

Dart 语言和 Flutter 框架为应用程序的自动化测试提供了广泛的支持。

测试类型

通常,有三种类型的测试流程可用于完整测试应用程序。它们如下 −

单元测试

单元测试是测试应用程序最简单的方法。它基于确保一段代码(通常是函数)或类的方法的正确性。但是,它不能反映真实环境,因此是查找错误的最少选择。

Widget 测试

Widget 测试基于确保 widget 创建、渲染和与其他 widget 交互的正确性。它更进一步,提供近乎实时的环境来查找更多错误。

集成测试

集成测试涉及单元测试和 widget 测试以及应用程序的外部组件,如数据库、Web 服务等,它模拟或模拟真实环境以查找几乎所有错误,但这是最复杂的过程。

Flutter 为所有类型的测试提供支持。它为 Widget 测试提供了广泛且独家的支持。在本章中,我们将详细讨论 widget 测试。

Widget 测试

Flutter 测试框架提供了 testWidgets 方法来测试 widget。它接受两个参数 −

  • 测试描述
  • 测试代码
testWidgets('test description: find a widget', '<test code>');

涉及的步骤

Widget 测试涉及三个不同的步骤 −

  • 在测试环境中渲染 widget。

  • WidgetTester 是 Fl​​utter 测试框架提供的用于构建和渲染 widget 的类。WidgetTester 类的 pumpWidget 方法接受任何 widget 并在测试环境中渲染它。

testWidgets('finds a specific instance', (WidgetTester tester) async { 
   await tester.pumpWidget(MaterialApp( 
      home: Scaffold( 
         body: Text('Hello'), 
      ), 
   )); 
});
  • 查找我们需要测试的 widget。

    • Flutter 框架提供了许多选项来查找在测试环境中渲染的 widget,它们通常称为 Finders。最常用的查找器是 find.text、find.byKey 和 find.byWidget。

      • find.text 查找包含指定文本的小部件。

find.text('Hello')
      • find.byKey 通过其特定键查找小部件。

find.byKey('home')
      • find.byWidget 通过其实例变量查找小部件。

find.byWidget(homeWidget)
  • 确保 widget 按预期工作。

  • Flutter 框架提供了许多选项来将 widget 与预期 widget 进行匹配,它们通常被称为 匹配器。我们可以使用测试框架提供的 expect 方法来匹配 widget,我们在第二步中找到的 widget 与我们预期的 widget,方法是选择任何匹配器。一些重要的匹配器如下。

    • findsOneWidget − 验证是否找到了单个 widget。

expect(find.text('Hello'), findsOneWidget);
    • findsNothing − 验证未找到任何小部件

expect(find.text('Hello World'), findsNothing);
    • findsWidgets − 验证找到的部件不止一个。

expect(find.text('Save'), findsWidgets);
    • findsNWidgets −验证是否找到了 N 个 widget。

expect(find.text('Save'), findsNWidgets(2));

完整测试代码如下 −

testWidgets('finds hello widget', (WidgetTester tester) async { 
   await tester.pumpWidget(MaterialApp( 
      home: Scaffold( 
         body: Text('Hello'), 
      ), 
   )); 
   expect(find.text('Hello'), findsOneWidget); 
});

在这里,我们使用 Text 小部件在其主体中渲染了一个带有文本 Hello 的 MaterialApp 小部件。然后,我们使用 find.text 查找小部件,然后使用 findsOneWidget 进行匹配。

工作示例

让我们创建一个简单的 Flutter 应用程序并编写一个小部件测试,以更好地理解所涉及的步骤和概念。

  • 在 Android Studio 中创建一个新的 Flutter 应用程序 Flutter_test_app。

  • 在测试文件夹中打开 widget_test.dart。它有一个示例测试代码,如下所示。 −

testWidgets('Counter increments smoke test', (WidgetTester tester) async {
    // 构建我们的应用并触发一个框架。
    await tester.pumpWidget(MyApp());
    
    // 验证我们的计数器是否从 0 开始。
    expect(find.text('0'), findsOneWidget);
    expect(find.text('1'), findsNothing);
    
    // 点击"+"图标并触发一个框架。
    await tester.tap(find.byIcon(Icons.add));
    await tester.pump();
    
    // 验证我们的计数器是否已递增。
    expect(find.text('0'), findsNothing);
    expect(find.text('1'), findsOneWidget);
});
  • 此处,测试代码执行以下功能 −

    • 使用 tester.pumpWidget 呈现 MyApp 小部件。

    • 使用 findsOneWidget 和 findsNothing 匹配器确保计数器最初为零。

    • 使用 find.byIcon 方法查找计数器增量按钮。

    • 使用 tester.tap 方法点击计数器增量按钮。

    • 使用 findsOneWidget 和 findsNothing 匹配器确保计数器增加。

  • 让我们再次点击计数器增量按钮,然后检查计数器是否增加到二。

await tester.tap(find.byIcon(Icons.add));
await tester.pump();

expect(find.text('2'), findsOneWidget);
  • 点击 Run 菜单。

  • 点击 widget_test.dart 选项中的 tests。这将运行测试并在结果窗口中报告结果。

Flutter 测试