나도 써보자 TDD

GDana
gdana
Published in
5 min readJul 21, 2019

배움을 얻고 있는 곳에서 내준 과제를 붙들고 있는지 일주일이 지나도 이게 대체 어떻게 돌아가는 건지 이해가 안가는 코드가 하나 있었습니다. 개발자라면 한번쯤 들어봤을 법한 TDD인데요. 테스트 코드를 작성하고 있어도 TDD를 모르고 작성한 결과 TDD 자체가 에러가 되는 테스트를 만들게 되었죠. 시행착오를 기록함으로써 모르고 작성했던 TDD가 무엇인지 알아가고자 기록합니다.

TDD를 작성하고 테스트가 통과하도록 만드십시오.

TDD를 작성하는 것이 과제인데 TDD는 무엇인지, 사용된 라이브러리는 어떻게 작동되는지 그리고 console.log 로 테스트 하는 것과 어떻게 다른지 가늠이 가지 않아 공부한 TDD를 소개합니다.

TDD 특징

  • 프로그래밍 완료 후 테스트를 하지 않고, 선 테스트 케이스를 작성합니다.
  • 여기저기 console.log 로 값을 체크하는 방법이 아닌 프로그래머가 작성한 코드가 옳은지 여부를 해결하기 위한 Assertion(해결하고자 하는 ‘주장’)을 세웁니다.
  • 때문에 프로그래밍의 목적을 명확히 정의해야 테스트 케이스를 작성할 수 있습니다.

아무래도 익숙한 프로그래밍이 아니지요? 이를 바탕으로 한 TDD 절차 또한 생소할테니 알아보고 가겠습니다!

TDD 절차

  1. TDD 실패: 성공적으로 돌아가는 코드를 작성하기 전에 구현할 기능 단위 테스트 케이스 먼저 작성합니다.
  2. TDD 성공: 기능 구현한 코드가 없고 테스트 케이스만 있기 때문에 1번의 테스트는 실패가 됩니다. 이를 통과하기 위한 코드를 작성합니다.
  3. TDD 리팩토링: 개선해야 할 코드가 있다면 리팩토링합니다.
  4. (다시 첫번째로 돌아가 테스트 케이스 작성)

조금이나마 TDD가 무엇인지 알게됬지만 테스트 케이스에 사용하라고 던져진 describe , it , expect 의 정체가 발목을 잡는군요!

테스트 도구

쓰임이 무엇인지 궁금했던 각 함수들은 테스트 프레임워크로 mocha, 라이브러리로는 chai 에 사용되는 함수였습니다.

  • describe: 테스트, 테스트의 이름을 지정합니다.
  • it: 단위 테스트, 테스트 안에서 실행될 단위 테스트입니다.
  • expect(a).to.equal(b): 각 a와 b에는 ‘결과값/기대값’이 들어가며, expect 는 chai의 세가지 Assertion 중 한가지입니다.

과제를 실행하기 위한 최소한의 정보를 알았으니 이제 테스트 케이스를 작성하러 가볼까요?

테스트 케이스 실패1

‘신용카드 번호가 주어지면 접두사와 카드 번호 길이 조합에 대해 올바른 발급기관을 리턴하는 함수를 작성하시오’ 라는 문제의 테스트 케이스를 작성하는 것이 과제였지만 흔한 비기너의 코드는 원하는대로 돌아가지 않습니다…

테스트 성공을 뜻하는 체크 표시가 출력됬지만 모든 테스트에 통과되지 않았다는 메세지가 출력되고 있으니 머리속에는 한가지 의문밖에 들지 않았지요.

“초록색 체크가 뜨면 통과됬다는 말 아닌가? ”

네! 이렇게 문제 해결에 제대로 접근하지 않았기 때문에 떠오를 수 있었던 의문이였습니다. 더불어 에러를 예방하고 찾아내기 위해 작성된 것이 테스트 코드니까 ‘테스트 코드는 완벽해’ 라고 생각했던 것 같습니다. 틀린 것이 없다 생각했기 때문에 작성된 테스트 코드에서 발생한 실수를 찾아내지 못했으니까요.

그렇담 찾아내지 못했던 실수를 한번 볼까요?

detectNetwork.test.js

혹시 찾으셨나요?

644에서 649까지의 접두사를 제외한 체크해야 할 접두사는 6011, 65입니다. 하지만 테스트하는 값은 길이만 다른 6011을 테스트 했기 때문에 올바른 테스트를 할 수 없었습니다.

테스트 케이스 실패2

실수를 잡아냈으니 이제 테스트 할 올바른 값을 넣으면 통과될 줄 알았지만 이번엔 테스트 케이스가 에러를 출력합니다.

detectNetwork.js

65의 접두사와 16, 19의 길이를 가지는 카드 번호를 확인하고자 짠 코드지만 65를 체크할 수 있는 값이 없기 때문에 6011하나만 체크하고 있었고 이 부분을 에러로 출력하고 있었던 것입니다.

테스트 케이스 성공

확인된 에러를 아래와 같이 고쳐봅니다.

코드를 위와 같이 고치고나니 모든 테스트가 통과됬습니다!

만약 테스트 코드 작성을 위한 코딩이 아닌 카드 번호가 주어졌을 때 올바른 발급기관을 리턴하는 코드를 짜는 것이 과제였다면 에러가 생긴 블럭 자체를 true로 인식하고서 그대로 제출했을 것 같네요.

사실상 if문 조건식에서 or연산자를 사용하고 있기 때문에 6011만 만족하더라도 참인 구문이였으니까요.

테스트 케이스 리팩토링

모든 테스트를 통과했으니 이제 MasterCard, Visa 등 여러 발급 기간의 번호를 확인을 위해 코드를 조금 리팩토링 해볼까요?

detectNetwork.test.js

카드 번호 길이가 16인 신용카드 번호를 일일이 적어주는 불폄함을 해소하기 위해 repeact()를 사용합니다.

큰 부분을 리팩토링 한 것은 아니지만 코드가 조금 깔끔해진 것 같네요.

이제 나도 TDD 작성?

마지막 테스트까지 통과하고 다시 과제를 확인할 때 TDD가 이렇게 작성되는 거구나 싶었던 것 같습니다. 하지만 TDD가 무엇인지 알기위한 코드였기 때문에 실제로 코드 작성할 때 사용해봐야 제것이 될 것 같습니다 : )

--

--