dart-add-unit-test

dart-add-unit-test

熱門

使用 `package:test` 為函式、方法與類別撰寫並整理單元測試。適合在開發新邏輯或修復 Bug 時使用,確保程式碼正確無誤且防止發生回歸錯誤(regression)。

2792星標
164分支
更新於 2026/8/5
SKILL.md
唯讀
名稱
dart-add-unit-test
描述

使用 `package:test` 為函式、方法與類別撰寫並整理單元測試。適合在開發新邏輯或修復 Bug 時使用,確保程式碼正確無誤且防止發生回歸錯誤(regression)。

Dart 與 Flutter 應用程式測試

目錄

規劃測試檔案結構

妥善組織測試檔案,使其對齊 lib 目錄結構,以保持專案架構的可預測性。

  • 將所有測試程式碼放置於 Package 根目錄下的 test 目錄中。
  • 所有測試檔案名稱末尾皆需加上 _test.dart(例如 lib/src/utils.dart 的測試檔案應為 test/src/utils_test.dart)。
  • 若要撰寫整合測試,請放置於 Package 根目錄下的 integration_test 目錄中。

撰寫測試

使用 package:test 作為 Dart 應用程式的標準測試函式庫。

  • 匯入 package:test/test.dart(若為 Flutter 專案,則匯入 package:flutter_test/flutter_test.dart)。
  • 使用 group() 函式將相關測試分組,以提供共享的情境上下文。
  • 使用 test() 函式定義獨立的測試案例。
  • 搭配 Matcher(例如 equals()isTruethrowsA())使用 expect() 函式驗證執行結果。
  • 使用標準的 async/await 語法撰寫非同步測試,Test runner 會自動等待 Future 執行完成。
  • 使用 setUp()tearDown() 回調(callbacks)管理測試前後的環境設定與資源清理。
  • 若被測試的程式碼依賴依賴注入(Dependency Injection),可結合 package:mockitopackage:test 來產生 Mock 物件、設定預期情境並驗證互動行為。

執行測試

根據專案類型與測試檔案所在位置,選擇合適的 Test runner。

  • 若為純 Dart 專案,請使用 dart test 命令執行測試。
  • 若為 Flutter 專案,請使用 flutter test 命令執行測試。
  • 若要執行整合測試,由於預設 runner 會忽略該目錄,因此需明確指定路徑:dart test integration_testflutter test integration_test

測試實作工作流程

實作新的測試套件時,請遵循以下步驟流程。可以複製這份檢查清單來追蹤進度。

任務進度

  • [ ] 1. 在 test/ 目錄中建立測試檔案,並確認副檔名包含 _test.dart
  • [ ] 2. 匯入 package:test/test.dart 以及目標函式庫。
  • [ ] 3. 定義 main() 函式。
  • [ ] 4. 使用 setUp() 初始化共享資源或 Mock 物件。
  • [ ] 5. 使用 group() 依功能將 test() 案例分組撰寫。
  • [ ] 6. 使用相應的 CLI 命令執行測試套件。
  • [ ] 7. 回饋循環(Feedback Loop):執行測試 -> 檢視失敗的 Stack trace -> 修復實作程式碼或斷言(assertions)-> 重新執行直到全部通過。

範例

標準單元測試套件

展示測試分組、環境設定、同步與非同步測試的撰寫方式。

import 'package:test/test.dart';
import 'package:my_package/calculator.dart';

void main() {
  group('Calculator', () {
    late Calculator calc;

    setUp(() {
      calc = Calculator();
    });

    test('adds two numbers correctly', () {
      expect(calc.add(2, 3), equals(5));
    });

    test('handles asynchronous operations', () async {
      final result = await calc.fetchRemoteValue();
      expect(result, isNotNull);
      expect(result, greaterThan(0));
    });
  });
}

使用 Mockito 進行 Mock 測試

展示如何設定 Mock 物件以進行依賴注入測試。

import 'package:test/test.dart';
import 'package:mockito/mockito.dart';
import 'package:mockito/annotations.dart';
import 'package:my_package/api_client.dart';
import 'package:my_package/data_service.dart';

// 使用 build_runner 產生 Mock:dart run build_runner build
@GenerateNiceMocks([MockSpec<ApiClient>()])
import 'data_service_test.mocks.dart';

void main() {
  group('DataService', () {
    late MockApiClient mockApiClient;
    late DataService dataService;

    setUp(() {
      mockApiClient = MockApiClient();
      dataService = DataService(apiClient: mockApiClient);
    });

    test('returns parsed data on successful API call', () async {
      // 設定 Mock 物件的預期行為
      when(mockApiClient.get('/data')).thenAnswer((_) async => '{"id": 1}');

      // 執行被測試系統(System Under Test)
      final result = await dataService.fetchData();

      // 驗證結果與互動行為
      expect(result.id, equals(1));
      verify(mockApiClient.get('/data')).called(1);
    });
  });
}