Community寫作與編輯github.com

photoeven2-netizen/astronusa

為函式、方法和類別編寫並組織單元測試,使用 `package:test`。在建立新邏輯或修復錯誤時使用,確保程式碼保持正確且無回歸問題。

astronusa 是什麼?

此技能提供了一套結構化的指南,用於在 Dart 和 Flutter 專案中編寫和組織單元測試,使用業界標準的 `package:test` 函式庫。其主要用途是協助開發者建立一致的測試規範,確保在新增功能或修復錯誤時,程式碼的正確性不受影響,並防止回歸錯誤。技能支援純 Dart 專案(使用 `dart test`)和 Flutter 專案(使用 `flutter test`),並涵蓋整合測試的執行方式。工作流程包含從建立測試檔案、匯入套件、設定 mock 物件、撰寫測試案例、到執行測試並根據反饋迴圈進行除錯的完整步驟。此外,還提供了使用 `package:mockito` 進行依賴注入測試的詳細範例,讓開發者能輕鬆模擬外部服務並驗證互動行為。

相容平台~Claude Code~Codex CLI~Cursor✓Gemini CLI
npx skills add https://github.com/photoeven2-netizen/astronusa/tree/HEAD/.agents/skills/dart-add-unit-test

Installed? Explore more 寫作與編輯 skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

測試 Dart 和 Flutter 應用程式

目錄

組織測試檔案

將測試檔案依照 lib 目錄結構進行組織,以保持可預測性。

  • 將所有測試程式碼放置在套件根目錄下的 test 目錄中。
  • 在測試檔案名稱的結尾加上 _test.dart(例如:lib/src/utils.dart 應在 test/src/utils_test.dart 中進行測試)。
  • 如果要撰寫整合測試,請將它們放置在套件根目錄下的 integration_test 目錄中。

撰寫測試

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

  • 匯入 package:test/test.dart(若為 Flutter 則匯入 package:flutter_test/flutter_test.dart)。
  • 使用 group() 函式將相關測試分組,以提供共用上下文。
  • 使用 test() 函式定義個別的測試案例。
  • 使用 expect() 函式搭配匹配器(例如 equals()、isTrue、throwsA())驗證結果。
  • 使用標準的 async/await 語法撰寫非同步測試。測試執行器會自動等待 Future 完成。
  • 使用 setUp() 和 tearDown() 回呼管理測試的設定與清理。
  • 若測試的程式碼依賴依賴注入,請使用 package:mockito 搭配 package:test 產生 mock 物件、配置固定情境,並驗證互動行為。

執行測試

根據專案類型和測試位置選擇適當的測試執行器。

  • 如果是純 Dart 專案,使用 dart test 指令執行測試。
  • 如果是 Flutter 專案,使用 flutter test 指令執行測試。
  • 如果要執行整合測試,請明確指定目錄路徑,因為預設執行器會忽略它:dart test integration_test 或 flutter test integration_test。

測試實作工作流程

在實作新的測試套件時,請遵循以下順序工作流程。複製核對清單以追蹤您的進度。

任務進度

  • 1. 在 test/ 目錄中建立測試檔案,確保使用 _test.dart 後綴。
  • 2. 匯入 package:test/test.dart 和目標函式庫。
  • 3. 定義 main() 函式。
  • 4. 使用 setUp() 初始化共用資源或 mock。
  • 5. 使用 test() 撰寫按功能分組的測試案例,並搭配 group()。
  • 6. 使用適當的 CLI 指令執行測試套件。
  • 7. 反饋迴圈:執行測試 → 檢視堆疊追蹤以找出失敗原因 → 修正實作或斷言 → 重新執行直到通過。

範例

標準單元測試套件

示範分組、設定、同步和非同步測試。

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

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

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

    test('正確地將兩個數字相加', () {
      expect(calc.add(2, 3), equals(5));
    });

    test('處理非同步操作', () 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('在 API 呼叫成功時回傳解析後的資料', () async {
      // 配置 mock
      when(mockApiClient.get('/data')).thenAnswer((_) async => '{"id": 1}');

      // 執行受測系統
      final result = await dataService.fetchData();

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

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

相關技能