테스트의 중요성은 강조해도 지나치지 않다. 테스트는 배포하는 것보다 훨씬 중요하다. 테스트 없이 배포를 한다는 것은 작성한 코드가 언제든 오작동해도 이상하지 않다는 얘기와 같다.
소프트웨어를 개발하는 방법중에 하나는 원하는 코드를 작성하기 이전에 테스트를 먼저 작성하는 것이다. 이를 Test-driven development, 혹은 TDD라고 부른다.
위에서 언급했듯, TDD는 실제 코드를 짜기 전에 단위 테스트부터 짜는 것을 원칙으로 한다.
TDD에는 세가지 법칙이 있다.
- 실패하는 단위 테스트를 작성할 때까지 실제 코드를 작성하지 않는다.
- 컴파일은 실패하지 않으면서 실행이 실패하는 정도로만 단위 테스트를 작성한다.
- 현재 실패하는 테스트를 통과할 정도로만 실제 코드를 작성한다.
깨끗한 테스트는 다섯가지 규칙을 따른다.
테스트는 빨라야한다. 테스트가 느리면 자주 돌릴 엄두를 내지 못하고, 코드 품질이 점점 망가지게 된다.
각 테스트는 독립적이어야한다. 한 테스트가 다음 테스트가 실행될 환경을 준비해서는 안된다. 즉, 어떤 순서로 실행해도 결과는 같아야한다.
테스트는 어떤 환경에서도 반복 가능해야한다. 테스트가 돌아가지 않는 환경이 하나라도 있다면 테스트가 실패한 이유를 둘러댈 변명이 생기기 때문이다.
테스트는 자가 검증이 가능해야한다. 즉, boolean
값으로 결과가 나와야한다. 성공, 아니면 실패다.
테스트는 적시에 작성해야한다. TDD를 따른다면 단위 테스트를 테스트하려는 실제 코드를 구현하기 전에 구현한다.
Single concept per test. 즉, 테스트 함수는 단 한개의 컨셉만 가지고 있어야한다. 이는 clean code 원칙중 함수의 역할은 단 한개여야한다는 것과 일맥상통한다.
이 말은 사실 '한 테스트 당 assert문을 최대한 줄여라'와 같다. 어떤 사람들은 한 테스트 당 assert문을 무조건 하나로 하는것이 옳다고 말한다. assert가 단 하나인 테스트 함수는 결론이 하나기 때문에 코드를 보면 훨씬 이해하기 쉽다. 이것은 상황마다 자기 자신이 판단하면 되겠다. 증요한 것은, 테스트 함수 하나는 개념 하나만 테스트하라는 것이다.
위의 나쁜 예시를 보자. 아래의 함수 한개가 너무 여러가지의 컨셉을 가지고 있다. 좋은 예시에서는 30일로 이루어진 달, 윤년, 윤년이 아닌 년에 따라 addDays()를 다르게 하고 있음을 볼 수 있다.
https://dev.to/aumayeung/javascript-clean-code-test-driven-development-12k9