테스트에 대한 개요

hanana·2023년 12월 19일
0

본 포스팅은 인프런 김우근 님의
Java/Spring 테스트를 추가하고 싶은 개발자들의 오답노트
강의를 참고하여 작성하였습니다.

TDD

Test Driven Development

아래는 Spiceworks에 What is TDD 라는 제목으로 소개한 글이다.
Test-driven development (TDD) is an iterative methodology that entails the conversion of each component of the application into a test case before it is built and then testing and tracking the component repeatedly.

번역기와 함께 요약하면,
TDD는 프로그램의 각 요소를 구축하기 전에 테스트 케이스를 작성한 다음, 구성 요소를 반복적으로 테스트하고 추적하는것을 수반으로 하는 방법론 이라고 한다.

TDD 개발 프로세스 - Red ,Green, Blue

  1. RED
    실패하는 테스트를 작성한다.
    이 과정에서 핵심은 컴파일 오류없이 오로지 테스트 결과가 실패로 남아야 한다.
  2. GREEN
    테스트가 성공할 수 있는 간단한 솔루션을 작성한다.
    이때 잘 작성되고 효율적인 코드가 반드시 필요하지는 않다. 통과하는것이 핵심이다.
  3. BULE (리팩토링 단계)
    성공한 테스트케이스를 기반으로 디자인패턴, 코드 보수 가능성, 가독성 및 품질과 같은 요소를 고려하여 리팩토링한다.
    코드가 수정될 때마다 테스트케이스를 실행하므로, 리팩토링 중에 기능이 손실되는 것에 대한 걱정을 하지 않을 수 있다.

그리고 TDD는 위 3가지 과정을 모든 개발단계에서 무한히 반복하는것을 의미한다.


TDD 장단점

장점

  • 1. 코드 품질 향상
    깨지는 테스트를 만들면서 인터페이스를 먼저 만드는것이 강제된다.
    -> What/Who 사이클을 고민하게 도와준다.
    어떤 행위(what)를 먼저 수행할 것인지를 결정한 후 누가(who) 수행할지를 결정한다.
    인터페이스를 먼저 구성하므로써 어떤 행위를 할 것인지를 먼저 정할 수 있게된다.
  • 2.개발자 생산성 향상
    TDD를 통해 개발자가 디버깅하는데 소요되는 시간을 줄여준다.
    개발을 처음 시작하는 단계에선 테스트 코드를 작성하는데 시간이 걸릴 수 있지만,
    프로젝트가 진행됨에 따라 테스트 작업이 더 빨라지고, 재작업이 줄어든다.

    Microsoft와 IBM의 공동 연구에 따르면
    TDD를 채택하면 결함 밀도가 40~90% 감소하는 것으로 나타났다고 한다.
    프로젝트를 완료하는 데 걸리는 시간도 15~35% 증가했지만
    유지 관리 비용이 낮아져 품질 개선으로 이를 상쇄했다고 한다.
  • 3. 문서로써의 역할
    테스트에 명시된 주장을 기반으로 사용자는 방법에 필요한 예상 입력과 원하는 결과를 확인할 수 있다.
    이를통해 코드를 작성한 개발자뿐만 아닌 모든 개발자가 좀 더 쉽게 코드를 유지보수하고 변경이 가능
  • 4. 신뢰할 수 있는 프로세스의 이점
    TDD를 사용하면 개발자와 사용자 모두 생성된 코드에 신뢰성을 가질 수 있음.
    테스트 코드를 통해 새로 추가한 코드가 이전의 코드와 어떻게 상호작용이 이루어질지 파악이 가능하고,
    추가한 코드로 회귀버그(Regression)에 대해 좀 더 자신감 있게 배포 할 수 있음
  • 5. 좋은 설계를 유도 할 수 있음
    테스트하기 좋은 코드는 일반적으로 설계가 잘 된 코드이다.
    테스트코드를 작성하다 보면 외부시스템에 의존하는 상황이 자주 발생하고, 테스트코드가 복잡해진다.
    테스트코드를 고민하면서 더 좋은 설계를 얻을 수 있다.

단점

  • 1. 단기적으로 개발속도 지연
    애플리케이션이 일정 크기가 넘어가기 전까지는 테스트를 먼저 작성해야하는 TDD 특성상 개발속도가 지연된다.
  • 2. 어려움
    테스트를 위한 전용문법, 의존성주입 등
    TDD를 적용한다는것 자체가 난이도가 있는 작업이다.

개발자가 고민해야 할 사항

  • 1. 무의미한 테스트
    findById와 같은 한두줄짜리 코드는 굳이 테스트를 하지 않아도 의도가 명확하고, 이러한 한두줄짜리 코드의 테스트를 위해서 수십줄을 TestCode를 작성해야하는것이 올바른지 고민해보자
  • 2. 느리고 쉽게 깨지는 테스트
    @SpringBootTest 와같은 테스트는 Spring에 의존하고 있어 테스트를 하기위해서 SpringBoot를 띄워야하고, 이러한 테스트는 시간이 오래걸린다.
  • 3. 테스트 불가능한 코드
    테스트 코드를 작성하면 테스트가 불가능한 경우가 있다.
    테스트가 불가능한 상황이라면 설계가 잘못된 코드라고 말 할 수 있다.
    테스트코드가 개발자에게 설계에 대해서 다시 생각해보라는 경고의 의미로
    이를 Mock 라이브러리를 이용해서 억지로 성공시킨다면, 좋은 설계를 가져갈 수 있는 기회를 놓치게 된다.

테스트의 3분류

  • 소형테스트(단위테스트)
    단일서버 / 단일프로세스 / 단일스레드 에서 돌아가는 테스트
  • 중형테스트(통합테스트)
    단일서버 / 멀티프로세스 / 멀티스레드 에서 돌아가는 테스트
    h2를 사용한 테스트가 여기에 해당
    자연스럽게 소형테스트보다 느리고, DB라는 외부모듈에 의존하고 있어 결과가 항상 일치하지 않는다.
  • 대형테스트(종단테스트)
    멀티서버에서 돌아가는 테스트
    보통 E2E 테스트

가이드에 따르면
중형테스트는 전체 테스트의 약 15%를 차지하고, 단위테스트가 전체테스트의 80%를 차지해야 한다.
그러나 많은 개발자들이 대부분의 테스트를 중형테스트로 만드곤 하는 실수를 저지르는데 이는 안티패턴이므로 지양해야 한다.


기타 참고자료
https://www.spiceworks.com/tech/devops/articles/what-is-tdd/

profile
성숙해지려고 노력하지 않으면 성숙하기까지 매우 많은 시간이 걸린다.

0개의 댓글