테스트의 가치(자가 테스트, 자동화 테스트)
: 직관만으로 테스트의 가치를 체감하긴 어렵다. 그러나, 컴파일때마다 테스트하는 것을 습관화하면 마지막 테스트 이후 현재 변경 부분에 대한 버그임을 명확하게 알 수 있고 결국 생산성이 향상된다.
- 핵심은 가장 작은 단위인 유닛 테스트이다.
- 아키텍처 평가 기준으로 Testability(테스트 용이성)를 활용하는 사례도 많다고 한다. 테스트하기 쉽게 만들수록 테스트를 잘 작성할 수 있게 되고, 이는 생산성과 직결되는 문제이기 때문인 것 같다.
TDD란? (Test driven development)
- 테스트 - 코딩 - 리팩터링을 한 cycle로 개발하는 개발 방법.
- 처음에는 테스트를 모두 실패한다. 만들어놓은 테스트를 기반으로 코딩을 하고, 모든 테스트가 통과하는 시점이 개발이 완료되는 시점이다.
테스트 작성
- BDD의 given - when - then 패턴을 적극 활용하면 좋다. setup - exercise - verify 혹은 arrange - act - assert 라는 표현도 있다.
- 유닛 테스트 하나당 검증 하나정도로 작성하면 장점이 있다. 만약 한 유닛 테스트에서 5~6개 검증이 있다면 앞쪽 검증을 통과 못하면 뒷쪽 검증은 실행조차 못한다. 테스트 하나당 검증 하나로 작성하면 한번에 모든 실패 원인을 파악하기 편하다.
- Edge case를 생각해보고 그 부분을 집중적으로 테스트한다. 사실 이러한 케이스는 어떤 메서드 혹은 클래스의 겉보기 동작이 아니기 때문에 리팩터링 후에 edge case에 대한 동작이 변하는지는 크게 신경쓰지 않아도 된다고 한다.
테스트 범위
- 단순히 커버리지를 올리겠다고 Getter, Setter나 UI, 영속성, 외부와의 통신부분까지 테스트할 필요는 없다. 핵심 비즈니스로직, 가장 우려가 되는 부분 등을 중점적으로 작성한다.
- 커버리지는 테스트가 되지 않은 영역을 찾는데 도움이 되고, 테스트 품질과는 크게 상관 없다.
- 완벽하게가 아니라 불완전하더라도 일단 핵심적인 부분만이라도 테스트하는 것이 훨씬 생산성 측면에서 이득이다.
Fixture
: 테스트에 필요한 객체나 데이터
- 각 유닛테스트끼리 상호작용하게 하는 공유 fixture를 작성하면 안된다. 이렇게 되면 테스트의 순서에 따라 결과가 달라지는 경우가 있다.
- 만약 공유 fixture가 필요한 상황이라면 immutable하게 만들거나 주의를 기울여서 fixture자체를 변경하지 않아야한다.
Reference)
리팩터링 2판