> For the complete documentation index, see [llms.txt](https://woobeens-organization.gitbook.io/megaptera_fe/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://woobeens-organization.gitbook.io/megaptera_fe/frontend-survival/week5/tdd.md).

# 1. TDD

> TDD 주의사항\
> 테스트 코드를 작성한다고 TDD가 아닌 TDD Cycle에 따라 테스트 코드 작성, 로직 구현, 리팩터링을 순환하는 과정을 엄격하게 지켜 개발해야 TDD라 할 수 있다.

## Keyword

* TDD란
* Jest
* Describe - Context - It 패턴
* 단위 테스트란

***

## 1. TDD란?

테스트 코드를 먼저 작성하는 방식, 구현보다 **인터페이스**와 **스펙**을 먼저 정의하여 개발을 진행하는 방식이다.

### 인터페이스

테스트하려는 대상(모듈, 함수, 클래스, 시스템 등)과 상호작용하기 위한 방법과 규칙을 정의

* 입력값 및 출력값 정의
* 함수 호출 방법
* 예외 처리 등

### 스펙

테스트 대상이 어떻게 동작해야 하는지에 대한 기대되는 동작

### TDD Cycle

1. Red → 실패하는 테스트 코드를 작성. 인터페이스와 스펙에 집중한다.
2. Green → 재빨리 테스트를 통과시킨다. 올바른 방법이 아니어도 괜찮다.
3. Refactor → 리팩터링을 통해 코드를 올바르게 만든다. TDD에서 가장 중요한 부분이지만, 간과될 때가 많다.

**`Red 단계`**

실패하는 코드를 빠르게 작성하기 위해, 작은 단위, 단계를 찾는다. 이 과정에서 알게된 것, 배운 것에 대한 피드백을 얻는 게 어렵지만 중요하다. Green단계의 통과하는 테스트 코드 작성이 어렵다면 이 단계에서 더 작은, 더 쉬운 문제를 정의한다.

**`Refactor 단계`**

의도를 드러내고 중복을 찾아 제거하는 연습을 해야한다. 테스트 케이스 정의 방법

***

## 2. Jest

Facebook에서 만든 JS, TS 테스트 프레임워크, React Testing libarary와 함께 테스트 러너로서 사용한다.

1. test 함수로 개별 테스트를 나열
2. BDD(행위 주도 개발) 스타일로 주체(대상) - 행위 중심으로 테스트를 조직

**`개별 테스트`**

```typescript
function add(x: number, y: number): number {
    return 1 + 2;
}

test('add', () => {
  expect(add(1, 2)).toBe(3);
});
```

**`BDD 스타일`**

describe - it (주체 - 행위) 중심으로 테스트를 조직화하는 방식 **`~는 ~이다 or ~한다.`**

> 주의❗️\
> 행위를 명시할 때 **`~된다`** 같은 수동형 표현은 적합하지 않다.

```typescript
function add(x: number, y: number): number {
    return 1 + 2;
}

describe('add', () => {
  it('returns sum of two numbers', () => {
    expect(add(1, 2)).toBe(3);
  });
});
```

***

## 3. Describe - Context - It 패턴

테스트 스크립트를 구성하는데 도움이 되는 테스트 코드 구성 패턴

* Describe - 설명할 테스트 대상을 명시한다.
* Context - 테스트 대상이 놓인 상황을 설명한다.
* It - 테스트 대상의 행동을 설명한다.

**`한국어로 테스트 스크립트 구성하기`**

* Describe - 테스트 대상을 명사로 작성한다. **`~는, ~(이)가`**
* Context는 - **`~인 경우, ~할 때, 만약 ~ 하다면`** 과 같이 상황 또는 조건을 기술한다.
* it - 명사로 작성한 테스트 대상의 행동을 작성한다.
  * 테스트 대상의 행동은 **`~이다, ~한다, ~를 갖는다`** 가 적절한다.
  * **`~된다`** 같은 수동형 표현은 좋지 않다.

```typescript
describe('add', () => {
  context('인자가 없을 경우', () => {
    it('0을 반환한다', () => {
    expect(add()).toBe(0);
    });
  });

  context('인자가 하나일 경우', () => {
    it('인자와 같은값을 반환한다', () => {
    expect(add(1)).toBe(1);
    });
  })

  context('인자가 두개일 경우', () => {
    it('두 수를 더한 값을 반환한다', () => {
    expect(add(1, 2)).toBe(3);
    });
  })
});
```

***

## 4. 단위 테스트란?

단위 테스트(Unit Test)는 컴퓨터 프로그래밍에서 특정 모듈이 의도된 대로 정확히 동작하는지 검증하는 절차다. 즉, 모든 함수와 메소드에 테스트 케이스를 작성하는 절차를 말한다.

**`단위 테스트의 목적`**

1. 코드가 의도한 대로 동작하는지 검증
2. 버그를 조기에 감지해 신속한 문제 해결
3. 코드 변경으로 인한 사이드 이펙트 예방
4. 요구사항 변경, 리팩토링 시 유연하고 안정적인 대응 가능
