9장 단위 테스트

Seunghee Ryu·2023년 12월 13일
0

클린 코드

목록 보기
9/18

  • 단위 테스트의 중요성과 규칙에 대해 설명한다

TDD 법칙 세 가지

  • 실패하는 단위 테스트를 작성할 때까지 실제 코드를 작성하지 않는다
  • 컴파일은 실패하지 않으면서 실행이 실패하는 정도로만 단위 테스트를 작성한다
  • 현재 실패하는 테스트를 통과할 정도로만 실제 코드를 작성한다

깨끗한 테스트 코드 유지하기

  • 더러운 테스트 코드는 없느니만 못하다
  • 테스트 코드가 복잡할수록 테스트 케이스를 작성하는 시간이 더 오래 걸린다
  • 기능이 추가되거나 변경될 때마다 테스트 케이스를 유지/보수 하는 비용은 늘어난다
  • 테스트 코드는 실제 코드 못지 않게 깨끗하게 짜야 한다

테스트는 유연성, 유지보수성, 재사용성을 제공한다

  • 테스트 케이스가 있고 커버리지가 높을 수록 유연한 기능 추가/변경이 쉽다
  • 아키텍처나 설계가 부실한 곳에서 더 효과있다
  • 기능 변경이 되더라도 테스트 케이스만 다 통과한다면 문제가 발생하지 않기 때문

깨끗한 테스트 코드

  • 깨끗한 테스트 코드를 만들기 위해서는 가독성이 중요하다
  • 중복된 코드를 합치고, 테스트 케이스에 노출이 필요없는 코드는 숨긴다
  • BUILD-OPERATE-CHECK 패턴이 이런 테스트 구조에 적합하다
    - Build: 테스트 전 필요한 데이터를 빌드하고,
    - Operate: 테스트할 API 메소드를 호출하고
    - Check: 실행한 메소드의 결과가 시스템에 준영향과 DB에 준 영향을 check(확인) 하라
  • 핵심은 잡다하고 세세한 코드를 다 없애 정말 필요한 자료 유형과 함수만 사용한다는 점

도메인에 특화된 테스트 언어

  • 테스트 코드를 작성하며 세세한 정보와 함수를 은닉하고 테스트에 필요한 함수만 노출시키는데 이렇게 특수 API가되며 이게 테스트 언어다
  • 깨끗한 테스트 코드를 만들기 위해 리팩토링을 하며 더 간결하고 표현력 있는 코드를 만들어라

이중 표준

  • 테스트 API코드에 적용하는 표준은 실제 코드에 적용하는 표준과 다르다
  • 실제 코드만큼 퍼포먼스를 따지지 않아도 된다.
  • 테스트 환경에서 돌아가는 코드이기 때문에 요구사항이 다르기 때문이다

테스트당 assert 하나

  • 최대한 하나의 테스트에서는 하나의 assert만 할 수 있도록 한다
  • 하지만, 테스트를 억지로 분리하며 중복되는 코드가 많아질 경우 합치는 것도 좋다
  • assert 문을 최대한 줄이는 것에 초점을 맞춘다

테스트당 개념 하나

  • 코드의 중복을 고려해 assert 문을 하나로 못줄이는 경우가 많다면 생각을 바꾼다
  • 테스트 함수에 하나의 개념만 테스트하라.
// addMonths ( ) 메서드를 테스트히는 장황한 코드
public void testAddMonths() {
		SerialDate dl = SerialDate.createlnstance(31, 5, 2004);
		
		SerialDate d2 = SerialDate.addMonths(1, dl);
		assertEquals(30, d2.getDayDfMonth());
		assertEquals(6, d2.getMonth());
		assertEquals(2004, d2.getYYYY());
		
		SerialDate d3 = SerialDate.addMonths(2, d1);
		assertEquals(31, d3.getDayOfMonth());
		assertEquals(7, d3.getMonth());
		assertEquals(2004, d3.getYYYY());
		
		SerialDate d4 = SerialDate.addMonths(1, SerialDate.addMonths(1, d1));
		assertEquals(30, d4.getDayOfMonth());
		assertEquals(7,  d4.getMonth()) ;
		assertEquals(2004, d4.getYYYY());
}
  • 위 코드를 보면 개행순으로 3가지의 테스트를 하는데, 얼핏보면 다 날짜를 검사하는 것 같아서 같은 개념을 테스트하는거니 괜찮을 것 같지만, 사실 다 다른 개념이다
    1. 첫 케이스는 30일로 끝나는 한 달을 더하면 날짜는 30일이 되어야지 31이 되면 안된다
    1. 두 번째 케이스는 2달을 더하면 그리고 그 달이 31일로 끝나면 31일이 되어야 한다
    1. 마지막은 31일로 끝나는 한 달을 더하면 30일이 되어야지 31일이 되면 안되며 각각의 다른 개념을 가지고 있기에 함수를 나누는게 맞으며, 2월같은 마지막 날짜가 28일인 경우의 테스트 케이스도 채워야 한다

F.I.R.S.T

  • 깨끗한 테스트가 되기 위해서는 다음 다섯 가지 규칙을 따른다

빠르게(First)

  • 테스트는 빨라야 한다
  • 테스트가 느리면 자주 돌리지 못하고 그 시간만큼 코드를 정리하지 못 할뿐 아니라 테스트를 자주 수행할 수 없다

독립적으로(Independent)

  • 각각의 테스트가 서로 의존하면 안된다
  • 한 테스트가 다음 테스트가 실행될 환경을 준비해서는 안된다

반복가능하게(Repeatable)

  • 테스트는 어떤 환경에서든 반복 가능해야 한다
  • 실제 환경, QA환경, 오프라인 환경 모두 가능해야 한다
  • 테스트가 돌아가지 않는 환경이 있다면 핑계거리가 되며 테스트를 수행하지 못해도 넘겨야하는 상황이 생긴다

자가검증하는(Self-Validating)

  • 테스트는 Boolean 값으로 결과를 내야 한다 (성공 or 실패)
  • 통과했는지를 알기 위해 로그 파일이나 콘솔창을 봐야하는것은 잘못된 것이다

적시에(Timely)

  • 테스트는 적시에 작성해야 한다
  • 즉, 테스트하려는 실제 코드를 구현하기 직전에 구현한다
  • 실제 코드를 작성 한 뒤에 테스트 코드를 작성하려 하면 테스트하기가 어려울 수도 있고, 테스트가 불가능하도록 실제 코드를 설계할 수도 있다

개인적인 감상

  • TDD에 대한 중요성은 들었지만 실제 개발에 적용해본적이 없어서 이론적으로만 이해가 되었다
  • 각종 강의나 유튜브 등에 예제가 있을테니 테스트를 만드는 것에 대해서 조금 더 검색해봐야 할 것 같다

0개의 댓글