테스트 공부
앱을 코딩할 때 가장 먼저 무엇을 할까요?
테스트합니다! 그리고 제대로 작동하는지 여부를 확인합니다! 버그를 발견하면 수정하고 계속 코딩을 진행하겠죠?
이것이 바로 테스트이지만, 이것이 유일한 방법은 아닙니다!
테스트에는 두 가지 종류가 있습니다!
수동 테스트는 프로그래밍 지식 등이 필요하지 않습니다. 테스터는 내부에서 어떤 알고리즘이 실행되는지 모른 채 손으로 앱을 깨뜨리기만 하면 됩니다! 그래서 블랙박스 테스트라고 부릅니다! 새로운 기능을 추가하는 과정에서 다른 부분에서 예상치 못한 동작이 발생할 수 있고, 테스터의 실력이 부족할 수 있기 때문에(결국 우리도 사람이니까요) 신뢰도가 높지는 않습니다.
반면에 자동화된 테스트는 모든 시나리오에서 앱을 테스트하는 방법을 컴파일러에 알려주고 앱이 제대로 작동하는지 테스트하도록 하기 때문에 프로그래밍 언어가 필요합니다! 그렇기 때문에 수동 테스트보다 더 안정적입니다! 또한 컴파일러가 새로운 기능을 추가하는 동안 기존 기능도 모두 검증하는 누적 방식이기 때문에 매우 안정적입니다. 모든 변경 사항에 대해 앱 전체가 처음부터 끝까지 테스트됩니다! 이를 통해 현재 개발이 기존 기능을 손상시키지 않도록 할 수 있습니다.
이제 자동화된 테스트의 장단점을 살펴보겠습니다!
(Dart의 널 및 타입 안전 시스템 덕분에 이러한 변수는 필요하지 않습니다! 동적 및 널 가능 변수를 사용하지 않는 한 말입니다).
단일클래스 또는 단일메서드/함수를 테스트하여 정의된 조건에서 논리 단위를 검증하는 경우(메서드를 실행하고 예상대로 작동할것으로 예상)
단일 UI 위젯과 그 동작을 테스트하려면(버튼을 클릭하고 예상대로 작동할것으로 예상)
골든 테스트는 기본적으로 위젯 테스트이지만, 생성된 "골든" 이미지와 위젯이 동일한지 확인하는 테스트입니다.
사용자 관점에서 앱의 많은 부분을 테스트하는경우(예 : 텍스트 필드를 채우고 로그인 버튼을 클릭한 후 홈페이지 라우팅 예상 등)
전체 경험을 테스트합니다.
// 어노테이션을 사용하여 전역 규칙을 정의할 수 있습니다!
// 정말 다양한 플랫폼 옵션이 있습니다!
// vm, 크롬, 파이어폭스, 사파리, 노드, 다트-vm, 브라우저, js, 맥-OS, 리눅스, 안드로이드, iOS...js, mac-os, linux, android, ios...
(['browser', 'android'])
('ios')
('currently failing (see issue 1234)')
(Duration(seconds: 45))
({'windows': Timeout.factor(2)})
void main() {
late HttpServer server;
// 테스트가 시작되기 직전에 초기화
setUp(() async {
server = await HttpServer.bind('localhost', 0);
});
// 테스트가 끝나기 전에 닫기
tearDown(() async {
await server.close(force: true);
server = null;
});
// 테스트 생성
test('description', () {
// write your test here
});
// 테스트 그룹핑
group(
'description',
() {
test('test1', () {});
test('test2', () {});
test('test3', () {});
},
skip: 'reason',
);
// 테스트별 규칙도 정의할 수 있습니다
test(
'description', () {},
// 특정 테스트에 대한 특정 규칙을 정의할 수 있습니다.
tags: 'chrome', // or ['chrome', 'firefox'],
skip: 'reason', // skips the test
timeout: const Timeout.factor(2), // 시간을 2배 느리게하기
retry: 3, // 테스트를 3번 실행하여 정상인지 확인
testOn: 'browser && !chrome', // Chrome을 제외한 모든 브라우저
// 플랫폼별 규칙!
onPlatform: {
'windows': const Timeout.factor(2),
'browser': [const Skip('add browser support')],
},
);
// 그리고 네, 어떤 결과든 기대할 수 있습니다!
// 매처 패키지 덕분에 결과를 일치시킬 수 있는 다양한 방법이 있습니다!
expect(text.trim(), equals('foo')); // sync
expect('foo,bar,baz', allOf([contains('foo'), isNot(startsWith('bar')), endsWith('baz')])); // sync
expect(await Future.value(10), equals(10)); // async
expectLater(actual, matcher); // async
expect(Future.value(10), completion(equals(10))); // async
expect(Future.error('oh no'), throwsA(equals('oh no'))); // on error
expect(Future.error(StateError('bad state')), throwsStateError); // on error
expect(() => int.parse('X'), throwsFormatException); // on error
expect(stream, emitsInOrder(['ready.', emitsAnyOf(['succeeded', 'failed']), emitsDone])); // stream
}
BDD Example
Feature: Counter
Scenario: Increase and decrease the value of the counter
Given
Counter's initial value is 0
And increase and decrease buttons are available
When User click on the increase button.
Then the counter's value should be 1.
아무도 테스트를 작성하라고 말하지 않지만 테스트는 사람의 자질을 보여줍니다! - 지혜로운 사람