Book Record/Clean Code

[Clean Code] 9장 단위 테스트

lakelight 2022. 10. 24. 18:25
728x90
반응형

 

깨끗한 코드를 작성하기 위한 아홉번째 기록

 

TDD 법칙 세 가지

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

위와 같은 법칙을 따른다면 코드를 한줄 작성할 때 마다 테스트 코드가 생길 것입니다. 그렇게 되면 실제 코드 보다도 더 많은 테스트 코드가 생길 것입니다. 이는 심각한 문제를 유발하기도 하기 때문에 신중하게 테스트 코드짜야합니다.

 

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

책에서 한 이야기가 나옵니다. 급하게 프로젝트를 완성해야 했기 때문에 지저분하지만 빠르게 테스트 코드작성한 이야기. 여러분도 예상하셨겠지만 지저분한 테스트는 테스트를 안 하는 것보다 못하다고 합니다. 왜냐하면 테스트 코드지저분할 수록 변경이 어려워지기 때문에 실제 코드를 변경해 기존 테스트 케이스가 실패하기 시작하면, 테스트 케이스수정하는데 많은 시간사용한다는 결론입니다. 또한 유지보수 하는데 많은 비용이 들 수 있습니다.

테스트 코드는 실제 코드 못지 않게 중요합니다. 테스트 코드는 사고와 설계와 주의가 필요하고 실제 코드 못지 않게 깨끗하게 짜야할 필요가 있습니다.

 

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

코드에 유연성, 유지보수성, 재사용성을 제공하는 버팀목이 바로 단위 테스트입니다. 이유는 테스트 케이스가 있으면 변경이 어렵지 않기 때문입니다. 그러므로 실제 코드를 점검하는 자동화된 단위 테스트 슈트는 설계와 아키텍처를 최대한 깨끗하게 보존하는 열쇠입니다.

 

깨끗한 테스트 코드

깨끗한 테스트 코드를 만들기 위해서는 3가지가 필요합니다.

  1. 가독성
  2. 가독성
  3. 가독성

가독성은 실제 코드보다 테스트 코드에 더더욱 중요합니다.  가독성을 위해서는 명료성, 단순성, 풍부한 표현력이 필요합니다. 테스트 코드는 최소의 표현으로 많은 것을 나타낼 수 있어야 합니다.

 

이중 표준 리팩터링 예제

@Test
public void turnOnLoTempAlarmAtThreashold(){
    hw.setTemp(WAY_TOO_COLD);
    contoller.tic();
    assertTrue(hw.heaterState());
    assertTrue(hw.blowerState());
    assertFalse(hw.collerState());
    assertFalse(hw.hiTempAlarm());
    assertTrue(hw.loTempAlarm());
}

위 코드를 가독성있게 리팩터링 한 예제가 있어서 가져와봤습니다.

@Test
public void turnOnLoTempAlarmAtThreashold(){
    wayTooCold();
    assertEquals("HBchL", hw.getState());
}
public String getState(){
    String state = "";
    state += heater ? "H" : "h";
    state += blower ? "B" : "b";
    state += cooler ? "C" : "c";
    state += hiTempAlarm ? "H" : "h";
    state += loTempAlarm ? "L" : "l";
}

True, False를 대소문자로 표현함으로써 간결하면서도 가독성을 높였습니다.

 

테스트 당 assert 하나

assert문이 하나인 함수는 결론이 하나라서 코드를 이해하기 쉽고 빠릅니다. 

assert문을 추가로 사용해야 할 때, given-when-then이라는 관례를 사용하면 given/when부분을 부모 클래스에 두고, then 부분을 자식 클래스에 두면 중복을 제거하고, assert문도 하나를 사용할 수 있습니다. 하지만 이런 경우에는 assert문을 한개 이상 사용하는 것도 좋은 방법입니다. 최대한 줄이면 좋고, 상황에 따라 assert문을 추가로 사용해야 합니다.

테스트 당 개념 하나

하나의 테스트 함수에서 여러 개념을 테스트하면 좋지 않습니다. 가장 좋은 규칙은 "개념 당 assert 문 수를 최소로 줄여라""테스트 함수 하나는 개념 하나만 테스트하라" 입니다.

 

깨끗한 테스트 규칙 F.I.R.S.T

Fast: 테스트는 빨라야 합니다. 테스트는 빨리 돌아야 한다는 말입니다. 자주 돌려서 초반의 문제를 찾아내기 위해서는 빠르게 동작하는 테스트 코드를 짜야합니다.

Independent: 각 테스트는 서로 의존하면 안됩니다. 한 테스트가 다음 테스트가 실행될 환경을 준비해서는 안됩니다. 각 테스트는 독립적으로 그리고 어떤 순서로 실행해도 괜찮도록 짜야합니다.

Repeatable: 테스트는 어떤 환경에서도 반복 가능해야 합니다. 실제 환경, QA 환경, 버스를 타고 집으로 가는 길에 사용하는 노트북 환경에서도 실행할 수 있어야 합니다.

Self-Validating: 테스트는 부울 값으로 결과를 내야 합니다. 성공 아니면 실패입니다. 통과 여부를 알려고 로그 파일을 읽게 만들어서는 안됩니다.

Timely: 테스트는 적시에 작성해야 합니다. 단위 테스트는 테스트하려는 실제 코드를 구현하기 직전에 구현해야 합니다. 

 

 

마무리

이번에는 단위 테스트에 대해서 배울 수 있는 시간이었습니다.

프로젝트를 할 때 테스트 코드를 짜지 않고 개발 했던 적이 있습니다.
프로젝트에서 기능이 변경되거나 오류 수정을 할 때마다 직접 포스트맨으로 테스트를 해야했고,
심지어 데이터베이스 구조를 변경하는 작업도 필요했기 때문에 변경하는 작업이 정말 두려웠습니다.

그런 경험이 있기에 이번 단위 테스트 부분은 정말 공감을 많이 하면서 읽었습니다.
개발을 할 때 테스트 코드를 짜고 실패한 테스트가 통과할 정도만 코드를 짜라고 하는 법칙이
정말 가슴속 깊이 박혔습니다.

포스팅 읽어주셔서 감사합니다.

 

 

[출처]
Clean Code (클린 코드,애자일 소프트웨어 장인 정신), 로버트 C. 마틴 저

728x90
반응형

'Book Record > Clean Code' 카테고리의 다른 글

[Clean Code] 11장 시스템  (2) 2022.11.19
[Clean Code] 10장 클래스  (0) 2022.11.06
[Clean Code] 8장 경계  (0) 2022.10.21
[Clean Code] 7장 오류 처리  (0) 2022.10.20
[Clean Code] 6장 객체와 자료 구조  (2) 2022.10.07