본문 바로가기

기존 코드의 버그를 수정할 때, 코드에서 '오류'를 찾아내고 그 오류를 피하도록 코드를 조정하는 습관에 빠지기 쉽습니다. 그러나 문제의 근본 원인이 설계 오류나 알고리즘 문제였다면, 코드에 플래그나 goto 문만 추가하는 것은 잘못된 접근법입니다. 근본 원인을 그대로 남겨둔 채, 이제 그 코드를 이해해야 할 다음 소프트웨어 엔지니어에게 코드를 더 이해하기 어렵게 만들었을 뿐입니다.

"내가 원래 코더였다면 이 문제를 어떻게 해결했을까?"라고 스스로에게 묻는 습관을 기르세요. 그런 다음 '백지 상태' 접근법과 실제로 눈앞에 있는 코드 간의 차이를 살펴보세요. 하지만 현실적으로 접근하세요. 당신과 작성자의 접근 방식이 다르다는 이유로 함수를 재구현하라는 뜻은 절대 아닙니다. 이 단계를 사고 실험으로 받아들이세요. 실패하는 테스트 케이스가 있습니다. 작성자가 이 케이스를 놓쳤습니다. 무엇이 그녀로 하여금 이 케이스를 놓치게 했을까요? 만약 작성자가 이 케이스를 알았다면, 그녀의 접근 방식은 어떻게 달라졌을까요? 기본적으로 작동하지만 여전히 버그가 있는 코드를 파헤칠 때 이런 유형의 질문들은 매우 소중합니다.

우리의 경우, 내부 함수에 또 다른 매개변수를 추가하고, 메인 프로시저의 3개 진입점에서 올바르게 초기화되어야 하는 또 다른 자동 변수를 추가하며, 중요한 지점에서 이 새 변수를 테스트하는 코드를 추가하는 대신, 하위 단계의 수행 순서를 변경함으로써 알고리즘을 수정할 수 있다는 것을 깨달았습니다. 그렇게 하자 추가 변수와 특수 케이스의 필요성이 사라졌습니다. 최종 코드는 원래 코드보다 훨씬 이해하기 쉬워졌으며, 첫 번째 수정 시도와는 비교도 안 될 정도입니다. 이는 우리가 올바른 방향으로 가고 있다는 확신을 줍니다. 문제를 재현하는 테스트 케이스는 원래의 (지나치게 복잡한) 수정안과 수정된 (간소화된) 수정안 모두 문제를 해결함을 증명했습니다. 이제 다른 부분을 망가뜨리지 않았는지 확인하기만 하면 됩니다.

이 수정 사항은 현장 배포(즉, 고객 사이트에 이미 설치된 버전)로 진행될 예정이므로, 세 가지 유형의 집중적인 회귀 테스트도 수행할 예정입니다. 그중 두 가지는 POSIX 표준 준수 여부를 지속적으로 점검할 것이며(버그 수정은 POSIX 함수를 구현하는 코드에 포함됨), 세 번째 유형의 테스트는 일반적인 시스템 수준 회귀 테스트입니다.

먼저 알고리즘을 고쳐라. 알고리즘이 올바르게 작동하면, 코드를 처리하라.

© 2024 Stratus Technologies.