Dev
테스트 코드 필요성과 종류
foxlee
2022. 3. 5. 12:36
* TDD와 테스트 코드 작성은 다르다. TDD는 방법론일뿐!
테스트 코드의 필요성
- 작성한 코드를 하나하나 작동시켜 검증하지 않고 테스트 코드를 실행하여 동작을 검증함
- 테스트 코드가 없다면 하나하나 다 검증해야되고, 시간단축 및 테스트 코드를 활용하여 실수를 최소화 할 수 있음 -> 단점: 요구사항이 변경되면 이에 따라 수정이 필요함
- 기능 추가에 유연하게 대처가능함 -> 기능 추가로 다른 코드에 영향을 끼치는 지 파악해야 하는데 테스트 코드를 통해 확인할 수 있음
- 잘 짠 테스트 코드는 코드의 문서 역할도 가능함
- 정상 작동/흐름, 예상되는 예외상황 등
- TDD: 테스트 코드 작성 -> 기능 개발 -> 리팩토링 과정
- 유지 보수의 편의성, 가독성, 안정성, 코드 전체 품질 향상 가능
- 외부환경을 분리해 두고 핵심로직을 먼저 개발할 수 있음
테스크 코드 작성시 참고
- Fast - 특히 단위테스트는 가능한 빠르게 실행되어야 함
- Independent - 객체 상태, 메소드, 이전 테스트 상태 등에 의존. 어떤 순서로 실행해도 성공
- Repeatable - 반복 가능해야함
- Self-Validating - 자체 검증 가능해야함 - Assert
- AAA 패턴
- Arrange(준비) : 테스트를 실행하기 전에 필요한 것들을 준비 => 객체를 생성하거나, Mock 객체를 만들거나, 테스트 전에 호출되어야 할 API들을 호출 등
- Act(실행) : 테스트 코드 실행(메서드 실행 등)
- Assert(단언) : 실행한 코드가 예상한대로 동작했는지 확인 => assertTrue(), assertThat() 등의 코드들이 여기에 해당
- Red - Green - Yellow
- Red - 테스트 코드 작성(실제 기능이 없기 때문에 테스트 실패)
- Green - 기능 개발 - 테스트 성공
- Yellow - 리팩토링
유닛 테스트, 통합 테스트, 종단간(E2E) 테스트
- 유닛 테스트 : 코드가 제대로 작동하는지 확인하기 위해 애플리케이션의 개별 모듈을 독립적으로 테스트(종속성과의 상호 작용없이)하는 것
- 통합 테스트 : 다른 모듈이 그룹으로 결합될 때 잘 작동하는지 확인하는 것
유닛 테스트의 특징
- 가장 작은 단위의 테스트이며, 보통 메서드, 클래스 레벨로, A라는 함수가 실행되면 B라는 결과가 나온다 정도로 테스트
- 하나의 메서드들이 잘 동작한다는 것은 보장할 수 있지만, 그들이 결합되었을 때도 잘 작동한다는 것은 보장할 수 없음
E2E 테스트의 특징
- 해당 시스템과 해당 시스템을 구축하고 배포하는 프로세스를 모두 시험하는 것
- 내부 기능들까지(클래스의 메서드) 테스트 할 필요는 없음(이는 단위테스트의 영역)
- 테스트를 만들기가 힘들고, 만든 테스트를 신뢰하기도 어려움
통합 테스트의 특징
- 모듈을 통합하는 과정에서 모듈 간 호환성의 문제를 찾아내기 위해 수행되는 테스트
- 유닛 테스트는 다른 컴포넌트들과 독립적인 반면 통합 테스트는 그렇지 않음
- Unit test와 달리 개발자가 변경할 수 없는 부분 (ex. 외부 라이브러리, db)까지 묶어서 검증할 때 사용되는 테스트
- 예를 들면, 유닛 테스트에서 데이터베이스에 접근하는 코드는 실제 데이터 베이스와 통신하는 것은 아니지만, 통합 테스트는 실제 통신해야 함
- Unit을 넘어서 각기 다른 시스템이 잘 상호작용 하는지 (db 연동 등)를 확인하는 작업이기 때문에, Unit test code를 작성할 때보다 더욱 복잡, 더 많은 코드를 테스트하기 때문에 에러 검출이 명확하지는 않다. 그래서 실제로는 Unit test에 더욱 초점을 두는 것이 좋다.