SKILL.md
readonlyread-only
name
dart-add-unit-test
description
使用 `package:test` 為函式、方法和類別編寫並組織單元測試。在建立新邏輯或修正錯誤時使用,以確保程式碼保持正確且無回歸。
測試 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來產生模擬物件、設定固定情境並驗證互動。
執行測試
根據專案類型和測試位置選擇適當的測試執行器。
- 如果是純 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()初始化共享資源或模擬物件。 - [ ] 5. 使用
group()按功能分組撰寫test()案例。 - [ ] 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('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 進行模擬
示範為依賴注入測試設定模擬物件。
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 產生模擬: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 {
// 設定模擬
when(mockApiClient.get('/data')).thenAnswer((_) async => '{"id": 1}');
// 執行受測系統
final result = await dataService.fetchData();
// 驗證結果與互動
expect(result.id, equals(1));
verify(mockApiClient.get('/data')).called(1);
});
});
}






