Skip to content

Latest commit

 

History

History
104 lines (63 loc) · 7.09 KB

testcode.md

File metadata and controls

104 lines (63 loc) · 7.09 KB

테스트 코드를 왜 작성하는 것인가?

1. 디버깅 비용 절감

개발자가 총 개발 소요 시간중 온전히 요구사항에 대한 기능 개발을 하는 시간이 생각보다 많은 비중을 차지 않는다.

애플리케이션은 항상 내결함성을 가지고 있고 좋은 코드와 설계를 갖추더라도 결함의 존재 자체를 부정할 수 없다.
그래서 기능에 대한 버그는 항시 발생하고 그것에 해결하기 위해 개발자는 디버깅을 꾸준히 할 수밖에 없다.

그러나 테스트 코드가 있는 프로젝트는 어떨까?

견고한 테스트를 작성하더라도 완벽하게 결함을 없앨 순 없다.
하지만 테스트 코드를 통해 오류를 줄일수 있었고 빠르게 대처할 수 있는 내성이 생기게 된다.

테스트는 아래의 그림과 같이 범위와 비중에 따라 세 분류(e2e, integration, unit)로 나누어지고 각각의 역할을 가지고 있다.

image

  • unit 테스트: 도메인 모델과 비즈니스 로직을 테스트, 작은 단위의 코드 및 알고리즘 테스트
  • integration 테스트: 코드의 주요 흐름들을 통합적으로 테스트하며 주요 외부 의존성(ex. 데이터베이스)에 대해서 테스트
  • e2e 테스트: 최종 사용자의 흐름에 대한 테스트이며 외부로부터의 요청부터 응답까지 기능이 잘 동작하는지에 대한 테스트

이렇게 구분한 테스트 구간의 경계로 인해 문제가 되는 코드의 범위와 케이스를 빠르게 파악하고 수정할수 있게 되었다.
테스트로 인해 결함을 최소화시켜 디버깅에 소모되는 시간을 줄어듬으로써, 서비스 개발자가 비즈니스 개발에 집중하면서 생산성 향상에 도움을 준다.

2. 코드 변경에 대한 불안감 해소

“버그를 고쳤는데 다른데서 또 터지네…” 와 같은 상황이라면 회귀 버그를 겪고 있는 것.

*회귀 버그란?
이전에 제대로 작동하던 소프트웨어 기능에 문제가 생기는 것을 가리킨다.
일반적으로 회귀 버그는 프로그램 변경 중 뜻하지 않게 발생한다.

왜 그런 것일까? 사실 이유를 생각해 보면 당연하다.

애플리케이션에서 기능은 단일 하나의 요소(함수, 객체, 도메인)로 이루어지지 않고 여러 요소들이 서로 상호작용하고 협력하여 만들어진다.
→ 그렇기 때문에 하나의 기능을 수정할때 구성된 요소가 다른 기능과도 협력하고 있고 영향을 주기 때문에 회귀 버그를 겪게 되는 것

그렇다면 회귀 버그를 완전히 차단하고 예방하는 방법?

위에서 말했듯이 애플리케이션의 기능은 요소들이 상호작용으로 만들어지기 때문에 사실상 그건 불가능하다.
회귀 버그는 예방하는 것이 아니라 관리하고 대처해야된다.

다시 말해 저희는 회귀 테스트를 해야한다.

회귀 테스트는 기능 추가나 오류 수정으로 인해 새롭게 유입되는 오류가 없는지 검증 해준다.
개인적으로 제가 테스트가 수 천개 있는 인프런 프로젝트를 진행하면서 느낀 점 중 가장 크게 와닿는 테스트의 이점이다.

테스트 코드는 그때 당시의 기능을 만들기 위해서만 필요한 코드가 아니다.

  • 그 이후에 요구사항이 변경되어 기존 코드를 수정하거나
  • 더 나은 코드를 위해 리팩토링을 하거나

서비스가 지속 가능하게 발전하기 위해 필요한 코드이다.

3. 더 나은 문서 자료

우리는 좋은 코드를 작성하기 위해 잘 읽히는 코드, 가독성 좋은 코드를 작성하려고 노력한다.
하지만 서비스 복잡도가 늘어남에 따라 코드의 양이 많아지고 코드의 복잡도가 높아지게 되는데,
이러한 복잡한 요구사항이 중첩되어 있는 기능들은 신규 입사자들이 코드를 이해하는데 많은 불편함을 겪게 한다.

그래서 저희는 그들의 편의를 위해 따로 문서화를 해두지만 그 문서를 쉽게 방치한다. (문서화의 가장 고질적인 문제점)

이 문제점이 발생하는 이유는 무엇일까?

저의 생각은 개발자가 문서와 코드를 같은 유지 보수 대상과 범주로 가져가는 게 어렵기 때문이라고 생각한다.
두 대상을 분리하고 물리적인 거리감이라는 이유로 코드의 수정에 맞춰 문서의 최신화가 잘 이루어지지 않는 경우들이 많기 때문.
그래서 소스 코드 외의 별도의 문서자료들은 관리 대상으로서 쉽게 제외되기 때문에 신뢰하기 어려워진다.

아래와 같이 테스트를 작성할 때 가장 먼저 명세를 작성하면서 코드의 실제 동작을 기술함으로써 이 코드가 어떤 역할을 가졌는지 이해하는데 도와준다.

기존에 중복된 메일이 있는 경우 회원가입을 할 수 없습니다.

문서화 테스트는 기능과 코드를 이해하는 데 도움을 준다.

4. 좋은 코드는 테스트하기 쉽다.

좋은 코드는 “변경하기 쉬운”이라는 형용사를 가지고 있는데, 의미로는 약한 결합도을 가지고 있는 코드를 뜻하며
반대로 강결합이 되어있는 코드는 유지비용이 증감되어 저품질코드로 분류되어진다.

그렇다면 강결합으로 이루어진 코드를 테스트하기 쉬울까? 당연히 매우 어렵다.

외부의 영향을 받거나 내부적으로 의존성을 가지고 있는 코드는 변경에 유연하게 대응하지 못하고 재사용하기 어려운 코드들이다.
그렇기 때문에 테스트를 작성하기 어려운 코드가 만들어지는 것이다.

그렇다고 테스트하기 쉬운 코드가 모두 좋은 코드가 되는 것은 아니다.
하지만 저희는 테스트를 작성하면서 하나의 좋은 코드의 지표를 아래와 같이 세울수 있게 됩니다.

5. 테스트 자동화

개발자의 기도메타는 본인이 작성한 코드가 실제 운영 환경에 배포됐을때 불안감에 휩싸여 기도를 시작한다 ㅋㅋ

“내가 작성한 코드가 정상적으로 동작할까?”
“내가 작성한 코드로 인해 다른 부분에서 오류가 생기지 않을까?”

이런 오만가지 생각이 들면서 개발자의 불안감을 점점 키워간다.

하지만 자동화 테스트가 있는 순간부터 우리는 CI에서 우리가 작성한 테스트 코드로 버그가 배포되는 것을 방지할 수 있게 된다.
앞서 이야기한 변경에 대한 내성과 회귀 버그를 지속적인 코드 병합 단계에서 확인할 수 있으므로 소프트웨어의 품질 또한 높여준다.

즉, 테스트 코드가 존재함으로써 안정감 있는 프로젝트 아니 안정감이 있는 우리의 모습을 볼 수 있게 된다.


참고 레퍼런스 : Inflab Tech - 테스트 코드를 왜 그리고 어떻게 작성해야 할까?