명세 기반 테스트 기법은 프로그램의 요구사항 자체에서 테스트를 도출하는 것으로,
개발자가 기능 개발을 마치고 테스트를 시작할 때 가장 먼저 접근하기 좋은 기법이다.
이번 장에서는 명세 기반 테스트 기법을 적용해 테스트 케이스를 작성하는 방법을 다룬다.
요구사항에서 테스트 케이스 뽑아내기
- 요구사항과 입출력에 대해 이해하기
- 무엇을 수행해야 하는지 확인
- 입력값 확인
- 출력값 확인
- 여러 입력값에 대해 프로그램이 수행하는 바를 탐색하기
- 직접 작성하지 않은 코드인 경우 더욱 필요한 단계이다.
- 테스트 가능한 입출력과 구획을 탐색하기
- 각 입력 매개변수의 가능한 케이스(=구획) 찾기
- 입력 매개변수들의 가능한 조합 찾기
- 출력값의 가능한 케이스 찾기 (전체 출력, 각 개별 출력 모두 확인하기!)
예를 들면, 문자열 배열을 출력하는 경우 배열이 null / empty / length==1 / length>1 인 경우와
배열의 각 개별 요소가 "" / length==1 / length>1 인 경우를 모두 고려해야 한다는 것이다.
- 경계 분석하기
- 경계 위에 있는 접점(on point)과 경계에 가장 가까운 거점(of point) 테스트
- 조건이 참인 내점(in point)과 조건이 거짓인 외점(out point) 테스트
- 테스트 케이스 고안하기
중요한 점은 테스트 케이스의 조합은 매우 많기 때문에 우리는 실용적인 테스트만을 골라야 한다는 점이다.- 각 범주에서 유의미한 구획만을 고른다.
- 구획별로 테스트 케이스를 도출한다.
- 테스트 케이스 자동화하기
- JUnit과 같은 툴을 이용해 테스트를 자동화한다.
- 모든 테스트를 한 메서드에 넣을지 / 어떤 단위별로 테스트를 묶을지 / 각 테스트마다 하나의 메서드를 사용할지는 상황에 맞게 결정하면 된다.
- 창의성과 경험을 발휘해서 테스트 스위트를 강화하기
- 특수문자(ex. 공백) 테스트 등
현업에서의 명세 테스트를 위한 팁
- 프로세스는 반복적으로 단계들 사이를 왔다 갔다 한다.
- 명세 테스트는 해당 기능의 비용에 비례하여 꼼꼼하게 수행한다.
- 구획과 경계를 명확히 구분지을 필요는 없다.
- 접점과 거점으로도 충분하지만 내점과 외점도 얼마든지 추가해도 좋다.
- 이해를 높이기 위해 입력을 변경해서 사용하자.
- 조합의 수가 폭발적으로 증가한다면 실용적이어야 한다.
- 무엇을 입력할지 모르겠다면 간단한 입력을 넣어보자.
- 관심 없는 입력에 대해 합리적인 값을 선택하자.
- 널과 예외 케이스는 의미가 있을 때만 사용하자.
- 테스트가 동일한 스켈레톤을 갖는 경우 매개변수화 테스트를 사용하자.
- 요구사항은 잘게 쪼갤 수 있다.
- 현업에서 클래스는 상태를 가지므로 이를 고려해야 한다.