읽기 좋은 코드가 좋은 코드다 Ch 14

테스트와 가독성

더스틴 보즈웰, 트레버 파우커

Alt text

느낌표 ! (인상 깊은 문장 | 문맥)

다른 프로그래머가 수정하거나 새로운 테스트를 더하는 걸 쉽게 느낄 수 있게 테스트 코드는 읽기 쉬워야 한다.

테스트 코드가 크고 두렵게 느껴지면 다음과 같은 일이 일어난다.

  • 코드를 수정하는 일이 두려워진다. 아니, 우리는 이 코드에 손대고 싶지 않아. 테스트 케이스를 모두 변경하는 일은 너무나 끔찍하다고!
  • 새로운 코드를 작성하면 그에 따르는 새로운 테스트를 작성하지 않는다. 시간이 흐름이 지나면서 더 낮은 비율의 코드가 테스트되며, 따라서 코드에 대한 확신이 줄어들 수 밖에 없다.

p.204

TDD(test-driven development) 의 단점 중 하나는 나중에 기능을 수정할 때 연관되어있는 테스트 케이스를 수정하는 사이드 이펙트와 변경한 테스트에서 놓치는 부분이 발생할 확률이 높다는 것이다. 변경할 때는 처음 테스트 케이스를 만들 때 보다 이해도가 떨어질 것이고 검증 또한 부실할 가능성이 높기 때문이다. 테스트 케이스 또한 코드이기 때문에 보기 좋게 되어있지 않다면 수정하기 싫은 코드가 될 것이다. 그렇다면 더더욱 나중에 코드를 수정하기 꺼려질 것이고 테스트 케이스는 오히려 검증을 해주지 못하고 불필요한 통과라는 값만 반환하게 될 것이다. 코드가 보기 좋지 않다면 새로운 테스트 케이스를 작성하기에 꺼려지는 것도 사실이다. 이럴 때 기존 코드를 수정해야하지만 여러 이유로 그러지 못하는 경우 많다. 테스트 케이스가 촘촘하지 못하면 결국 나중에 할 일이 더욱 많아지기 때문에 비효율적이 된다. 테스트 케이스 또한 코드로써 깔끔하게 잘 작성해야한다.

부끄럽지만 필자의 경험으로는 사용자 계정 관련 테스트 코드를 작성할 때 처음에는 아래와 같이 테스트 계정을 생성했다.

it('Sign Up Test', async () => {
   await (new UserModel({
       userId: uuidv4(),
       pw: uuidv4(),
       name: randomStr(4),
       ...
   })).save();
   
   assert.eqaul(..., ...)
});

논리상으로는 문제는 없지만 계정 생성을 함수로 빼야 훨씬 더 좋은 코드가 된다. 장점은 아래와 같다.

  1. 다른 테스트에서도 사용자 계정을 간편하게 만들 수 있다.
  2. 가입 명세가 달라졌을 때 한 함수만 수정하면 된다.
  3. 코드의 양이 함수 호출로 끝나기에 전체적인 코드 line 수가 줄어든다.

위 예제처럼 코드를 작성하여 다른 테스트에서도 가입 생성을 저 로직을 copy & paste 로 사용했다. 시간이 지나고 문제를 직면했다. 테스트 실패했을 때 test 로 만들어진 사용자 데이터가 사라지지 않는 것이였다. 물론 의도에 따라서 안 사라지게 할 수 있겠지만 필자는 모든 테스트 데이터는 사리지기를 원했다. assert 전에 사용자 계정을 사라지게할 수 있지만 그 또한 불필요한 코드라고 생각이 들었다. 그리하여 사용자 계정을 생성할 때 userId: uuidv4() -> userId: ` test-${uuidv4()} ` 로 변경하기로 하였다. 그리고 테스트 케이스 모두 종료 후 userId 가 test- 로 시작하는 데이터를 찾아 삭제하도록 하였다. 또 문제는 모든 사용자 계정을 생성하는 곳을 찾아가 수정을 해야했다. 이 때 잘못을 깨닫고 fakeCreateUser() 함수로 분리하여 사용하도록 하였다. 함수로 분리한 결과 나중에 pw 암호화이건 validation 이건 코드 수정이 최소화되었다. 사실 이론적으로 모르는 이야기는 아니였지만 실제 코드에서는 그러지 못했었다. 아는 것과 깨달은 것은 다른 것 같다.

일반적인 설계원리를 따르면 덜 중요한 세부 사항은 사용자가 볼 필요 없게 숨겨서 더 중요한 내용이 눈에 잘 띄게 해야 한다.

p.206

가능하면 가장 간단한 입력으로 코드를 완전히 검사할 수 있어야 한다.

p.213

지금 작성하는 코드의 테스트 코드를 나중에 작성할 거라는 사실을 염두에 두면 재미있는 일이 벌어진다.

p.218

테스트 케이스도 당연히 코드이기 때문에 보기 좋아야한다. 일반적인 코드와 다른 것은 데이터까지 보기 좋아야한다는 것이다. 테스트 케이스에 필요한 데이터는 많은 데이터가 아니라 꼭 필요한 데이터 소수일 수 있다. 예를 들어 1~100 이 경우가 정상적인 데이터라면 경계값으로 데이터를 구성해야한다. [0, 1, 100, 101] 과 같이 말이다. 개인적으로 테스트 케이스도 보기 좋게 작성해야한다는 생각은 사실 크게 염두해두지 않았던 것 같다. 그래서 그런지 생각해보면 지금 작성 중인 테스트 케이스가 새삼 좋지 않게 보인다. 보이지 않던 것이 의식이 되면 보이는게 새삼 신기하다.

Chapter 14 느낌

Chapter 14 에서는 테스트 케이스가 보기 좋아야 테스트 대상이 되는 코드도 보기 좋다고 설명하고 있는 것 같다. 해야할 일이 명확할 것이고 버그도 줄어들기 때문이다.


읽기 좋은 코드가 좋은 코드다 Ch 13

코드 분량 줄이기

읽기 좋은 코드가 좋은 코드다 Ch 15

‘분/시간 카운터’를 설계하고 구현하기

NCloud LB & SourcePipeline 구축하기
tech collection 서비스 성능 개선하기
Selenium 복권 구매 자동화 만들어보기
디자인 패턴
책 리뷰
블로그 챌린지