0%

【文章翻譯】Updates on Flutter Testing

【文章內容使用 Gemini 1.5 Pro 自動產生】

更新整合測試,支援行動端的 Firebase Test Lab;同時也支援網頁和桌面端的獨立支援!

Flutter 的目標是提供一個開放的框架,用於在多個平台上快速構建精美的原生應用程式。實現這個目標的很大一部分是能夠輕鬆地測試您的 Flutter 應用程式,以確保它們按您的意願工作,並在您所針對的平台上以您想要的方式呈現。一些測試可以透過使用 內建於 Dart 的單元測試框架 編寫的單元測試來處理。Dart 單元測試對於非 UI 測試非常有效;它在您的開發機器上執行,並且不依賴於 Flutter 應用程式的 GUI。

整合測試(也稱為端到端測試或 GUI 測試)比單元測試更進一步,因為整合測試嘗試透過按下按鈕、選擇項目和在鍵盤上輸入等方式模擬使用者與您的應用程式互動。這種測試是自動的,以避免讓人類做這種重複性的工作,因為坦白說,我們不擅長這種事情。我們最初避免人類互動的解決方案是一種編寫 Flutter 測試的特殊方式。這些測試從主機執行,就像 Dart 單元測試一樣,並驅動在真實或虛擬設備上運行的應用程式,就像一個人一樣。這些測試稱為 Flutter 驅動測試,因為您使用 flutter_driver 套件和 flutter drive 命令列來驅動應用程式的 GUI。

不幸的是,Flutter 驅動測試存在一些問題。一個問題是測試從開發機器執行並與設備上的應用程式通訊,這意味著測試不適合在像 Firebase Test Lab 這樣的設備池上執行。另一個問題是,為您的測試單獨使用一個程序會讓您很難檢查應用程式的狀態。您可以檢查輸出,但是您如何知道,例如,應用程式的內部狀態。最後,flutter_driver API 比它需要的要複雜,特別是在編寫程式碼以找到螢幕上適當的 Widget 來進行測試時。

因此,為了解決這些問題並繼續改進 Flutter 測試體驗,使其涵蓋越來越多目標,我們很高興宣布 integration_test Plugin 的 1.0 版,這是一種更簡單的方式來測試您的 Flutter 應用程式,並且也支援 Firebase Test Lab。

開始使用 integration_test

使用 integration_test Plugin 需要兩個步驟。首先,將 Plugin 添加到您的 pubspec.yaml 檔案中,作為開發相依,並使用 flutter pub get 將 plugin 拉到您的專案中:

1
2
3
4
5
6
7
# pubspec.yaml

dev_dependencies:
flutter_test:
sdk: flutter
integration_test: ^1.0.0

然後,在測試程式碼中使用 integration_test 套件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:my_app/main.dart' as app;

void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

group('end-to-end', () {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
app.main();
await tester.pumpAndSettle();

// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);

// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pumpAndSettle();

// Verify the counter increments by 1.
expect(find.text('1'), findsOneWidget);
});
});
}

請注意 integration_test 套件的匯入和對 IntegrationTestWidgetsFlutterBinding.ensureInitialized() 的呼叫,這將確保套件正確初始化。還要注意標準 WidgetTester 測試程式碼。這是在 flutter create 期間由預設的 Counter 應用程式範本生成的相同測試程式碼。

雖然 integration_test 使您的測試能夠以獨立的方式捆绑到您的應用程式中(這是像 Firebase Test Lab 這樣的設備池的要求),但它需要一些我們將在下面介紹的構建技巧。但是,在測試開發過程中,能夠透過命令列互動式執行您的測試非常方便,为此,您需要一個新的入口點:

1
2
3
4
5
6
import 'package:integration_test/integration_test.dart';

void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
integrationDriver();
}

integrationDriver 的呼叫是 integrationDriver Plugin 的便捷包裝函數,使您能夠使用 flutter drive 命令執行新的測試:

1
2
3
$ flutter drive 
--driver=test_driver/integration_test.dart
--target=test/widget_integration_test.dart

此命令會將您的應用程式部署到模擬器,執行您的測試,並向您顯示結果。

Flutter integration_test in action

此特定測試在 iOS 上執行,但 integration_test Plugin 也適用於 Android,只需更改 --device-id 選項,就像適用於其他平台一樣。此外,您也可以針對網頁和桌面目標執行整合測試,但此功能仍處於預發佈階段。

在 Firebase Test Lab 上執行

當您知道測試可以使用虛擬或實體硬體在本地執行後,就可以將應用程式在 Firebase Test Lab 提供的大量設備上執行。

Firebase Test Lab console

Firebase Test Lab 是一個基於雲端的應用程式測試基礎設施。透過一項操作,您可以在各種設備和設備配置上測試您的 Android 或 iOS 應用程式,並在 Firebase 主控台中查看結果 - 包括日誌、影片和螢幕截圖。integration_test Plugin 的一大進步是能夠在 Firebase Test Lab 上執行針對 Android 和 iOS 的 Flutter 應用程式,讓您能夠在發佈應用程式之前,在數百台設備上同時測試,以查找平台、外觀因素或設備特定的問題。

若要在 Firebase Test Lab 上執行測試,您需要進行一些配置,並使用 Gradle 命令為 Android 和 iOS 構建測試工具,這取決於您選擇的平台。有關這些詳細資訊,請查看 flutter.dev 上最新的整合測試文件

從 Flutter 驅動測試遷移

對於使用現有的 flutter_driver 測試的使用者,遷移到新的 API 並不困難。除了前面提到的適當初始化之外,您還需要遷移到新的 WidgetTester API。

flutter_driver API (left) vs. WidgetTesting API (right)

flutter_driver API(左邊顯示)和 WidgetTester API(右邊顯示)在概念上非常相似,但您可以看到許多細節是不同的。例如,您不是在 flutter_driver 上呼叫 waitFor 方法,而是在 WidgetTester 上呼叫 pumpAndSettle 方法。前者等待特定 Widget 出現,後者等待應用程式 UI 渲染階段穩定。獲得特定 Widget 後,您可以使用兩個 API 類似地對其進行操作,但您使用的是不同的物件。WidgetTest API 更符合您在 Dart 單元測試中看到的內容。如您所見,expect 方法用於確保 Widget 的內容符合您的預期。

有關如何將測試从 flutter_driver 遷移到 integration_test 和 WidgetTester 的詳細資訊,請查看 flutter.dev 上的遷移文件

原生 UI 測試

如果您有一個現有的 Android 或 iOS 應用程式,您使用 Add-to-App 為其添加 Flutter,那麼您可能已經為這些原生應用程式有了現有的整合測試,您想要利用這些測試。在這種情況下,將 Flutter 螢幕的測試添加到這些現有的測試中。對於 Android,如果您使用 Espresso 框架編寫測試,可以使用 espresso Plugin,它為 Espresso 對 Flutter Android 應用程式的測試提供了綁定。我們很快就會有類似的 Plugin 來支援使用 Earl Grey 建立的原生 iOS 測試。

總結

本公告介紹了使用適用於 Flutter 的新 integration_test Plugin 的整合測試的新基礎。不僅 API 更簡單,而且更一致,使用 integration_test 編寫的測試可以使用 Firebase Test Lab 在數百台不同的設備上執行。Flutter 團隊計劃透過將 flutter create 範本來使用 integration_test 作為預設值,更新測試輸出以支援使用 JUnit 格式的現有測試工具,添加在測試期間為黃金測試比較截取螢幕截圖的功能等等,來進一步發展這個新基礎。有關針對 Flutter 應用程式和 Plugin 的整合測試新建議的完整詳細資訊,請查看 flutter.dev 上的測試文件


Flutter 測試更新 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。