Flutter中的测试

一个经过良好测试的应用,应用有许多单元测试和widget测试,并使用代码覆盖率功能来追踪。再加上对所有主要使用场景足够多的集成测试。

Flutter中将测试分成三类:

单元测试

Widget测试

集成测试

下面分别简单介绍如何编写这个三种测试用例。

单元测试

添加依赖

dev_dependencies:
  flutter_test:
    sdk: flutter

普通逻辑测试

import 'package:test/test.dart';

void main() {
  test('my first unit test', () {
    var answer = 42;
    expect(answer, 42);
  });
}

如果需要mock依赖,可以使用Mockito库。

Widget 测试

实现一个widget测试的方式和单元测试很像,使用Flutter提供的WidgetTester工具来发送点击、滚动手势,或者在视图树寻找某个子控件、读取文本、验证widget属性是否正确等。

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

void main() {
  testWidgets('my first widget test', (WidgetTester tester) async {
    // You can use keys to locate the widget you need to test
    var sliderKey = UniqueKey();
    var value = 0.0;

    // Tells the tester to build a UI based on the widget tree passed to it
    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return MaterialApp(
            home: Material(
              child: Center(
                child: Slider(
                  key: sliderKey,
                  value: value,
                  onChanged: (double newValue) {
                    setState(() {
                      value = newValue;
                    });
                  },
                ),
              ),
            ),
          );
        },
      ),
    );
    expect(value, equals(0.0));

    // Taps on the widget found by key
    await tester.tap(find.byKey(sliderKey));

    // Verifies that the widget updated the value correctly
    expect(value, equals(0.5));
  });
}

集成测试

Flutter中的集成测试也是使用package:test编写的,其原理和Selenium/WebDriver(web)、Expresso(Android)、UI Automation(iOS)类似,测试脚本和App运行在不同的进程,测试脚本通过向App进程发送模拟事件来驱动测试流程。

添加API依赖

dev_dependencies:
  flutter_driver:
    sdk: flutter

创建instrumented Flutter应用,即开启Flutter Driver扩展的应用,通过调用enableFlutterDriverExtension()开启。

// This line imports the extension
import 'package:flutter_driver/driver_extension.dart';

void main() {
  // This line enables the extension
  enableFlutterDriverExtension();

  // Call the `main()` of your app or call `runApp` with whatever widget
  // you are interested in testing.
}

编写集成测试,测试文件位于my_app/test_driver/user_list_scrolling_test.dart

import 'dart:async';

// Imports the Flutter Driver API
import 'package:flutter_driver/flutter_driver.dart';
import 'package:test/test.dart';

void main() {
  group('scrolling performance test', () {
    FlutterDriver driver;

    setUpAll(() async {
      // Connects to the app
      driver = await FlutterDriver.connect();
    });

    tearDownAll(() async {
      if (driver != null) {
        // Closes the connection
        driver.close();
      }
    });

    test('measure', () async {
      // Record the performance timeline of things that happen inside the closure
      Timeline timeline = await driver.traceAction(() async {
        // Find the scrollable user list
        SerializableFinder userList = find.byValueKey('user-list');

        // Scroll down 5 times
        for (int i = 0; i < 5; i++) {
          // Scroll 300 pixels down, for 300 millis
          await driver.scroll(
              userList, 0.0, -300.0, Duration(milliseconds: 300));

          // Emulate a user's finger taking its time to go back to the original
          // position before the next scroll
          await Future.delayed(Duration(milliseconds: 500));
        }

        // Scroll up 5 times
        for (int i = 0; i < 5; i++) {
          await driver.scroll(
              userList, 0.0, 300.0, Duration(milliseconds: 300));
          await Future.delayed(Duration(milliseconds: 500));
        }
      });

      // The `timeline` object contains all the performance data recorded during
      // the scrolling session. It can be digested into a handful of useful
      // aggregate numbers, such as "average frame build time".
      TimelineSummary summary = TimelineSummary.summarize(timeline);

      // The following line saves the timeline summary to a JSON file.
      summary.writeSummaryToFile('scrolling_performance', pretty: true);

      // The following line saves the raw timeline data as JSON.
      summary.writeTimelineToFile('scrolling_performance', pretty: true);
    });
  });
}

执行集成测试

flutter drive --target=my_app/test_driver/user_list_scrolling.dart

上面执行命令的背后:

  1. 构建–target 对应App并安装到设备上
  2. 启动App
  3. 执行user_list_scrolling_test.dart文件的测试

你可能感兴趣的:(Flutter)