It's just like pok    version4


버그 발생 주요 원인

 | 

새 회사에서 진행하는 프로젝트 규모가 아무래도 기존 회사에서 진행하는것보다 작다보니 버그의 발생 양상이나 대처등이 예전보다 많이 꼼꼼해졌다. 그래서 예전부터 해보고 싶었던, 버그의 진짜 원인을 고민해보기 작업을 진행하였다.(사실 이 작업을 시작한 원래 이유는, 정말 유닛테스트가 버그를 줄이는데 영향을 미치는가? 였다.)

각 카테고리를 다시 적어보자면,

  • 명시적이지 않은 기능의 미 구현
  • 외부 결과를 보여주는 과정에서, 얻어온 결과가 잘못된 경우
  • 외부 라이브러리의 잘못된 사용
  • 여러 개발자가 함께 일할때, 같은 기능을 서로 다르게 개발
  • 이벤트 처리 혹은 콜백(외부에 의한 호출)등으로 call-flow가 명확하지 않은경우
  • 여러 개발자가 함께 일할때, 변경사항이 어떤부분은 적용되고 어떤부분은 적용이 되지 않은 경우
  • 기능은 명시적인데, 설계상 발생하는 케이스를 놓쳐서 발생하는 경우

명시적이지 않은 기능의 미 구현

버그의 가장 많은 부분을 차지하는것은, 명시적이지 않은 기능에 대해 프로그래머의 임시방편적인 대처 혹은 예외처리를 명시적 기능으로 들어내지 않아 버그로 처리된 경우였다.

세부 내용을 보면, 기능을 만들때 충분히 고려했을수도 있는 내용도 있고, “지원하지 않는 기기”처럼 지원 스펙범위의 차이에서 오는 경우도 있었다.

그리고 일명, 해달라는대로 해줬는데 버그로 남은 경우도 있었다.

정석적인 문제 해결방식은 명시적이지 않은것에 대해

  • 개발단계에서 발견될수 있음을 인지하고
  • 명시적이지 않는것을 일찍 발견하여
  • 짜증내지 않고 개발의 일부로써 기능등을 명확히 만드는것이다.

유닛테스트와 연계해서 고민해볼 포인트는, 유닛테스트를 하면 기능이 좀더 명확하게 되는가? 이다. 이것은 사실인것 같다. 하나의 기능을 테스트 가능한 유닛으로 고민하다보면, 유닛(혹은 객체)간 연동이나 객체의 논리적인 부분을 좀더 살펴보게 된다. 물론 테스트 가능함에 몰입되다 보면 원래 요구사항과 전체적인 그림을 못보는 경우도 있지만 역할을 잘 정의할수록 명시적이지 않은 기능이 들어나는 경우가 많다.

외부의 오류에 의해 내부 수행 로직 흐름 변경

“외부 결과를 보여주는 과정에서, 얻어온 결과가 잘못된 경우”와 “이벤트 처리 혹은 콜백(외부에 의한 호출)등으로 call-flow가 명확하지 않은경우”등이 수행 로직 흐름이 예상한것과 다를때 발생한 오류들이다. 전자는 서버등의 리모트 컴포넌트를 의미하며 후자는 내부에서 컴포넌트간의 호출 오류다.

이 외부 흐름은 사실 런타임시에 결정되는 경우가 많아 모니터링외에 다른 좋은 방법을 모르겠다. Crosscutting-concerns로 잘 정의하는 방법도 있을테고 다른 여러 방법들도 있을텐데, 이미 이벤트를 사용하거나 외부 결과에 의존하는 설계 결정에서 사전 검출은 쉽지 않을것이다.

외부 라이브러리의 잘못된 사용

이것은 전적으로 개발자 자신의 잘못이라고 보는것이 맞겠다. 좀더 라이브러리를 잘 파악하고 사용을 했어야하는데 사실 개발을 하다보면 그렇지 못한 경우가 많다.

이 경우에는 외부 라이브러리를 잘 “고립”시켜 오류가 잘 들어나고 수정하기 쉽게 설계하는것이 좋은 개선 방향같다. (사실, 내 경우에 있어서 이런 오류는 수정하기 쉬웠다)

기능은 명시적인데 설계상 기능을 만족하지 못한 경우

설계상 오류라 뭐라 할말이 없다. 케이스가 너무 복잡해지면, 이 방법이 맞는가 고민을 해야한다.

이 케이스의 무시무시한점중 하나는, 테스트를 포기하는데 있다. 너무 많은 케이스를 커버하는 테스트를 짜기 어렵기 때문에 “만들고 기도하기”라는 악마의 유혹에 넘어가기 쉽다.

여러 개발자와 함께 개발하기에 발생하는 이슈들

이 경우에는 개발 조율자? 라는 역할이 필요하다는 결론에 도달했다. 즉 개발자를 조율하고 요구 사항 전체를 이해하고 관리하는 역할이 소프트웨어 개발중에 필요하다. 이런 역할을 아키텍쳐가 할 수도 있고 개발팀장이 할 수도 있지만, 간과하지 않고 역할을 수행하는것이 중요하다.


프로그래밍 회사