做自(zì)由與創造的先行者

Flutter 測試應用(yòng)

Flutter開(kāi)發手冊

介紹

應用(yòng)的功能(néng)越多,手動測試的難度就越大(dà)。一套完整的自(zì)動化測試将幫助您确保您的應用(yòng)在發布之前正确執行,同時(shí)保留您的功能(néng)和(hé)錯誤修複速度。

有很(hěn)多種自(zì)動化測試。這(zhè)些(xiē)總結如下(xià):

單元測試:測試單一功能(néng)、方法或類。例如,被測單元的外(wài)部依賴性通常被模拟出來(lái),如package:mockito。 單元測試通常不會(huì)讀取/寫入磁盤、渲染到(dào)屏幕,也(yě)不會(huì)從(cóng)運行測試的進程外(wài)部接收用(yòng)戶操作(zuò)。單元測試的目标是在各種條件下(xià)驗證邏輯單元的正确性。

widget 測試:(在其它UI框架稱爲 組件測試) 測試的單個widget。測試widget涉及多個類,并且需要提供适當的widget生命周期上(shàng)下(xià)文(wén)的測試環境。 例如,它應該能(néng)夠接收和(hé)響應用(yòng)戶操作(zuò)和(hé)事(shì)件,執行布局并實例化子widget。widget測試因此比單元測試更全面。 然而,就像一個單元測試一樣,一個widget測試的環境被一個比完整的UI系統簡單得多的實現(xiàn)所取代。小(xiǎo)部件測試的目标是驗證小(xiǎo)部件的UI如預期的那樣的外(wài)觀和(hé)交互。

集成測試: 測試一個完整的應用(yòng)程序或應用(yòng)程序的很(hěn)大(dà)一部分。通常,集成測試可以在真實設備或OS仿真器上(shàng)運行,例如iOS Simulator或Android Emulator。 被測試的應用(yòng)程序通常與測試驅動程序代碼隔離,以避免結果偏差。集成測試的目标是驗證應用(yòng)程序作(zuò)爲一個整體正确運行,它所組成的所有widget如預期的那樣相互集成。 您還可以使用(yòng)集成測試來(lái)驗證應用(yòng)的性能(néng)。

單元測試

某些(xiē)Flutter庫,如dart:ui在獨立的Dart VM附帶的Dart SDK的中是不可用(yòng)。該flutter test命令允許您在本地Dart VM中運行測試,使用(yòng)無頭版(不會(huì)顯示UI)的Flutter引擎。 使用(yòng)這(zhè)個命令你(nǐ)可以運行任何測試,不管它是否依賴于Flutter的庫。

使用(yòng)package:test,編寫一個Flutter單元測試。編寫單元測試使用(yòng)的package:test文(wén)檔在這(zhè)裏。

例如:

将此文(wén)件添加到(dào) test/unit_test.dart:

import 'package:test/test.dart';

void main() {

test('my first unit test', () {

var answer = 42;

expect(answer, 42);

});

}

另外(wài),您必須将以下(xià)内容添加到(dào)您的pubspec.yaml:

dev_dependencies:

flutter_test:

sdk: flutter

即使你(nǐ)的測試本身沒有明(míng)确導入flutter_test,也(yě)需要這(zhè)樣做 ,因爲測試框架本身在後台也(yě)使用(yòng)了(le)它。

要運行測試,從(cóng)您的項目目錄(而不是從(cóng)test子目錄)運行 flutter test test/unit_test.dart

要運行所有測試,請(qǐng)從(cóng)項目目錄運行flutter test

Widget 測試

您以類似于單元測試的方式實現(xiàn)widget測試。要在測試中執行與widget的交互,請(qǐng)使用(yòng)Flutter提供的WidgetTester。 例如,您可以發送點擊和(hé)滾動手勢。您還可以使用(yòng)WidgetTester在widget樹中查找子widget、讀取文(wén)本、驗證widget屬性的值是否正确。

例子:

将此文(wén)件添加到(dào)test/widget_test.dart:

import 'package:flutter/material.dart';

import 'package:flutter_test/flutter_test.dart';

void main() {

testWidgets('my first widget test', (WidgetTester tester) async {

// You can use keys to locate the widget you need to test

var sliderKey = new UniqueKey();

var value = 0.0;

// Tells the tester to build a UI based on the widget tree passed to it

await tester.pumpWidget(

new StatefulBuilder(

builder: (BuildContext context, StateSetter setState) {

return new MaterialApp(

home: new Material(

child: new Center(

child: new Slider(

key: sliderKey,

value: value,

onChanged: (double newValue) {

setState(() {

value = newValue;

});

},

),

),

),

);

},

),

);

expect(value, equals(0.0));

// Taps on the widget found by key

await tester.tap(find.byKey(sliderKey));

// Verifies that the widget updated the value correctly

expect(value, equals(0.5));

});

}

運行 flutter test test/widget_test.dart.

查看(kàn)所有可用(yòng)于widget測試的package:flutter_test API

爲了(le)幫助調試widget測試,您可以使用(yòng)debugDumpApp() 函數來(lái)可視(shì)化測試的UI狀态, 或者隻是簡單的在您的首選運行時(shí)環境(例如模拟器或設備)中運行flutter run test/widget_test.dart以查看(kàn)您的測試運行。 在運行flutter run的測試的會(huì)話(huà)期間,您還可以交互式地點擊Flutter工(gōng)具的部分屏幕來(lái)打印建議(yì)的Finder。

集成測試

如果您熟悉Selenium/WebDriver(web),Espresso(Android)或UI Automation(iOS),那麽Flutter Driver就是Flutter與這(zhè)些(xiē)集成測試工(gōng)具的等價物。 此外(wài),Flutter Driver還提供API以記錄測試執行的操作(zuò)的性能(néng)跟蹤(又名時(shí)間軸)。

Flutter的Driver是:

一個命令行工(gōng)具 flutter drive

一個包 package:flutter_driver (API)

這(zhè)兩者允許你(nǐ):

爲集成測試創建指令化的應用(yòng)程序

寫一個測試

運行測試

添加flutter_driver依賴項

要使用(yòng)flutter_driver,您必須将以下(xià)塊添加到(dào)您的pubspec.yaml:

dev_dependencies:

flutter_driver:

sdk: flutter

創建指令化的Flutter應用(yòng)程序

一個指令化的應用(yòng)程序是一個Flutter應用(yòng)程序,它啓用(yòng)了(le)Flutter Driver 擴展。啓用(yòng)擴展請(qǐng)調用(yòng)enableFlutterDriverExtension()。

例:

假設你(nǐ)有一個入口點的應用(yòng)程序my_app/lib/main.dart。要創建它的指令化版本,請(qǐng)在my_app/test_driver/下(xià)創建一個Dart文(wén)件。 在您正在測試的功能(néng)之後命名它; 接下(xià)來(lái)定位到(dào)my_app/test_driver/user_list_scrolling.dart:

// 這(zhè)一行導入擴展

import 'package:flutter_driver/driver_extension.dart';

void main() {

// 啓用(yòng)擴展

enableFlutterDriverExtension();

// Call the `main()` of your app or call `runApp` with whatever widget

// you are interested in testing.

}

編寫集成測試

集成測試是一個簡單的package:test測試,它使用(yòng)Flutter Driver API告訴應用(yòng)程序執行什(shén)麽操作(zuò),然後驗證應用(yòng)程序是否執行了(le)此操作(zuò)。

例子:

爲了(le)有意思起見,我們也(yě)讓我們的測試記錄下(xià)性能(néng)跟蹤(performance timeline)。我們創建一個user_list_scrolling_test.dart測試文(wén)件位于my_app/test_driver/下(xià):

import 'dart:async';

// Imports the Flutter Driver API

import 'package:flutter_driver/flutter_driver.dart';

import 'package:test/test.dart';

void main() {

group('scrolling performance test', () {

FlutterDriver driver;

setUpAll(() async {

// 連接app

driver = await FlutterDriver.connect();

});

tearDownAll(() async {

if (driver != null) {

// 關閉連接

driver.close();

}

});

test('measure', () async {

// 記錄閉包中的performance timeline

Timeline timeline = await driver.traceAction(() async {

// Find the scrollable user list

SerializableFinder userList = find.byValueKey('user-list');

// Scroll down 5 times

for (int i = 0; i < 5; i++) {

// Scroll 300 pixels down, for 300 millis

await driver.scroll(

userList, 0.0, -300.0, new Duration(milliseconds: 300));

// Emulate a user's finger taking its time to go back to the original

// position before the next scroll

await new Future.delayed(new Duration(milliseconds: 500));

}

// Scroll up 5 times

for (int i = 0; i < 5; i++) {

await driver.scroll(

userList, 0.0, 300.0, new Duration(milliseconds: 300));

await new Future.delayed(new Duration(milliseconds: 500));

}

});

// The `timeline` object contains all the performance data recorded during

// the scrolling session. It can be digested into a handful of useful

// aggregate numbers, such as "average frame build time".

TimelineSummary summary = new TimelineSummary.summarize(timeline);

summary.writeSummaryToFile('stocks_scroll_perf', pretty: true);

summary.writeTimelineToFile('stocks_scroll_perf', pretty: true);

});

});

}

運行集成測試

要在Android設備上(shàng)運行測試,請(qǐng)通過USB将設備連接到(dào)計(jì)算(suàn)機并啓用(yòng)USB調試。然後運行以下(xià)命令:

flutter drive --target=my_app/test_driver/user_list_scrolling.dart

該命令将:

構建 --target 應用(yòng),并将其安裝在設備上(shàng)

啓動應用(yòng)

運行my_app/test_driver/下(xià)的user_list_scrolling_test.dart

您可能(néng)想知(zhī)道(dào)該命令如何找到(dào)正确的測試文(wén)件。flutter drive 命令使用(yòng)一種約定來(lái)查找與--target應用(yòng)程序在同一目錄中具有相同文(wén)件名但(dàn)是具有_test後綴的測試文(wén)件。

網站(zhàn)建設開(kāi)發|APP設計(jì)開(kāi)發|小(xiǎo)程序建設開(kāi)發
下(xià)一篇:Flutter 調試應用(yòng)
上(shàng)一篇:Flutter 使用(yòng)熱重載