Skip to content

Commit

Permalink
docs: 📝 update post
Browse files Browse the repository at this point in the history
  • Loading branch information
nyj001012 committed Nov 14, 2024
1 parent 998e015 commit b61b45b
Showing 1 changed file with 56 additions and 1 deletion.
57 changes: 56 additions & 1 deletion _posts/web/2024-03-22-how_to_test.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,66 @@ tag:
- test
toc: true
toc_sticky: true
last_modified_at: 2024-03-22T00:00:00+09:00
last_modified_at: 2024-11-14T00:00:00+09:00
---

# 테스트는 왜 필요할까?
"리포지토리, 서비스, 컨트롤러를 작성하고 나니 잘 동작하는지를 어떻게 확인하지?"

이걸 확인하기 위한 가장 원초적인 방법은 직접 돌려보는 것이다. 스프링을 올리고, 직접 요청을 날려보면서 확인하기...
그러나, 이걸 코드 상에서 잘 동작하는지를 확인하는 방법이 있다. 바로 테스트다.

테스트를 작성하면 저런 귀찮고도 귀찮은 과정을 건너뛰고 코드 상에서 내가 의도한 대로 함수가 동작하는지를 확인할 수 있다.

저게 내가 느꼈던 필요성이고, 구글링을 해보니 *"테스트는 소프트웨어의 품질을 향상시키고, 버그를 사전에 찾아내고 수정할 수 있기 때문에 중요합니다."* 라고 한다.

# 테스트 작성 방법
## given-when-then
mocking 같은 개념은 일단 두고, 가장 기본적으로 테스트를 작성하는 데 가이드라인이 될 수 있는 패턴이 있다. 바로 **given-when-then**이다.

- given: ~가 주어지고 (세팅)
- when: ~를 할 때 (실행)
- then: ~여야 한다. (검증)

예를 들어 오리의 계좌에서 거위의 계좌로 100만원을 송금하는 함수의 테스트를 작성한다고 가정해보자.

- given: 오리와 거위의 계좌에 각각 150만원이 있다.
- when: 오리가 거위에게 100만원을 송금한다.
- then: 오리의 계좌에는 50만원, 거위의 계좌에는 250만원이 남아있어야 한다.

이렇게 작성할 수 있고 이 내용을 그대로 코드로 작성하면 그게 테스트 코드다. 각각의 단계에서 사용하는 함수들은 테스트 패키지마다 다르다.

## 테스트는 독립적으로 실행되어야 한다
내가 앞서 오리와 거위의 계좌와 관련해서 테스트를 진행했었다.
뒤이어 저 테스트에 이어서 오리와 거위의 계좌에 100만원이 있을 때, 거위의 계좌에서 200만원을 송금하려 하면 예외를 throw 하는지를 확인하는 테스트를 작성한다고 해보자.

만약 앞선 테스트의 결과가 초기화되지 않고 다른 테스트와 유기적으로 연결되어 있다면, 오리의 계좌에는 50만원이, 거위의 계좌에는 250만원이 있는 채로 테스트가 진행된다.
따라서 거위의 계좌에서 200만원을 송금하는 건 정상적인 상황이기 때문에 예외가 발생하지 않을 것이고, 내가 의도한 바와 다르게 동작한다.

이런 상황이 벌어질 수 있기 때문에 테스트 전/후에 초기화를 해주거나, 각 테스트마다 데이터를 다르게 사용하는 등 테스트 간에 간섭을 없애 **테스트가 독립적으로 실행**되게 해야한다.

## 테스트의 단위는 작게!
이유는 간단하다. 하나의 테스트를 진행하는 데 2분이 걸린다면?
하나에 2분이라니 그 정도는 기다릴 수 있을 것처럼 보이지만, 만약 그런 테스트가 30개, 100개라면?
따라서 테스트의 단위를 작게 하는 게 좋다.

나의 경우, 저 오리-거위의 송금 테스트를 예시로 들자면, `class 오리_거위_송금` 이라는 테스트 클래스를 만들고, 안에 성공 케이스를 구현한 테스트 함수를 작성한다.
그리고 테스트 클래스 내부에 또 `class 오리_거위_송금_실패` 클래스를 만들어, 이 실패 케이스 클래스 내부에 다양한 실패 케이스들에 대한 테스트 함수를 구현한다.

```java
class 오리_거위_송금 {
@Test
public void 성공() {...}

@Nested
class 오리_거위_송금_실패 {
@Test
public void 계좌의_잔액이_부족할_때() {...}

@Test
public void 정전이_발생했을_때() {...}
}
}
```

이건 자바로 작성한 건데 자바스크립트로 하면 아마 `describe`를 중첩으로 사용하는 것 아닐까?

0 comments on commit b61b45b

Please sign in to comment.