목차
1. 테스트 코드를 작성하는 이유
2. 테스트 코드 작성의 기본 원칙
3. 테스트 코드 잘 작성하는법
1. 테스트 코드를 작성하는 이유
1-1: 디버깅 비용 절감
- unit 테스트: 도메인 모델과 비즈니스 로직을 테스트, 작은 단위의 코드 및 알고리즘 테스트
- integration 테스트: 코드의 주요 흐름들을 통합적으로 테스트하며 주요 외부 의존성(ex. 데이터베이스)에 대해서 테스트
- e2e 테스트: 최종 사용자의 흐름에 대한 테스트이며 외부로부터의 요청부터 응답까지 기능이 잘 동작하는지에 대한 테스트
1-2: 코드 변경에 대한 불안감 해소
“버그를 고쳤는데 다른데서 또 터지네…”
위와 같은 상황이라면 회귀 버그를 겪고 있는 것.
회귀 버그
이전에 제대로 작동하던 소프트웨어 기능에 문제가 생기는 것을 가리킨다.
일반적으로 회귀 버그는 프로그램 변경 중 뜻하지 않게 발생한다.
-위키 백과
회귀 버그를 완전히 차단하고 예방할 수 있을까?
애플리케이션의 기능은 요소들이 상호작용으로 만들어지기 때문에 사실상 그건 불가능하다.
회귀 버그는 예방하는 것이 아니라 관리하고 대처해야된다.
다시 말해 우리는 회귀 테스트를 해야 한다.
테스트 코드는 그때 당시의 기능을 만들기 위해서만 필요한 코드가 아니다.
그 이후에
- 요구사항이 변경되어 기존 코드를 수정하거나
- 더 나은 코드를 위해 리팩토링을 하거나
서비스가 지속 가능하게 발전하기 위해 필요한 코드.
1-3: 더 나은 문서 자료
문서화를 하면서 나중에는 새로 만드는 것보다 기존 문서들을 유지 보수하는 것이 더 귀찮은 일이라고 생각할 수 있다.
하지만 테스트가 귀찮은 일이라고 생각했던 문서의 역할을 해줄 수 있다.
“문서화할 내용을 나와 가장 가까운 IDE, 코드에 배치하는 건 어떨까?”
아래와 같이 테스트를 작성할 때 가장 먼저 명세를 작성하면서 코드의 실제 동작을 기술함으로써 이 코드가 어떤 역할을 가졌는지 이해하는데 도와준다.
기존에 중복된 메일이 있는 경우 회원가입을 할 수 없습니다.
문서화 테스트는 기능과 코드를 이해하는 데 도움을 준다.
2. 테스트 코드 작성의 기본 원칙
첫째, 테스트 코드는 독립적이어야 한다.
각 테스트는 다른 테스트에 영향을 받지 않고 독립적으로 실행되어야 한다.
둘째, 테스트 코드는 반복 가능해야 한다.
동일한 입력에 대해 항상 동일한 결과를 반환해야 한다.
왜냐하면 테스트의 신뢰성을 높이기 위해서.
셋째, 테스트 코드는 명확하고 이해하기 쉬워야 한다.
테스트 코드는 코드의 동작을 검증하는 역할을 하기 때문에, 다른 개발자들이 쉽게 이해할 수 있어야 한다.
넷째, 테스트 코드는 빠르게 실행되어야 한다.
테스트가 느리면 개발 속도가 저하될 수 있기 때문에, 가능한 한 빠르게 실행되도록 작성해야 한다.
마지막으로, 테스트 코드는 지속적으로 유지보수되어야 한다.
코드가 변경될 때마다 테스트 코드도 함께 업데이트되어야 한다.
왜냐하면 테스트 코드가 코드의 최신 상태를 반영해야 하기 때문.
3. 테스트 코드 잘 작성하는 방법
3-1: DRY 보다는 DAMP
개발 원칙 중에는 DRY(Don’t Repeat Yourself) 라는 원칙이 있다.
중복 코드를 싫어해 중복 코드가 보이면 그것을 어떻게든 없애려고 하는 경향이 있는데
그렇다면 중복을 줄이기 전에 DAMP하게 테스트 코드를 작성하는 것을 고려해봐야한다.
DAMP 원칙은 Descriptive and Meaningful Phrases의 약자로 의미있고 설명적인 구문을 사용하라는 원칙이다.
Better:
- 테스트의 중복을 줄이는 것이 아니라 더 서술적이고 의미있게 작성하는 방향으로 리팩터링을 해야한다.
- 테스트는 서로 독립적이고 격리되어야 하기때문에 테스트 수정에 다른 테스트가 영향을 받지 않도록 해야한다.
- DAMP 원칙을 지키면서 중복을 줄이는 방안으로는 테스트 픽스쳐 함수나 클래스등을 사용할 수 있다.
3-2: 테스트는 구현이 아닌 결과를 검증하도록 한다.
어떻게 라는 내부 구현 검증보다는 무엇을 이라는 결과 검증에 집중하여 테스트 코드를 작성해야 합니다.
Better:
- 테스트 코드는 내부 구현이 아닌 실행 결과에 집중해야 한다.
- 의미있는 테스트, 검증을 하자.
3-3: 읽기 좋은 테스트를 작성하라.
테스트 코드는 메인, 제품 코드을 위한 코드라 할지라도 우리의 책임이고 관리 대상이다.
테스트 코드도 가독성이 좋아야하고 불명확한 테스트 코드는 읽는 행위도 유지보수 하는 행위도 어렵게 만든다.
좋은 테스트 코드는 읽는 사람 입장에서 이 테스트를 이해하는데 필요한 모든 정보를,
테스트 케이스 본문에 담고 있는 테스트를 말한다.
그리고 이와 동시에 관련없는 정보는 담지 말아야 한다.
또한 테스트 코드의 가독성을 높이는 방법중 하나는 테스트의 구조를 잘 잡는 것인데,
테스트의 구조는 준비, 실행, 검증 3개의 구절로 나뉘어질 수 있다.
각각의 구절을 AAA 패턴(Arrange-Act-Assert 주석으로 구분)이나 GWT 패턴(given-when-then 행위 주석으로 구분)으로 구간을 나누어 작성하는것이 좋다.
(물론 구조를 위한 주석을 사용하지 않고 각 영역에 맞게 테스트 함수 내 코드를 구분해서 작성할수 있다면 그 방안을 사용하는 것이 좋다.)
그리고 만약 테스트안에 너무 많은 양의 코드가 존재한다면 이부분을 좀더 코드 재사용의 목적으로 모듈화(테스트 팩토리, 빌더, 핼퍼 메소드)해두면 쉽게 읽힐수 있게된다.
Better:
- 테스트 코드도 코드이므로 읽기 쉬운 코드를 작성하자.
- 무엇이 잘못되어 실패했는지, 어떻게 고쳐야 하는지를 파악하기 어려운 테스트를 작성하지 말자.
- 테스트 구조를 나누는 패턴과 테스트 코드를 모듈화하는 방법을 통해 테스트 코드를 읽기 쉽게 작성하자.
3-4: 테스트 명세에 비즈니스 행위를 담도록 한다.
마지막으로 테스트 명을 작성할 때도 유의할 점이 있다.
테스트명은 퍼블릭 인터페이스와 마찬가지로 명확하게 의도가 들어나도록 작성이 되어야한다.
좋은 테스트 코드는 우리가 작성한 코드의 문서이기에 명확한 의도가 당긴 명세가 되어야 한다.
여기서 명확하게 의도가 드러나는 이름은 개발자의 용어가 아닌 비즈니스 행위를 담은 비개발자가 읽을수 있게 설명되어야 한다.
Bad:
it('관리자를 생성한후 관리자 정보를 확인한다.')
Better:
it('관리자 정보로 가입한다')
이렇게 잘 작성된 이름은 다음과 같은 효과를 가지고 온다.
- 테스트 코드와 실행 로그를 확인하지 않아도, 동작을 유추할 수 있으며, 요구사항이 빠르게 공유가 될수 있다.
- 영향 범위를 빠르게 파악할 수 있으며 유추를 통하여 빠른 복구를 할 수 있다.
마무리
테스트 코드는 “지속 가능한 서비스, 프로젝트”를 위해 필수적인 요소중 하나.
'박졔삐한테 남겨놓는 글' 카테고리의 다른 글
10/10 세션 참고 블로그 글 (1) | 2024.10.10 |
---|---|
코딩테스트 사이트 (0) | 2024.09.25 |
https://www.baeldung.com/java-streams (0) | 2024.09.13 |