회고 | 거대한 패키지의 TDD(Test-driven Development) 실패기

주싱·2021년 12월 31일
0

더 나은 테스트

목록 보기
4/16
post-custom-banner

요즘 저희 팀은 내년에 오픈할 글로벌 우주지상국 네트워크 구축에 힘을 쏟고 있습니다. 저는 그 중에서 지상국을 구성하는 다양한 시스템들의 제어 모듈 개발을 담당하고 있습니다. 시스템 제어 모듈은 시스템 당 제어 모듈 하나가 독립적으로 개발되는 구조를 가지는데요. 시스템 별로 통신 프로토콜이 모두 다르지만 제어하는 구조가 유사해서 공통 모듈을 지속적으로 추출하고, 통신 프로토콜에 종속적인 메시지 구성 및 처리 기능은 개별적으로 개발하는 방향으로 개발을 진행하고 있습니다. 이번주는 새로운 시스템의 제어 모듈을 개발하기 시작했는데요. 개발을 시작하며 문득 TDD를 시도해 보고 싶어 졌습니다. TDD라고 해서 거창한 것을 시도한 것은 아니고 일단 ‘테스트 코드를 먼저 작성하자’를 실천해 보기로 합니다. 그리고 테스트 코드를 먼저 개발하면 어떤 차이점이 있는지 느껴보기로 결단(?) 했습니다.

TDD 실패 프로세스

이제 호흡을 가다듬고 생애 첫 TDD를 시작해 봅니다.

  1. 호기롭게 JUnit 테스트 파일을 먼저 만듭니다. 그리고 분석한 통신 프로토콜을 따라 테스트 함수 하나를 만들기 시작합니다.
  2. 시작부터 난관에 부딪힙니다. 일단 테스트 코드를 만들려고 하니 실제 제어 기능을 담당하는 클래스 참조가 없습니다.
  3. 그래서 일단 참조할 수 있도록 클래스를 정의하고, 내부의 public 함수들의 시그니처만 정의해 두면 되겠다고(세부 구현은 나중에 하고) 생각했습니다.
  4. 클래스를 만들려고 보니 기존에 작성한 다른 시스템 제어 클래스가 보입니다. 어짜피 동일한 인터페이스를 구현할 것이기 때문에(인터페이스를 Implements 하여) 반복된 코딩을 줄일 수 있다고 생각하고 기존 코드를 복사해 왔습니다. (여기서 부터 뭔가 잘못된 것 같습니다)
  5. 기존 코드를 복사해 놓고 클래스 이름 앞에 붙는 시스템명 Prefix를 현재 시스템 이름으로 바꾸었습니다. 그리고 제어 클래스 내부에서 참조하는 다른 클래스들의 이름도 현재 시스템 이름에 맞도록 바꾸었습니다. 참조 변수의 이름을 바꾸었더니 빨간 색이 마구 보이기 시작합니다. 당연히 제어 클래스가 사용하는 다른 참조들은 정의되어 있지 않기 때문입니다.
  6. 여기서 부터 참조의 참조를 따라가며 4~5단계를 반복하며 코드를 수정해 나가기 시작했습니다. 한참을 그렇게 했습니다.
  7. 분명 시작은 JUnit 테스트 함수 하나를 만드는 것이었는데, 퇴근할 시간이 되어가는데 테스트 실행은 물론이고 빌드 조차 제대로 안되는 코드 작성이 쭉이어졌습니다.
  8. 무척 지치고 힘이 빠지더라구요. 이건 아니다 싶어서 일을 잠시 멈추었습니다. 그 때 까지 커밋을 하나도 하지 못했습니다. 뭔가 분명 잘못되었다는 직감이 들었습니다. 그래서 회고를 해봐야 겠다고 생각했고 이글을 쓰게 되었습니다.

빠른 실패

돌아보니 저는 작은 테스트 함수 하나를 작성하려 하다가 테스트에 필요한 거대한 패키지 전체를 한 번에 정의하려는 실수를 하고 있었습니다. 그건 저로 하여금 몇 시간이 지나도 테스트할 수 없고, 빌드도 되지 않는 코드를 끈질기게 붙잡고 있도록 했고, 거의 하루 종일 아무런 성취도 만족도 이루지 못하게 했습니다.

짧은 주기의 피드백

오늘 하루를 스스로 돌아보았습니다. 저는 별 다른 생각 없이 다음과 같은 전략을 가지고 코드를 작성했더라구요.

  • 한 번의 호흡으로 전체 패키지를 구현하고 테스트하려 했습니다.
  • 테스트 케이스의 입력과 출력에 집중하는 대신, 유사한 구조의 기존 코드를 복사하고 빌드되게 만드는데 집중했습니다.

다음 주기의 교정

그래서 아무생각 없이 실행하던 전략을 아래와 같이 교정하고 다시 동일한 패키지의 TDD에 도전해 보기로 합니다. 어설픈 TDD라도 성공하는 날에 성공기를 다시 정리해 보겠습니다. (제발!)

  • 작은 호흡으로 패키지의 일부가 먼저 빌드되고, 테스트 될 수 있도록 코드 영역을 쪼개어 분할 정복해야 겠습니다.
  • 테스트 케이스의 입력과 출력을 다시금 분명히 정의하고, 테스트 입력에 대한 출력을 확인하는데 집중해야 겠습니다.

나에게 필요한 것

개발자로서 오늘 하루의 삶은 무척 불만족스러웠습니다. 커밋 하나, 테스트 하나 하지 못하고 단지 빌드가 성공하는 코드를 좀비처럼 쫓아 일한 것 같습니다. 사실 큰 덩어리를 쥐고 있는 모습은 개발 전 영역에서 은연중에 나타나는 저의 나쁜 습관인 것 같습니다. 그래서 요즘 부단히 작게 생각하려고 많은 노력을 하고 있는데(커밋 주도 개발, 브랜치 주도 개발 등) TDD를 처음하다 보니 제 본성이 또 나왔나 봅니다. 다시 한번 되뇌입니다.

“내가 행복하게 하루를 보내기 위해서는 크고 복잡한 요구들을 여러 작은 조각들로 나누어 단계적으로 정복해 나가야 한다. 그래야만 나는 오늘 하루를 마치며 완성되지 못한(완성되고 있는) 1개의 시도가 아니라, 완성된 N개의 작은 성취와 여러개의 만족을 얻을 수 있다. ”

큰것을 작은 것으로 쪼개어 다루고, 하루에 작은 여러개의 만족을 자기에게 선물합시다. 그것이 우리가 빠르게 성취하고, 여러개의 만족을 얻는 코드 작성을 하는 지름길이란 생각이 듭니다.

profile
소프트웨어 엔지니어, 일상
post-custom-banner

0개의 댓글