最近一直斷斷續續的學習flutter,今天跟大家介紹一下flutter driver測試。
flutter測試基礎
Flutter的測試遵循Android的測試規範進行了分層。
-
單元測試:測試單一功能、方法或類。例如,被測單元的外部依賴性通常被模擬出來,如package:mockito。
-
widget 測試:(在其它UI框架稱為 元件測試) 測試的單個widget。(我們要開發一個UI介面,需要通過組合其它Widget來實現,Flutter中,一切都是Widget!)
-
整合測試: 測試一個完整的應用程式或應用程式的很大一部分。通常,整合測試可以在真實裝置或OS模擬器上執行,例如iOS Simulator或Android Emulator。
不同型別測試之間簡單對比:
單元測試 | widget測試 | 整合測試 |
---|---|---|
Confidence | Low Higher | Highest |
維護成本 | Low Higher | Highest |
依賴 | Few More | Lots |
執行速度 | Quick | Slower |
flutter driver 整合測試
整合測試就是我們最常看到的 Flutter UI自動化測試,他的執行過程一般需要在模擬器或真機上啟動App,模擬使用者的點選、輸入操作,從而完成功能的驗證。
- 首先,你要建立第一個flutter應用。
https://book.flutterchina.club/chapter2/first_flutter_app.html
下面涉及到的檔案如下:
flutter_app/
├── lib/
│ └── .dart
├── test_driver/
| ├── app.dart
| └── app_test.dart
├── pubspec.yaml
- 在
pubspec.yaml
檔案中,新增flutter_driver
外掛,所以 flutter_driver並不是建立專案標配的,需要你額外安裝。
dev_dependencies:
test: ^1.5.1
flutter_test:
sdk: flutter
flutter_driver:
sdk: flutter
然後在flutter應用根目錄下執行命令:
flutter_app> flutter pub get
Running "flutter pub get" in flutter_app... 0.6s
- 在專案的跟目錄下建立
test_driver
目錄,分別在該目錄下建立app.dart
和app_test.dart
檔案。
一個指令化的應用程式是一個Flutter應用程式,它啟用了Flutter Driver 擴充套件。啟用擴充套件請呼叫enableFlutterDriverExtension()。app.dart
檔案內容如下:
// 匯入擴充套件
import 'package:flutter_driver/driver_extension.dart';
// 匯入main入口檔案
import 'package:flutter_app/main.dart' as app;
void main() {
// 啟用擴充套件
enableFlutterDriverExtension();
app.main();
}
整合測試是一個簡單的package:test測試,它使用Flutter Driver API告訴應用程式執行什麼操作,然後驗證應用程式是否執行了此操作。
編寫繼承測試用例,app_test.dart
檔案內容如下:
import 'dart:io';
// Imports the Flutter Driver API
import 'package:flutter_driver/flutter_driver.dart';
import 'package:test/test.dart';
void main() {
group('計數器測試', () {
final counterTextFinder = find.byValueKey('counter');
FlutterDriver driver;
setUpAll(() async {
driver = await FlutterDriver.connect();
sleep(Duration(seconds: 2));
});
tearDownAll(() async {
if (driver != null) {
driver.close();
}
});
// 第一條用例
test('starts at 1', () async {
expect(await driver.getText(counterTextFinder), "0");
});
// 第二條用例
test('increments the counter', () async {
driver.tap(find.byTooltip("Increment"));
expect(await driver.getText(counterTextFinder), "1");
});
});
}
作為一個有多年測試經驗的同學,單純學習元素定位和斷言也花了我半天時間。
setUpAll()
& tearDownAll()
:定義用例開始和結束的執行動作。
driver = await FlutterDriver.connect();
連結接app,這是App測試的入口。
driver.close();
關閉瀏覽器。
driver.tap()
driver.enterText()
driver.getText()
...
flutter常用操作,觸控、輸入和獲取文字等。
find.byValueKey()
find.byTooltip()
...
元素定位,Flutter driver提供了好幾種定位方式。
expect()
斷言方法,斷言兩個值是否相等。
flutter driver API:
https://api.flutter.dev/flutter/flutter_driver/flutter_driver-library.html
執行整合測試
最後,如何執行整合測試:
flutter_app> 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.5s
Running Gradle task 'assembleDebug'...
Running Gradle task 'assembleDebug'... Done 2.4s
✓ Built build\app\outputs\apk\debug\app-debug.apk.
I/flutter (16043): Observatory listening on http://127.0.0.1:58900/uUbkcJhS5qM=/
00:00 +0: 計數器測試 (setUpAll)
VMServiceFlutterDriver: Connecting to Flutter application at http://127.0.0.1:54121/uUbkcJhS5qM=/
VMServiceFlutterDriver: Isolate found with number: 4454864095217843
VMServiceFlutterDriver: Isolate is paused at start.
VMServiceFlutterDriver: Attempting to resume isolate
VMServiceFlutterDriver: Waiting for service extension
VMServiceFlutterDriver: Connected to Flutter application.
00:03 +0: 計數器測試 starts at 1
00:03 +1: 計數器測試 increments the counter
點選 add Icon
斷言計數器加1
00:03 +2: 計數器測試 (tearDownAll)
00:03 +2: All tests passed!
Stopping application instance.