유닛 테스트는 버그를 잡는다기보다 영역 표시를 하는 것

1 week ago 25

버그를 잡는 데 그다지 효과적이지 않은 유닛 테스트가 왜 업계에서 유일하게 보편화된 테스트 방법이 됐는지를 분석한 글 하드웨어 관점에서 소프트웨어 테스트는 끔찍해 보임 (저자는 하드웨어 개발 경험이 많은 프로그래머) 소프트웨어는 "나중에 고치면 된다"는 문화로 버그투성이 코드 출시가 허용되는 반면, 하드웨어 버그는 치명적이라 선택의 여지가 없음 유닛 테스트가 버그를 잘 못 잡는 두 가지 이유 까다로운 버그와 성능 문제의 상당수는 컴포넌트 간 상호작용에서 나오므로 여러 팀의 컴포넌트를 함께 돌리는 통합 테스트가 필요한데 통합 테스트는 매우 드묾 오히려 사람들은 자기 "유닛" 밖을 건드리지 않으려고 의존성 모킹에 무리한 일들을 함(모킹을 쉽게 하려고 추상 클래스만 쓰거나 테스트마다 API 스텁을 만들어 API 변경 시 호출부에 더해 스텁까지 전부 고쳐야 하게 만드는 식) 까다로운 버그를 찾으려면 아주 많은 입력 조합이 필요한데 유닛 테스트는 소수의 입력과 출력을 하드코딩하는 방식임 하드웨어 업계에서는 랜덤 입력 생성이 일반적이며 이는 입력 분포와 "출력이 올바른지 판별하는 방법"을 고민하게 만듦 반면 유닛 테스트의 기대 출력은 그냥 코드를 돌려 나온 값을 "정답"으로 하드코딩한 것이 전형적인 기원임 그런데 왜 유닛 테스트만 보편화됐는가 저자의 생각: 유닛 테스트의 주된 용도는 모든 것이 통제 없이 끊임없이 바뀌는 환경에서 남들이 내 코드를 함부로 망가뜨리지 못하게 막는 것임 코드 소유권이 없고("공유 소유권"이라는 완곡어법) 모두가 모든 것을 바꾸라고 독려받는 문화에서 "망가뜨림"은 사회적 구성물임. 고치도록 강제되어야만 "망가뜨린 것"이 됨 유닛 테스트가 완벽한 완화책인 이유: 쓰기 쉽고, 싸고 빨라서 커밋 게이트(lint, test 등 머지가 가능한지 테스트하는 것)로 걸어도 반발이 적고, 조직이 품질에 지불할 의향이 있는 딱 그만큼의 비용으로 "품질" 체크박스를 채워주며, 남의 테스트를 작성자와 상의도 없이 지우거나 억지로 통과하게 고치는 것은 너무 볼썽사나운 일이라 결국 테스트를 통과시키거나 작성자와 대화해야 하는 메커니즘이 생김 이것이 경영진과 프로그래머 모두 만족하는 균형점이며 테스트 없이 정말 빠르게 달리다가 서로가 낸 피해를 복구하느라 허둥대는 것보다는 실제로 더 빠르게 움직이게 해줌 테스트가 코드 크기를 대략 두 배로 만드는 이유도 여기서 나옴 — 같은 코드를 두 번 쓰는 셈이기 때문임. 첫 번째로...

Read Entire Article