TEST/SW 테스팅 이론

테스트 코드 작성하는 이유와 방법

블로그 주인장 2024. 3. 29.

테스트 코드 작성하기

애플리케이션을 개발하면서 테스트 코드를 통해 개발한 코드를 어떻게 테스트할 수 있는 지 알아보겠습니다.


테스트하기 어려운 영역


1️⃣관측할 때마다 다른 값에 의존하는 코드

  • 현재 날짜/시간, 랜덤값, 전역 변수/함수, 사용자 입력 등

2️⃣ 외부 세계에 영향을 주는 코드

  • 표준 출력, 메시지 발송, 데이터베이스에 기록하기 등

 

순수함수(pure function)

  1. 같은 입력에는 항상 같은 결과
  2. 외부 세상과 단절된 형태
  3. 테스트하기 쉬운 코드

 

테스트 코드를 작성하는 이유


  • 개발 과정에서 문제를 미리 발견할 수 있다.
    • 일부러 오류가 발생할 수 있는 테스트 코드를 작성해서 예외처리가 잘 작동하는지 확인
    • 정확히 의도한 비즈니스 로직에 맞춰 테스트 코드를 작성해서 결과값이 잘 나오는지 검토
  • 리팩토링의 리스크가 줄어든다.
    • 리팩토링 : 개발 이후 서비스 업데이트를 위해 계속해서 코드를 추가하고 수정하는 작업을 진행하는 것
    • 테스트 코드가 작성되어 있다면 테스트 코드를 실행해보는 것만으로도 혹시 모를 부작용에 대비할 수 있다.
  • 애플리케이션을 가동해서 직접 테스트 하는 것보다 테스트를 빠르게 진행할 수 있다.
  • 하나의 명세 문서로서의 기능을 수행한다.
    • 대부분 협업을 통해 프로젝트를 진행하기에, 다른 사람이 작성한 코드를 바로 이해하는 것은 쉽지 않다.
    • 코드를 이해하기 쉽게 개발자가 직접 명세를 작성하고 공유하는 과정을 거쳐야한다.
    • 동작 검증을 위해 작성되어 있는 테스트 코드를 애플리케이션 코드와 비교하면서 작성자의 의도가 파악되어 타인의 코드를 이해하기 쉬워진다.
  • 몇 가지 프레임워크에 맞춰 테스트 코드를 작성하면 좋은 코드를 생산할 수 있다.
  • 코드가 작성된 목적을 명확하게 표현할 수 있으며, 불필요한 내용이 추가되는 것을 방지한다.

 

단위 테스트와 통합 테스트


1️⃣ 단위 테스트

애플리케이션의 개별 모듈을 독립적으로 테스트하는 방식이다.

 

단위 테스트의 특징

  • 테스트 대상의 범위를 기준으로 가장 작은 단위의 테스트 방식이다.
  • 일반적으로 메서드 단위로 테스트를 수행하게 되며, 메서드 호출을 통해 의도한 결과값이 나오는 지 확인하는 수준으로
    테스트를 진행한다.
  • 특정 모듈에 대한 테스트만 진행하기 때문에 데이터베이스나 네트워크 같은 외부 요인을 제외하고 진행한다.
  • 테스트 비용이 적게 들기 때문에, 테스트 피드백을 빠르게 받을 수 있다.

 

2️⃣ 통합 테스트

애플리케이션을 구성하는 다양한 모듈을 결합하여 전체적인 로직이 의도한 대로 동작하는지 테스트하는 방식이다.

 

통합 테스트의 특징

  • 모듈을 통합하는 과정에서의 호환성 등을 포함해 애플리케이션이 정상적으로 동작하는 지 확인하기 위해 수행하는 테스트 방식이다.
  • 통합 테스트는 여러 모듈을 함께 테스트해서 정상적인 로직 수행이 가능한지를 확인한다.
  • 통합 테스트는 외부 요인들을 모두 포함하고 테스트를 진행하므로, 애플리케이션이 온전히 동작하는지를 테스트한다.
  • 테스트를 수행할 때마다 모든 컴포넌트가 동작해야하기 때문에 테스트 비용이 커지는 단점이 있다.

 

테스트 코드를 작성하는 방법


Given-When-Then 패턴

  • 간단히 테스트로 여겨지는 단위 테스트에서는 잘 사용하지 않는다.(불필요하게 코드가 길어진다)
  • 테스트 코드를 작성하는 이유 중 하나인 '명세' 문서의 역할을 수행한다는 측면에서 도움이 된다.

1️⃣ Given

  • 테스트를 수행하기 전에 테스트에 필요한 환경을 설정하는 단계이다.
  • 테스트에 필요한 변수를 정의하거나 Mock 객체를 통해 특정상황에 대한 행동을 정의한다.

2️⃣ When

  • 테스트의 목적을 보여주는 단계이다.
  • 실제 테스트 코드가 포함되며, 테스트를 통한 결과값을 가져오게 된다.

3️⃣ Then

  • 테스트의 결과를 검증하는 단계이다.
  • 일반적으로 When 단계에서 나온 결과값을 검증하는 작업을 수행한다.
  • 결과값이 아니더라도 이 테스트를 통해 나온 결과에서 검증해야하는 부분이 있다면 이 단계에 포함한다.

 

좋은 테스트를 작성하는 5가지 속성(F.I.R.S.T)

1️⃣ 빠르게(Fast)

  • 테스트는 빠르게 수행되어야한다.
  • 테스트가 느리면 코드를 개선하는 작업이 느려져 코드의 품질이 떨어질 수도 있다.
  • 테스트 속도에 절대적인 기준은 없지만, 목적을 단순하게 설정해서 작성하거나 외부 환경을 사용하지 않는 단위테스트를 작성하는 것 등을 빠른 테스트라고 할 수 있다.

2️⃣ 고립된, 독립적(Isolated)

  • 하나의 테스트 코드는 목적으로 여기는 하나의 대상에 대해서만 수행되어야한다.
  • 하나의 테스트가 다른 테스트 코드와 상호작용하거나 관리할 수 없는 외부 소스를 사용하게 되면 외부 요인으로 인해 테스트가 수행되지 않을 수 있다.

3️⃣ 반복 가능한(Repeatable)

  • 테스트는 어떤 환경에서도 반복 가능하도록 작성해야한다.
  • 개발 환경의 변화나 네트워크 연결 여부와 상관없이 수행되어야한다.

4️⃣ 자가 검증(Self-Validating)

  • 테스트는 그 자체만으로 테스트의 검증이 완료되어야한다.
  • 테스트가 성공했는지, 실패했는지 확인할 수 있는 코드를 함께 작성해야한다.
  • 결과값과 기댓값을 비교하는 작업을 코드가 아니라 개발자가 직접 확인하고 있다면, 좋지 못한 테스트 코드이다.

5️⃣ 적시에(Timely)

  • 테스트하려는 애플리케이션 코드를 구현하기 전에 완성되어야한다.
  • 너무 늦게 작성된 테스트 코드는 정상적인 역할을 수행하기 어려울 수도 있다.
  • 테스트 코드로 인해 발견된 문제를 해결하기 위해 소모되는 개발 비용도 커지기 쉽다.
  • 이 개념은, 테스트 주도 개발의 원칙을 따르는 테스트 작성 규칙으로, 테스트 주도 개발을 기반으로 애플리케이션을 개발하는 것이 아니라면, 이 규칙은 제외하고 진행하기도 한다.
반응형

'TEST > SW 테스팅 이론' 카테고리의 다른 글

TDD(Test-Driven-Development)의 설명  (0) 2024.04.02

댓글