참고: https://flutter-ko.dev/docs/cookbook/testing
https://mangkyu.tistory.com/182
[TDD] 단위 테스트와 TDD(테스트 주도 개발) 프로그래밍 방법 소개 - (1/5)
이번에는 여러 개발 서적들 및 실무 경험 그리고 시행 착오 등을 겪으면서 얻은 테스트 주도 개발 방법에 대해 소개해보고자 합니다. 이번 포스팅에서는 먼저 단위 테스트와 중요성 그리고 단위
mangkyu.tistory.com
플러터에서는 어떤 테스트 방법이 있을까?
플러터에서는 크게 Unit test, Widget test, Integration test 로 나누어져 있습니다.
공통
먼저, test 라이브러리를 import해주기 위해
flutter/pubspec.yaml 에 해당 코드를 추가해야 합니다.
dev_dependencies:
test: <latest_version>
간단히 알아야 하는 test 라이브러리의 메소드는 다음과 같습니다.
- test
테스트에 대한 설명과 실제 테스트 코드를 적습니다.
시간 제한(timeout) 이나 테스트 환경 (브라우저, OS) 등도 적어줄 수 있습니다.
- expect
expect(실제값, 기대값)
테스트의 기대값과 실제값을 비교합니다.
- setup
테스트를 시작하기 전에 설정을 해줍니다.
테스트 단위 하나마다 실행됩니다. ( test() 함수 하나가 테스트 단위 하나에요. 한 파일에 여러 test() 가 있으면 여러번 실행됩니다. )
- setupAll
테스트 시작하기 전에 설정을 해줍니다.
파일 하나에 한번만 실행됩니다. (데이터 베이스 설정할 때 쓰기 좋겠죠)
- teardown
테스트를 마치고 할 작업을 정해줍니다.
테스트 단위 하나마다 실행됩니다.
- teardownAll()
테스트를 마치고 할 작업을 정해줍니다.
파일 하나에 한번만 실행됩니다.
참고: https://software-creator.tistory.com/21
더 참고하면 좋을 것들: https://pub.dev/packages/test
test할 것들은 반드시 test/ 폴더 안에 들어가야 합니다. 그리고 끝이 반드시 test로 끝나야 합니다.
예) counter_test.dart
플러터의 가장 상위 폴더에서 터미널로 테스트할 수 있습니다.
flutter test test/counter_test.dart
혹은, 해당 파일에 들어가 debug->start debugging으로 실행해볼 수 있습니다.
test는 반드시 main(){} 에서 실행되어야 합니다.
Unit test
Unit test는 메소드, 클래스같은 작은 단위를 테스트할 때 쓰입니다.
간단히 예제를 하나 만들었습니다.
void main() {
test('simple test', () {
expect(1 + 1, 2);
});
}
이렇게, 실제 값과 기대 값이 같다면 test가 통과되는 모습을 볼 수 있습니다!
보통, 계산기 같은 클래스를 유닛 테스트의 예제로 많이 사용합니다.
다음으로는 함수를 테스트해보겠습니다.
int add(int x, int y) {
return (x + y);
}
group('add func test', () {
test('test 1', () {
expect(add(20, 30), 50);
});
test('test 2', () {
expect(add(20, 30), 60);
});
});
예상대로 하나의 테스트는 성공하고, 하나의 테스트는 실패하는 것을 볼 수 있습니다.
Widget test
참조: https://docs.flutter.dev/cookbook/testing/widget/introduction
위젯 테스트는 위젯이 화면에 잘 보여지고, 사용자의 상호작용이 잘 동작하는지를 확인할 수 있는 테스트입니다.
플러터 공식 예제를 보며 차근차근 진행해보겠습니다.
먼저, flutter_test 라이브러리를 import 해줍니다.
import 'package:flutter_test/flutter_test.dart';
그 후, 간단한 위젯을 만들어줍니다.
class MyWidget extends StatelessWidget {
const MyWidget({
super.key,
required this.title,
required this.message,
});
final String title;
final String message;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
child: Text(message),
),
),
);
}
}
해당 위젯은 Appbar에 title, 가운데에 글씨로 message가 표현되네요.
그리고, 해당 위젯을 가짜로 만들어줍니다.
testWidgets('MyWidget has a title and message', (tester) async {
await tester.pumpWidget(const MyWidget(title: 'T', message: 'M'));
});
testWidgets 메소드는 테스트 환경에 위젯을 만들고 상호작용할 수 있게 해주는 메소드입니다.
pumpWidget은 전달받은 위젯을 빌드하고, 렌더링합니다.
pump 메소드 팁
플러터의 테스트환경에서는 상태가 갱신되었다고 해서 자동으로 화면을 리빌드하지 않으므로, 다시 빌드할 수 있는 여러가지 방법을 제공합니다.
tester.pump(Duration duration)
duration 은 프레임입니다. 해당 프레임이 지난 후에, 위젯 리빌드를 예약합니다.
tester.pumpAndSettle()
예약된 프레임이 없다면 정해진 시간마다 지속적으로 계속해서 pump method를 실행합니다.
그 후, finder를 만들어줍니다.
final titleFinder = find.text('T');
final messageFinder = find.text('M');
finder는 find 메소드로 만들 수 있으며, 해당 위젯이 화면에 잘 출력되는지 확인해줍니다.
우리는 Text 위젯을 확인할 것이기 때문에 find.text() 를 이용했습니다.
expect(titleFinder, findsOneWidget);
expect(messageFinder, findsOneWidget);
그리고 Matcher를 활용해 해당 위젯이 화면에 잘 나타나는지 검증합니다.
Matcher
- findsOneWidget
위젯 트리에 해당 위젯이 정확히 하나 있다는 것을 확인합니다.- findsNothing
위젯이 없는지 확인합니다.- findsWidgets
하나 혹은 여러 개의 위젯이 있는지 확인합니다.- findsNWidgets(int n)
n 개의 위젯이 존재하는지 확인합니다.- matchesGoldenFile
위젯의 렌더링이 특정 비트맵 이미지, 폰트와 같은지 확인합니다.
그 외에도 특정 key를 가진 위젯을 찾을 수 있고, 터치, 드래그, 입력 같은 동작도 테스트 해볼 수 있으니 참고 바랍니다.
Integration test
참조: https://docs.flutter.dev/cookbook/testing/integration/introduction
마지막으로, Integration test 입니다. app 전체가 어떻게 어우러져 동작하고 실제 기기에서 어느 정도의 성능을 내고 있는지 확인해 볼 수 있는 test입니다.
test_driver 이라는 라이브러리가 추가로 필요하고
꼭 테스트할 항목은 integration_test 라는 폴더 안에 넣어주어야 합니다.
'Flutter' 카테고리의 다른 글
Flutter Provider - 꿀팁 ? ~ ? 🎈 (1) | 2024.01.03 |
---|---|
Flutter 네이티브 연결 (1) | 2023.11.14 |
Flutter - Test 2편 (0) | 2023.11.10 |
Flutter - Unit Testing (1) | 2023.11.10 |
Flutter - ListView (0) | 2023.11.08 |