> For the complete documentation index, see [llms.txt](https://taewoongs-organization.gitbook.io/jtwjs-dev-wiki/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://taewoongs-organization.gitbook.io/jtwjs-dev-wiki/dev_note/testing/undefined.md).

# 단위 테스트의 두 분파

## 단위 테스트의 정의

* 작은 코드 조각(단위)을 검증
* 빠르게 수행
* 격리된 방식으로 처리하는 자동화된 테스트

단위 테스트 정의 중 **격리된 방식**에 대한 논쟁으로 두 개의 단위테스트 분파로 나뉘었다.

## 고전파 vs 런던파

* **고전파**: 모든 사람이 단위 테스트와 TDD에 원론적으로 접근하는 방식이라 '**고전**'이라 칭함
* **런던파**: 런던의 프로그래밍 커뮤니티에서 시작됨
  * **목 추종자(mockist)**&#xB85C; 불리기도 함,  그만큼 목(mock)을 많이 활용한다는 말이겠지

단위 테스트의 정의에서 격리문제를 어떻게 다루는지의 의견차이는  '**단위'가 무엇을 의미하는지**에 대한 관점과 **테스트 대상 간 의존성 처리 방식**에 영향을 미친다.

### 고전파(Classical school)

**단위 테스트를 격리**해서 실행해야 한다고 보는 입장

단위 테스트를 격리한다는 것은 테스트간 공유되는 의존성을 격리하는 것을 의미한다.(즉, 공유 의존성만 목(mock)으로 대체)

테스트 코드의 단위를 검증하는 것이 아닌 **동작 단위**, 즉 문제 영역에서 의미가 있는것을 검증해야 한다.

동작 단위를 구현하는데 필요한 모듈이 몇개인지는 상관없다.

#### 고전파 방식의 TDD 단점 이자 장점

오작동하는 다른 모듈을 참조하는 테스트를 할 때 실패할 수도 있다. \
즉, **하나의 버그가 전체 시스템에 걸쳐 테스트 실패를 야기하는 파급효과를 가져온다.**\
결국 문제의 원인을 찾기 더 어려워진다.

이는 테스트를 정기적으로(소스 코드가 변경될 때 마다) 실행하면 버그의 원인을 알아낼 수 있다.\
실패한 테스트를 모두 볼 필요는 없다. 버그가 생긴 코드 한 곳만 고치면 다른것들도 자동으로 고쳐진다.

\
오히려 이렇게 **계단식으로 실패하는 것은 가치가 있다.** \
하나의 코드 조각이 여러 개의 테스트에서 실패를 일으킨다면, 해당 코드 조각은 **전체 시스템에서 매우 중요한 역할을 하고 있을 가능성이 높다는것을 의미**한다. \
따라서 해당 코드 조각을 수정할 때는 전체 시스템에 큰 영향을 미치지 않도록 주의해서 작업하라는 유용한 정보가 된다.

{% hint style="info" %}
**응집도 높은 동작 단위 테스트**

테스트는 해결하는 데 도움이 되는 문제에 대한 이야기를 들려줘야하며,  일반 사람들이 볼 때에도 **응집도**가 높고 의미가 있어야 한다.

**응집도가 높은 테스트**: 우리집 강아지를 부르면, 바로 나에게 온다.

**응집도가 낮은 테스트**: 우리집 강아지를 부르면 먼저 왼쪽 앞다리를 움직이고, 이어서 오른쪽 앞다리를 움직이고....

실제 동작 대신 코드 단위를 목표로 테스트할 때 응집도가 낮은 테스트가 되기 쉽다.
{% endhint %}

### 런던파(London school)

**테스트 대상인 코드 조각을 격리**해야한다고 보는 입장

불변 의존성을 제외한 모든 의존성 있는 코드는 목(mock)으로 대체한다.&#x20;

#### 런던파 방식의 TDD 장점

* 테스트가 실패하면 코드베이스의 어느 부분이 고장 났는지 확실히 알 수 있다.

#### 런던파 방식의 TDD 단점

* 테스트 대상의 초점이 동작 단위가 아닌 코드 단위이기 때문에 개별 테스트 수도 많아지고 테스트 목적이 뚜렷해지지 않는다.
* 목(mock)을 사용함으로써 코드 설계상 문제가 되는 코드베이스를 숨긴다.
* 목(mock) 객체를 많이 사용하므로 테스트 코드가 복잡해지고 유지보수하기 어려워진다.

## 의존성 종류

* **공유 의존성**: 테스트 간 서로 공유되고 서로의 결과에 영향을 미칠 수 있는 수단을 제공하는 의존성
  * **휘발성 의존성**: 런타임 환경의 설정 및 구성을 요구(DB) or 비결정적인 동작을 포함(난수 생성기 처럼 호출마다 다른 결과를 제공하는 것)
* **비공개 의존성**: 공유하지 않는 의존성
* **프로세스 외부 의존성**: 애플리케이션 실행 프로세스 외부에서 실행되는 의존성

ex) 테스트 결과에 서로 영향을 주는 공유 의존성이면서 프로세스 외부 의존성 -> DataBase
