Flutter:单元测试、Widget测试、集成测试

Flutter测试应用:

如果APP较小,手动测试即可。当页面达到几十个的时候,一套完整的自动化测试将有助于确保应用在发布之前正确执行,同时快速修复错误。

自动化测试方法:

      单元测试:

                    测试单一功能、方法、类。例如,将测试单元的外部依赖模拟出来package:mockito。单元测试通常不会读取/写入磁盘、渲染到屏幕,也不会从运行测试的进程外部接收用户操作。单元测试的目标是在各种条件下验证逻辑单元的正确性。

      组件测试:

                    测试单个Widget,目标是验证Widget如预期的外观和交互功能。测试Widget涉及多个类,并需要提供适当的Widget声明周期上下文的测试环境。例如,它应该能够接收和响应用户操作和事件,执行布局并实例化子Widget。

       组件测试比单元测试更全面。

      集成测试:

                     测试整个应用程序或应用程序的很大一部分。通常,集成测试可以在真实设备或模拟器上运行。集成测试的目标是验证应用程序作为一个整体是否正确运行,它所组成的所有Widget是否如预期的那样相互集成。还可来验证应用的性能。

  

      经过充分测试的应用程序,往往经过非常多的单元测试、Widget测试。通过代码覆盖进行跟踪,以及覆盖所有重要使用场景的大量集成测试。

 

类目 单元测试 组件测试 集成测试
维护成本 很高
依赖 很多
执行速度 非常慢

 

测试依赖添加:

   Flutter:单元测试、Widget测试、集成测试_第1张图片

  1. 单元测试:

         某些Flutter库,在独立的Dart VM附带的Dart SDK中是不可用的。flutter test命令允许在本地Dart VM中运行测试,使用无头版(不会显示UI)的Flutter引擎。flutter test可以运行任何测试,不管它是否依赖Flutter的库。

Flutter:单元测试、Widget测试、集成测试_第2张图片

    2.Widget测试:

                实现Widget测试要在测试中执行与Widget的交互,使用Flutter提供的WidgetTester。例如,可以发送点击和滚动手势。还可以使用WidgetTester在Widget树中查找子Widget、读取文本、验证Widget属性的值是否正确。

Flutter:单元测试、Widget测试、集成测试_第3张图片

Flutter:单元测试、Widget测试、集成测试_第4张图片

为了帮助调试Widget测试,可以使用debugDumpApp()对测试的UI状态进行可视化,或者在模拟器上运行flutter run test/widget_test.dart查看测试运行。在运行flutter run 进行测试的会话期间,可以点击Flutter工具的部分屏幕来打印建议的Finder。

    3.集成测试:

Flutter Driver是集成测试工具,它还提供API以跟踪测试执行的操作的性能。

Flutter Driver包括:

      一个命令行工具flutter drive

      一个包package:flutter_driver(API)

Flutter Driver的功能包括:

      创建指令化的应用程序

      写一个测试

      运行测试

3.1 添加flutter_driver依赖:

Flutter:单元测试、Widget测试、集成测试_第5张图片

3.2 创建指令化的Flutter应用程序:

一个指令化的应用程序就是一个Flutter应用程序,它启用了Flutter Driver扩展。启用扩展调用enableFlutterDriverExtension().

例子:

为main.dart创建它的指令化版本,定位到

Flutter:单元测试、Widget测试、集成测试_第6张图片

Flutter:单元测试、Widget测试、集成测试_第7张图片

3.3 编写集成测试:

集成测试就是一个简单的package:test测试,使用Flutter Driver API告诉应用程序执行什么操作,然后验证应用程序是否执行了此操作。

例子:

滚动测试记录下性能跟踪(performance timeline)。

Flutter:单元测试、Widget测试、集成测试_第8张图片

Flutter:单元测试、Widget测试、集成测试_第9张图片

3.4 运行集成测试:

连接设备或虚拟器,运行如下命令:

flutter drive --target = 项目名/test_driver/user_list_scrolling.dart

这个命令将:

  • 构建--target应用,并安装在设备上
  • 启动应用
  • 运行xx/test_driver/user_list_scrolling_test.dart

该命令如何找到正确的测试文件的?

解:

flutter drive命令使用一种约定来查找测试文件,这种测试文件与--target应用程序在同一目录中具有相同文件名但具有_test后缀。

示例代码:

import 'package:flutter_test/flutter_test.dart';
import 'package:test_demo/main.dart';
import 'package:flutter/material.dart';
void main(){
  //单元测试:测试的就是某一个具体的类或者方法
  test('should return hello + something.', (){
    var string = YinLeiTestDemo.greet('Yinlei');
    expect(string, "Hello Yinlei ~~");
  });

  //widget测试:测试应用里面的小部件
  testWidgets("widget testting demo", (WidgetTester tester) async{
    await tester.pumpWidget(
      MaterialApp(
          home: TestDemo(),
      )
    );

    //查找小部件里面有没一个text的小部件,显示的文字是Hello
    final labelText =find.text('Hello');
//    expect(labelText, findsNothing);
//    expect(labelText, findsOneWidget);
    expect(labelText, findsNWidgets(1));


    //测试小部件的交互行为
    final actionChipLabelText= find.text('0');
    expect(actionChipLabelText, findsOneWidget);
    //expect是断言

    final actionChip = find.byType(ActionChip);
    await tester.tap(actionChip);
    await tester.pump();//他会帮我们重建小部件

    final actionChipLabelTextAfterTap = find.text('1');
    expect(actionChipLabelTextAfterTap, findsOneWidget);
    expect(actionChipLabelText, findsNothing);

  });

  //集成测试:测试的是整体的应用的某一个功能。一般需要2个文件。且需要在pubspec.yaml中添加如下依赖。一般test/test_driver/app.dart
//  dev_dependencies:
//  flutter_driver:
//  sdk: flutter


}
//添加对应的测试条件
import 'package:flutter_driver/flutter_driver.dart';
import 'package:test/test.dart';
//运行测试:打开终端:
//flutter driver --target=test_driver/app.dart,这个命令会去创建一个应用,然后会安装在设备上,测试会连接应用,并去操控应用。这个过程就像是用户在使用。
void main(){
  //一组测试
  group('App', (){//连接到创建的集成测试Integrationtesting
    FlutterDriver driver;
    //--------------------------------------------------------------------
    final actionChip = find.byValueKey('actionChip');
    final actionChipLabelText = find.byValueKey('actionChipLabelText');



    //--------------------------------------------------------------------
    setUpAll(() async{//运行测试之前要去做的一些事情
      driver = await FlutterDriver.connect();
    });

    tearDownAll(() async{
      if(driver != null){
        driver.close();
      }
    });

    //--------------------------------------------------------------------
    //添加测试
    test('starts at 0', () async{
      expect(await driver.getText(actionChipLabelText), '0');
    });

    test('increments the counter', () async{
      await driver.tap(actionChip);

      expect(await driver.getText(actionChipLabelText), '1');
    });

  });
}

 

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '测试',
      home: TestDemo(),
    );
  }
}



class TestDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('TestDemo'),
        elevation: 4.0,
      ),
      body: TestDemohome(),

    );
  }
}

//WidgetTest
class TestDemohome extends StatefulWidget {
  @override
  _TestDemohomeState createState() => _TestDemohomeState();
}


class _TestDemohomeState extends State {
  int count = 0 ;
  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Chip(
          label: Text('Hello'),
        ),
        //测试小部件的交互能力。
        ActionChip(
          key: Key('actionChip'),//集成测试里面会用到这个key,定位到具体的某个小部件
          label: Text('$count',key: Key('actionChipLabelText'),),
          onPressed: (){
            setState(() {
              count ++;
            });
          },
        ),
      ],
    );
  }
}


//单元测试
class YinLeiTestDemo{
  static greet(String name){
    return 'Hello $name ~~';
  }
}
//集成测试
import 'package:flutter_driver/driver_extension.dart';
import 'package:test_demo/main.dart' as app;

void main(){
  enableFlutterDriverExtension();

  app.main();
}

 


补充:

关于测试的如下错误

Flutter集成测试:Target of URI doesn't exist: 'package:test/test.dart'.

 参考我的这篇文章:

https://blog.csdn.net/qq_39969226/article/details/91849407

 

 

你可能感兴趣的:(Flutter)