반응형

📝테스트 코드 작성의 장점

  1. 테스트 코드를 작성하면 다른곳에서 코드 수정이 이루어졌을 때 테스트코드를 실행시킴으로써 빠르게 파악할 수 있습니다.
  2. 내 코드를 리팩토링할 때 기존 기능이 정상 동작하는지에 대해 빠르게 파악할 수 있습니다.
  3. 테스트 코드는 그 차체로 명세입니다. 어떤식으로 동작했으면 좋겠다는 등에 대한 이유가 포함되어있는 코드입니다.
  4. CI할 때 테스트코드를 앞에 두어서 오류나면 아예 빌드가 안 되게 되어 버그 있는 코드를 배포 안 시키게 할 수 있습니다.

 

📝테스트 코드 작성의 단점

  1. 테스트 코드도 생각을 해야하고 코드를 짜야하기 때문에 개발 공수랑 같이 들어가게 됩니다.
  2. 유지보수가 지속적으로 필요합니다.
  3. 잘못된 테스트를 작성한 경우는 신뢰를 주기 힘듭니다.
  4. 너무 과도한 테스트는 생산성을 저하합니다. 적절한 선에서의 테스트 코드 작성이 필요합니다.

 

📝TDD, BDD, ATDD

Test-Driven Development (TDD)

  1. 실패하는 테스트 작성 (Red)
  2. 테스트를 통과시키기 위한 최소한의 코드 작성 (Green)
  3. 코드 정리 및 리팩토링 (Refactor)

개발자가 테스트를 먼저 작성하고 그 테스틀 통과하는 최소한 코드를 작성하는 방식입니다.

 

Behavior-Driven Development (BDD)

  1. 어떤 상황이 주어졌을 때 (Given)
  2. 어떤 행위를 하면 (When)
  3. 어떤 결과가 나와야한다 (Then)

사용자의 행동과 기대결과를 중심으로 시스템을 설계하고 개발하는 방식입니다.

 

Acceptance Test-Driven Development (ATDD)

  1. 어떤 상황이 주어졌을 때 (Given)
  2. 어떤 행위를 하면 (When)
  3. 어떤 결과가 나와야한다 (Then)

승인 조건을 먼저 정의하고 그 조건 만족하는지 테스트하는 방식입니다. → 도대체 BDD랑 하는 행위가 뭐가 다른지 모르겠음

 

 

우리가 실무를 하면 시간안에 해야하기 때문에 기능 개발이 우선이 되고 그 다음에 그 기능에 대해 경계값에 대해 테스트하는 게 훨씬 좋습니다. 테스트를 먼저 작성하고 개발하는 건 너무 비효율적이고 최악의 경우 테스트만 만들고 데드라인이 다가온 경우도 있을 수 있으니 개발 먼저 하고 그에 맞는 테스트를 작성하는게 좋습니다.

 

 

📝가치 있는 테스트 코드

테스트의 가치

  • 모든 걸 테스트 코드로 작성할 수 있지만 일반적으로 로직이 복잡하거나 도메인 관련성이 큰 경우 테스트의 가치가 큽니다.

테스트의 비용

  • 외부 의존성 (협력자수)이 많아질수록 테스트의 비용이 큽니다.

 

 

📝효율적인 테스트 vs 비효율적인 테스트

효율적인 테스트

효율적인 테스트는 테스트할 가치가 있는 것들을 의미합니다.

도메인 관련성이 높거나 코드가 복잡한 걸 의미합니다.

 

  • 도메인 관련성이 높거나 코드가 복잡한 경우
    • 달력의 계산 시스템과 같이 의존성은 없지만 복잡하면서 도메인 관련성이 높음
  • 의존성이 높으면서 도메인 관련성이 높거나 코드가 복잡한 경우
    • 테스트하기는 애매하기 때문에 이럴 때는 의존성을 분리시켜서 알고리즘은 도메인 관련성이 높거나 코드가 복잡한 부분으로 나눠서 테스트 해야한다. (리팩토링 필요)

 

 

비효율적인 테스트

비효율적인 테스트는 테스트를 하나마나인 경우를 의미합니다.

간단한 코드이거나 컨트롤러와 같은 간단하면서 외부 의존성이 많은 경우가 이에 해당합니다.

 

  • 로직을 복잡하지 않고 외부 의존성만 많은 코드
    • 레이어를 연결해주고 데이터를 주고 받는 역할
  • 의존성은 낮으면서 간단한 로직
    • 간단한 코드로 프로퍼티의 값을 세팅 따위의 간단한 코드

 

📝좋은 테스트와 테스트 궁금증

단위테스트 비중 늘리기

의존성에 엮이지 않게 해서 빠르게 테스트 코드를 실행 시킬 수 있게한다.

 

실패 케이스 작성

성공하는 케이스에 대해서만 만드는 게 아니라 실패했을 때 어떤 오류를 발생이 나와야하는지에 대한 것도 테스트코드에 넣으면 좋다.

 

쉽게 깨지지 않는 테스트

너무 자주 깨지는 테스트의 경우 하나의 서비스만 테스트하는 것이 아니라 통합테스트 마냥 여러 서비스를 같이 사용하는 경우 벌어집니다.
Mock으로 조회하고 Mock으로 데이터를 넣거나 해도 Mock에 사용하는 Service를 호출하기 때문에 해당 Mock에 해당하는 서비스가 바뀌면 테스트가 고장나게 됩니다. 즉, 상세 구현이 너무 노출되는 경우 변경에 취약하게 됩니다.

 

Mock으로 테스트가 망가지는 게 중요한 게 아니라 결과값이 잘 나오는 게 중요합니다.

 

회귀 방지를 잘해주는 테스트

회귀 방지란 코드 변경시 문제를 잘 알려주는 코드입니다.

수정이 일어났을 때 결과가 달라졌다는 걸 빠르게 인식 시킬 수 있는 게 회귀방지를 잘해주는 코드입니다.

통합테스트의 경우 단위보다 더 넓은 범위 커비리지가 있기 때문에 회귀 방지가 더 잘 됩니다.

 

테스트 범위 정하기 (경계값 테스트)

모든 경우를 다 테스트 할 수 없다.

그 중에서 중요한 테스트를 하기 위해서

길이의 경계값 (2 ~ 10자리) 2

존재 유무를 기준으로하는 테스트

(이모지를 포함한 경우, 이모지 만 있는 경우, 이모지가 없는 경우)

랜덤값으로 하는 테스트

 

커버리지 100%는 불가능하다

커버리지 100%는 불가능하며 중요 부분에 대해 테스트 케이스를 만드며 진행하면서 고도화해야한다.

라인 커버리지가 아닌 컨디션 커버리지를 목표로 한다.

통합 테스트의 경우는 모든 경우보다 리스크 큰 핵심 엣지 케이스만 골라서 테스트하며 단순 조회같은 테스트는 안 하는게 낫다. (개발 시간은 유한) → CUD는 의미가 있는 테스트이다

 

테스트 환경을 분리해야한다

통합테스트의 경우 실제 개발 DB로 테스트하는 경우 매번 테스트할 때마다 같은 결과를 낼 수 없다.

테스트 DB를 사용하거나 인메모리나 도커를 이용해서 테스트를 하는게 일반적이다 (환경 분리)

 

 

📝통합테스트 (테스트 더블)

공유 의존성 (테스트 더블 필요)

  • 테스트 간에 공유되고 서로 결과가 영향을 미칠 수 있는 수단 제공합니다.
  • static 변수, 싱글톤 객체 등...

비공개 의존성 (테스트 더블 X)

  • 공유하지 않는 주로 시스템 내부 객체간의 의존성을 의미한다.
  • 구현 세부사항에 속하는 경우가 많다.
  • 인스턴스를 만들어서 제어가 가능하다.

프로세스 외부 의존성 (테스트 더블 필요)

  • 어플리케이션 외부에서 실행되는 의존성
  • 외부 시스템 변화에 따라 테스트가 깨질 수 있다.
  • 데이터베이스, 결제 시스템 등...

 

비관리 의존성

  • 상태 초기화 불가
    • 결제 API는 내가 테스트를 실행한다고 해서, 결제 내역 DB를 매번 깨끗하게 초기화해주지 않음
    • 테스트 실행 전에 “이전 결제 이력 지우기” 같은 걸 직접 못함
  • 외부 환경 종속
    • 네트워크 상태, API 서버 상태, 계정 제한, 요금 정책 등에 따라 테스트 결과가 달라짐
    • 내가 테스트 실행 맥락에서 이 모든 걸 통제할 수 없음
  • 외부 부작용
    • 실제로 결제를 발생시키면 돈이 빠져나가거나, 외부 시스템 로그에 기록이 남음
    • 테스트 실행이 외부 세계에 영향을 주므로 “안전하게 되돌릴 수 없음”


데이터베이스는 프로세스 외부 의존성이라 테스트 더블의 대상처럼 보이지만 내가 내부에서 제어가 가능하기 때문에 테스트 더블의 대상이 아니다. (비관리 의존성)

 

테스트 더블의 경우 내가 완전히 제어할 수 없는 외부자원으로 외부 API(결제 API)등이 이에 해당합니다.

 

 

 

🔗 참고 및 출처

https://velog.io/@suhongkim98/TDD-BDD-ATDD-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0

https://www.youtube.com/watch?v=QsD1hCzaGCU

https://www.youtube.com/watch?v=qQaUrk4kROk

https://www.youtube.com/watch?v=zblBEqTa_qQ

https://dionysus2074.tistory.com/313

https://www.youtube.com/watch?v=qECd2q3USqA

https://www.youtube.com/watch?v=gs1qM1TF5zA

반응형