Dart 및 Flutter 애플리케이션 테스트하기
목차
테스트 파일 구조화하기
예측 가능성을 유지하기 위해 lib 디렉토리 구조를 반영하여 테스트 파일을 구성하세요.
- 모든 테스트 코드는 패키지 루트의
test디렉토리 안에 배치하세요. - 모든 테스트 파일 이름 끝에
_test.dart를 추가하세요 (예:lib/src/utils.dart는test/src/utils_test.dart에서 테스트). - 통합 테스트를 작성하는 경우, 패키지 루트의
integration_test디렉토리에 배치하세요.
테스트 작성하기
Dart 애플리케이션의 표준 테스트 라이브러리로 package:test를 사용하세요.
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);
});
});
}