리팩토링 2판 요약 정리 Ch.4
카테고리: Software ArchitectureDecember 14, 2021
리팩토링 2판을 번역/요약한 글입니다.
테스트 만들기 (Building Tests)
- 리팩토링은 그 자체로 매우 훌륭한 도구이지만, 이것만으론 부족하다. 혹시 모를 실수에 대비해 반드시 견고한 테스트 코드가 있어야 한다. (IDE와 같은 도구에서 제공하는) 자동 리팩토링 기능을 사용한다고 하더라도 테스트 코드를 통해 테스트하는 것이 좋다.
- 굳이 리팩토링 때문만이 아니더라도, 좋은 테스트를 작성하고 사용하면 개발자로서의 효율을 높일 수 있다.
자가 테스트 코드의 가치 (The Value of Self-Testing Code)
- 사실, 대부분의 개발자들은 디버깅하는데 대부분의 시간을 보낸다. 실제 개발을 하는 시간은 상대적으로 적다. 일반적으로 버그를 해결하는 것은 그렇게 어렵진 않지만(?), 버그를 찾는 것은 지옥이다. 그리고 버그를 하나 해결하면 또 다른 곳에서 버그가 튀어나온다.
버그 보존의 법칙 - 모든 테스트가 자동으로 결과를 체크하도록 하는 것이 좋다 (콘솔 창 같은 곳에 찍힌 테스트 로그를 수동으로 일일이 비교하고 있을 순 없지 않은가?).
- 이렇게 테스트를 자동화하면 생산성을 (훨씬) 증대할 수 있다. 나의 경험을 예로 들자면, 기능(함수)을 추가할 때마다 테스트 코드를 추가하고 테스트를 돌렸더니 버그를 찾는데 걸리는 시간이 감소하여 결과적으로 디버깅 시간이 감소했다.
- 또한, 테스트를 자주 돌렸기에 버그가 발생한 지점이 내가 방금 작성한 코드에 있음을 빠르게 파악할 수 있었고, 살펴봐야 하는 코드의 양이 적기 때문에 빠르게 디버깅할 수 있었다.
기타 요약
- 각 테스트 케이스가 실패하는 모습을 적어도 한 번이상은 직접 확인해보라. 항상 성공만 하는 테스트는 별 의미없다.
- 테스트를 쉽게 돌릴 수 있도록 도와주고, 실패한 테스트 케이스를 쉽고 빠르게 볼 수 있게 해주는 프레임워크가 좋은 테스트 프레임워크이다. 이는 자가 테스트 코드에 있어 필수적인 피드백이다.
- 테스트를 자주 해라. 현재 작성 중인 코드는 수 분마다 테스트하고, 모든 테스트를 적어도 하루에 한 번 이상 돌려라.
- 테스트는 현재, 혹은 미래에 발생할 버그를 찾기 위해 수행하는 것이다. 따라서 테스트는 위험 요인을 위주로, 즉 risk-driven 방식으로 수행해야 한다. 단순히 읽고 쓰기만 하는 (클래스의) 접근자 같은 것들은 단순하기 때문에 버그를 찾을 가능성이 낮고, 따라서 굳이 테스트할 필요가 없다.
- 너무 많은 테스트 케이스를 작성하게 되면 정작 필요한 테스트를 놓치게될 수 있다. 나는 주로 잘못될까봐 걱정되는 영역 위주로 테스팅하는데, 이렇게 적은 수의 테스트 케이스 만으로도 테스트의 많은 이점을 누릴 수 있다.
- 완벽한 테스트를 아예 하지 않는 것보단 불완전한 테스트를 하는 것이 차라리 낫다.
- 무언가 잘못될 수 있는 경계 조건을 반드시, 그리고 집중적으로 검사하라.
- 내가 코드의 적(enemy)이 되었다고 생각하고 테스트하라. 어떻게 하면 테스트를 실패시킬 수 있는지 생각하라.
- 테스팅으로 모든 버그를 잡아낼 수 없다는 사실 때문에 테스트를 안 한다 는건 말도 안된다. 테스팅으로 모든 버그를 잡을 수 없는 건 사실이지만, 대부분의 버그는 충분히 잡아낼 수 있기에 걱정할 필요 없다.
- 앞서 말했듯이 리스크가 큰 영역, 복잡한 영역 위주로 테스트하라. 모든 영역에 대해 일일이 테스트를 하다 보면 지쳐서 테스트를 포기하게 될 수도 있다.
- 물론 테스트를 통해 모든 버그를 찾아낼 수는 없지만 리팩토링을 하면서 코드에 대해 더 많이 이해하게 되고, 그로 인해 점차 더 많은 버그를 찾아낼 수 있다.
- 버그를 발견하게 되면, 즉시 해당 버그를 명확히 잡아내는 테스트를 작성하는 습관을 들여라. 나는 항상 버그를 고치기 전에 이러한 테스트 케이스부터 만든다. 또한, 이를 계기로 테스트 케이스에 또 다른 허점은 없는지 살펴본다.
- 나는 항상 테스트를 마련한 다음 리팩토링을 진행하지만, 리팩토링하는 와중에도 계속해서 테스트를 추가한다.
- 새로운 기능을 추가할 때, (당연하게도) 새로운 테스트도 추가하지만 기존 테스트도 다시 살펴보라. 테스트들이 명확한지, 무엇을 하는지 더욱 이해하기 쉽도록 리팩토링 해야 하는지, 올바른 테스트를 갖췄는지 등등을 살펴보라.
- “충분한 테스트”에 대한 좋은 측정 수단은 없다. 몇몇 사람들은 테스트 커버리지를 통해 측정해야 한다고 주장하지만, 테스트 커버리지는 테스트 되지 않은 영역을 식별해 내는 데엔 유용하지만 테스트의 퀄리티를 측정하지는 않는다.
- 결국 “충분한 테스트”에 대한 기준은 주관적이다. “누군가 코드에 결함을 만들게 되었을 때 (테스트를 통해) 이를 캐치해낼 수 있는가?” 와 같은 것들이다. 자가 테스트 코드의 목적은 (코드에 대해) 자신감을 얻기 위함이다. 리팩토링했을 때 모든 테스트를 통과하게 되면, 리팩토링 과정에서 어떠한 버그도 만들지 않았다고 자신할 수 있고 테스트를 충분히 했다고 할 수 있다.