From b61b45bfbe56e0c5af9372d0adfe0d217aa45746 Mon Sep 17 00:00:00 2001 From: nyj001012 Date: Thu, 14 Nov 2024 20:40:12 +0900 Subject: [PATCH] docs: :memo: update post --- _posts/web/2024-03-22-how_to_test.md | 57 +++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/_posts/web/2024-03-22-how_to_test.md b/_posts/web/2024-03-22-how_to_test.md index a440689..c186bde 100644 --- a/_posts/web/2024-03-22-how_to_test.md +++ b/_posts/web/2024-03-22-how_to_test.md @@ -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`를 중첩으로 사용하는 것 아닐까?