如果APP较小,手动测试即可。当页面达到几十个的时候,一套完整的自动化测试将有助于确保应用在发布之前正确执行,同时快速修复错误。
自动化测试方法:
单元测试:
测试单一功能、方法、类。例如,将测试单元的外部依赖模拟出来package:mockito。单元测试通常不会读取/写入磁盘、渲染到屏幕,也不会从运行测试的进程外部接收用户操作。单元测试的目标是在各种条件下验证逻辑单元的正确性。
组件测试:
测试单个Widget,目标是验证Widget如预期的外观和交互功能。测试Widget涉及多个类,并需要提供适当的Widget声明周期上下文的测试环境。例如,它应该能够接收和响应用户操作和事件,执行布局并实例化子Widget。
组件测试比单元测试更全面。
集成测试:
测试整个应用程序或应用程序的很大一部分。通常,集成测试可以在真实设备或模拟器上运行。集成测试的目标是验证应用程序作为一个整体是否正确运行,它所组成的所有Widget是否如预期的那样相互集成。还可来验证应用的性能。
经过充分测试的应用程序,往往经过非常多的单元测试、Widget测试。通过代码覆盖进行跟踪,以及覆盖所有重要使用场景的大量集成测试。
类目 | 单元测试 | 组件测试 | 集成测试 |
维护成本 | 低 | 高 | 很高 |
依赖 | 少 | 多 | 很多 |
执行速度 | 快 | 慢 | 非常慢 |
某些Flutter库,在独立的Dart VM附带的Dart SDK中是不可用的。flutter test命令允许在本地Dart VM中运行测试,使用无头版(不会显示UI)的Flutter引擎。flutter test可以运行任何测试,不管它是否依赖Flutter的库。
2.Widget测试:
实现Widget测试要在测试中执行与Widget的交互,使用Flutter提供的WidgetTester。例如,可以发送点击和滚动手势。还可以使用WidgetTester在Widget树中查找子Widget、读取文本、验证Widget属性的值是否正确。
为了帮助调试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依赖:
3.2 创建指令化的Flutter应用程序:
一个指令化的应用程序就是一个Flutter应用程序,它启用了Flutter Driver扩展。启用扩展调用enableFlutterDriverExtension().
例子:
为main.dart创建它的指令化版本,定位到
3.3 编写集成测试:
集成测试就是一个简单的package:test测试,使用Flutter Driver API告诉应用程序执行什么操作,然后验证应用程序是否执行了此操作。
例子:
滚动测试记录下性能跟踪(performance timeline)。
3.4 运行集成测试:
连接设备或虚拟器,运行如下命令:
flutter drive --target = 项目名/test_driver/user_list_scrolling.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