集成测试
单元测试和Widget测试对某一个单独的函数 类 或者 一个Widget 它们并不能一起测试
我们以前测试这个应用程序 就直接跑在真机上再来做测试
但是这里就有一个问题 就是有些测试我们是是希望 每次写完代码 都希望能点击几下来做一个测试
而我们又想对这个整个这个应用程序来做一个测试 这个是时候我们就可以使用集成测试了
发布一个可测试的应用程序到真机上
我们新建一个文件 counter_demo_test.dart你跑起来这个文件它会自己把这个文件启动起来 并且 我们可以在里面写很多的操作
这样我们就省去了点击操作的时间 当我们要跑这个文件的时候
我们要想写这个测试 我们要先依赖一个测试
现在这里是添加两个依赖 像这个测试
然后使用这个 FlutterDriver
首先需要添加 依赖
新建一个文件 test_app.dart
import 'package:flutter_driver/flutter_driver.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
group("counter application test", () {
FlutterDriver driver;
setUpAll(() {
driver = FlutterDriver.connect();
});
});
}
这个获得driver的方式和java的数据库连接一样connect
我们首先要对我们的应用程序做一个安装
然后我们既要做测试代码了
最后我们要把这个driver关掉
这里我们把引用程序 启动了之后它就会自动启动吗
并不会 它怎么知道要找这个引用程序呢
这里我们把名字改一下 改成 app_test.dart
同时我们还需要一个 文件来启动应用程序
app.dart
import 'package:flutter_driver/driver_extension.dart';
import "package:testsample/main.dart" as app;
void main() {
// 1. 初始化Driver
enableFlutterDriverExtension();
// 2. 启动应用程序
}
我们通过
import “package:testsample/main.dart” as app;
这个语句就把这个东西引入文件中了
这里我们就要调用这个里面的main方法
所以我们用as app app.main()
就可以启动这个程序了
app.dart 这样我们就可以启动这个程序了
import 'package:flutter_driver/driver_extension.dart';
import "package:testsample/main.dart" as app;
void main() {
// 1. 初始化Driver
enableFlutterDriverExtension();
// 2. 启动应用程序
app.main();
}
这样我们就可以
然后我们将集成测试的代码放到一个文件夹里面
启动的代码 需要自己在终端里面写 这里没有快捷建 来使用这个东西
注意我们的集成测试的文件夹命名是有规定的 所以名字还不能乱取 这里 它是直接调用的test_drive 来调用的 app_test.dart
所以这里必须叫 test_driver
这样就可以启动了
而且这里报错了
这里我们找不到dart:ui 这个问题其实是 导包不对引起的 我们这导入的包是flutter_test/flutter_test.dart我们因该导入的是test/test.dart才对
这样就可以了
我们如果要做测试 我们就要拿到对应的widget 然后再做测试
对我们我们的app 我们必须绑定key
然后我们用这个测试的用例
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
key: ValueKey("counter"),
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
key: ValueKey("increment"),
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
然后就是
使用这个key的值和 ref有点像 我们直接取到的对用的组件的东西
import 'package:flutter_driver/flutter_driver.dart';
//import 'package:flutter_test/flutter_test.dart';
import "package:test/test.dart";
void main() {
group("Counter App Test", () {
FlutterDriver driver;
// 初始化操作
setUpAll(() async {
driver = await FlutterDriver.connect();
});
// 测试结束操作
tearDownAll(() {
if (driver != null) {
driver.close();
}
});
// 编写测试代码
final counterTextFinder = find.byValueKey('counter');
final buttonFinder = find.byValueKey('increment');
test("starts at 0", () async {
expect(await driver.getText(counterTextFinder), "0");
});
test("on tap click", () async {
await driver.tap(buttonFinder);
expect(await driver.getText(counterTextFinder), "1");
});
});
}
执行结果
C:\Study\Cord\testsample>flutter drive --target=test_driver/app.dart
Using device Android SDK built for x86.
Starting application: test_driver/app.dart
Installing build\app\outputs\apk\app.apk... 1.9s
Running Gradle task 'assembleDebug'...
Running Gradle task 'assembleDebug'... Done 10.3s
√ Built build\app\outputs\apk\debug\app-debug.apk.
D/FlutterActivity(29216): Using the launch theme as normal theme.
D/FlutterActivityAndFragmentDelegate(29216): Setting up FlutterEngine.
D/FlutterActivityAndFragmentDelegate(29216): No preferred FlutterEngine was provided. Creating a new FlutterEngine for this FlutterFragment.
I/flutter (29216): Observatory listening on http://127.0.0.1:37587/3DrHsO5FZdE=/
D/FlutterActivityAndFragmentDelegate(29216): Attaching FlutterEngine to the Activity that owns this Fragment.
D/FlutterView(29216): Attaching to a FlutterEngine: io.flutter.embedding.engine.FlutterEngine@5c1e68b
D/FlutterActivityAndFragmentDelegate(29216): Executing Dart entrypoint: main, and sending initial route: /
00:00 +0: Counter App Test (setUpAll)
[info ] FlutterDriver: Connecting to Flutter application at http://127.0.0.1:64493/3DrHsO5FZdE=/
[trace] FlutterDriver: Isolate found with number: 3261186132154635
[trace] FlutterDriver: Isolate is paused at start.
[trace] FlutterDriver: Attempting to resume isolate
[trace] FlutterDriver: Waiting for service extension
[info ] FlutterDriver: Connected to Flutter application.
00:02 +0: Counter App Test starts at 0
00:02 +1: Counter App Test on tap click
00:02 +2: Counter App Test (tearDownAll)
00:02 +2: All tests passed!
Stopping application instance.
但是这里 就没有问题了 所以这里我们导包的时候不能用flutter默认的flutter_test下面的包
这就是关于我们的集成测试 这个就是流程
我们使用集成测试 需要的步骤
- 最好先将这个东西 安装到模拟器上
- 创建测试文件 和启动文件
- 通过启动命名来启动集成测试 flutter drive --target=test_driver/app.dart
注意这些东西 官方文档里面都是没有的
这就是我们的测试 一般来说如果公司没有要求 是不会写 而且会比较花时间 但是没有这些时间 所以我们 开发人员一般是不会用这个 集成测试的