애자일 체험 2
나의 업무방식은 3년전 애자일 코칭을 받고나서 꽤 많이 바뀌었다. 가끔 당시 적어둔 글을 보면, 무언가 할 말이 있긴한데 정리가 덜 된 느낌이 있었다. 다행히 최근에 일을 하다가 이게 중요했구나 싶은 몇가지 기억이 떠올라 적어둔다.
1. 문제 해결
나를 코칭해준 이가 제일 처음 했던 질문은 이 프로젝트를 하면서 얻고자 하는것, 개선하고 싶은 것이 무엇입니까였다. 그때 나의 대답은 하루에 5시간만 일하고 싶습니다였다. 나는, 밤새지 않고도 고객을 만족시키기, 그걸 해보고 싶었다.
옆에서 하루 5시간이라는 나의 말을 들은 팀장은 하루 4뽀모(2시간)도 하기 힘들다면서 5시간은 길어보인다는 조언을 해주셨고, 우리는 하루 6뽀모(3시간) 작업하기를 목표로 정했었다.
나는 당시 코치의 태도에서 애자일의 규칙이나 관행이 아니라 내가 가진 문제를 핵심에 놓고 있다는 느낌을 받았었다.
스크럼이나 회고 따위의 애자일 프랙티스들은 문제를 해결하기 위한 수단이고, 그들이 적절하지 않다면 현장에서 새로운 프랙티스를 만들어 낼 수도 있는것 아닌가,라는 것이 그의 일관된 주장이었다. 나는 그전에 책을 보고 이런 저런 규칙들을 따라해보려 한적이 있었는데, 아마도 이런 태도의 차이때문에 성공하지 못했던 것 같았다.
현장의 상황에 민감해지는 것. 그것이 중요했다.
그리고, 코치는 나의 목표를 달성하는 데에는 일정 추정과 테스트가 중요하다고 판단했던 것 같다.
2. 일정 추산
그 과제는 6개월짜리였는데, 대략 4개월동안 구현, 1달간 테스트, 마지막에 디플로이라는 큰 그림이 그려져있었다. 5개의 큰 요구사항들이 있었고, 각각은 2~4주 정도면 해결할 수 있을 것처럼 보였다. 이 그림을 그리던 과정은 지금은 잘 기억나지 않는다. 다만 작업 첫날 코치의 요구사항이 아주 어려웠던 기억이 난다.
코딩을 시작하는 날이었는데, 늘 하던 것 처럼 문제를 읽고 대략 구상을 한 다음 곧바로 작업을 시작하려 했다. 그때 옆에서 보고있던 코치가, 앞으로는 작업전에 요구사항을 쪼개서 오늘안에 해결 가능한 분량을 추정해달라고 했다.
대략 2주나 4주 정도 걸릴 것 같은 문제를 여러개로 쪼개서 6뽀모(3시간)짜리 작업으로 만들어달라는 요구였다. 이게, 처음에는 꽤 어려웠다.
예를 들면, 프로젝트에 들어있던 1800개의 소스파일 중에 어떤 부분에 내가 수정할 기능이 들어있는지 알아보는데에 과연 얼마나 걸릴 것인가. 나로써는 추산을 할 수가 없었다. 혹은 추산을 하기가 싫었다. 그냥 곧바로 IDE를 열어서 소스를 보고 싶었다. 그래야 한다고 생각했다. 소스를 보지 않고 뭘 추정할 수 있지?
결국 약간의 갈등을 거쳐 나온 그날의 목표는 ‘디버깅 모드에서 트레이스해서 어느 모듈쯤에 수정할 기능이 있는지 알아내기’ 였던 것같다. 혹은 ‘IDE에서 디버깅 동작하게 하기’ 였는지도 모르겠다.
어느쪽이든 전에는 일정 추산할 때에 넣어본 적이 없는 항목이었다. 하지만 곰곰히 생각해보면 양쪽다 2시간 혹은 20시간도 걸릴 수 있는 작업들이다. 대강대강 기능만 보고 일정을 세우는 경우, 이런 것들은 어딘가 회색지대에 숨어서 일정을 늘리는 범인들이었다.
코치가 강조했던 몇안되는 규칙이었기 때문에, 6개월동안 매일 매일 뽀모도로 단위로 일정 쪼개기를 반복해야 했다. 처음에는 하기싫거나 어려웠던 뽀모도로 단위 목표설정을 반복하다보니, 내 능력치를 가늠하는 능력이 점점 좋아졌다. 이번 25분동안 내가 할 수 있는 분량이 어느정도인가 하는 것은 반복해서 추정하다보면 조금씩 잘하게 될 수 밖에 없다. 그리고 나중에는 그 자체가 꽤 즐거운 작업이 되어있었다.
왜냐하면, 목표를 설정하고나면 오늘 할 일은 이게 전부구나, 혹은, 오늘 저녁 식사 전에 이 만큼은 진도가 나가있겠구나, 라는 것이 점점 더 명확해지기 때문이었다. 오늘 하루 이 이상의 일은 하기 힘들다는 현실을 인식하게 된다고할까. 밤을 새면 더 일할 수도 있겠지만, 그러면 내일이 고달퍼질 것이었다. 그리고 그건 내 목표에서 어긋나는 방향이었다.
물론 6개월 내에 과제를 마치려면 지금 이 기능까지는 구현하고 있어야 하는데, 라는 현실적인 고민이 있긴했지만, 다행히 크게 밀리지 않으면서 대체로 하루 3시간 근무를 유지했었다. 내 작업 속도를 인지하고 있으니 상황에 따라 조금 더 하거나 조금 짧게 일하면서도 불안이 덜했다.
3. 투명함과 신뢰
프로젝트 초기의 어느날, 고객께서 요구사항 한가지를 조금 확장하고 싶다는 메일을 보내셨다. 나는 이때도 습관적으로, 이걸 어떻게 반영하면 좋을까 고민하면서 소스를 열어보려했다. 그때 코치는 나의 손을 잡으며, 잠시만 멈추세요,라고 말했었다. 그리고는 나에게 물었다.
“이 기능을 구현하는데 들어갈 일정을 추정하는데 얼마나 걸릴지 추정해주세요.”
추정의 추정이라니. 아무리 애자일도 좋지만 고객님이 이런 이야기를 어떻게 받아들일지 고민이 되었다. 긴가민가 하면서, 분석해야할 기능과 관련 소스코드들을 떠올리면서 아마도 오늘 하루 작업량(3시간)을 모두 써야 해당 기능을 구현하는데 들어갈 일정을 추산할 수 있겠습니다, 라고 말해주었다.
그러자, 코치는 이렇게 답장을 썼다.
“그 기능을 구현하는데 며칠이 필요한지 아직 모릅니다. 필요한 일정을 계산하는데 오늘 하루가 소요될 듯 합니다. 괜찮으신지요”
고객은 꽤 황당해하면서 그냥 원래대로 구현하라는 답장을 보내오셨다.
비슷한 일은 한번 더 있었는데 그때는 ‘그러면 한번 추산해보라’는 답장을 주셨었다. 분석을 해보니 일주일 정도의 추가 일정이 필요하다는 결과가 나왔고 그렇게 답장을 보냈었다. 분석을 하면서도 이게 정말 좋은 방식인지 어떤지, 나로써는 확신할 수 없었는데, 프로젝트가 끝난 후에야 이 방식의 장점을 알 수 있었다.
디플로이가 성공적으로 끝난 후, 고객사의 담당자가 우리를 찾아왔을 때, 담당자는 그전에 일했던 어떤 업체도 우리처럼 투명한 팀은 없었다면서 좋은 조건을 제시하며 내년에도 함께 일하고 싶다고 했다.
프로젝트 기간동안 우리가 무슨 일을 하고 있는지, 그게 언제쯤 끝날 거라고 예상하는지 알려준 것이 너무 좋았다고 했다. 그 일정 추정이 틀릴 수 있다는 건 자신들도 잘 안다, 그걸 문제삼지는 않는다. 진짜 문제는 투명한가, 신뢰할 수 있는가라는 것이 그분들의 이야기였다.
4. 테스트 우선
하루 단위, 궁극적으로는 뽀모도로 단위의 일정 추산과 더불어 강요받은 것이 있는데, 그건 TDD였다.
나의 코치는 구현한 기능을 손으로 돌려보고 납품하는 것을 용납하지 않았다. 하지만 나 역시 테스트를 먼저 구현하는 것이 프로젝트 후반까지도 익숙해지지 않았다. 결국은 코드의 양만 쓸데없이 늘어나는 것 아닌가, 하는 생각이 있었다.
내 생각을 바꾼 사건은 어떤 요구사항 한가지를 구현하면서 일어났다. 내가 만지던 프로그램은 여러 개의 다른 서버들과 소켓 통신을 하고 있었는데, 정해진 규칙에 따라 이 소켓들 중 어떤 녀석이 끊어지면 관리자에게 경고를 하게 되어있었다. 나에게 주어진 요구사항은 그 정해진 규칙을 ‘조금만’ 수정해 달라는 것이었다.
요구사항을 구현하는 것은 어렵지 않았지만 테스트를 위해 만든 목업서버가 소켓연결을 하지 못하는 문제가 있었다. 연결후 핸드쉐이킹이 필요했던 것 같은데, 아무튼 우리 서버와의 소켓연결 자체가 되질 않았다. 그렇다고 목업서버가 잘 안되니 실제 서버의 소스나 바이너리를 달라고 할 수도 없었다.
나는 아마도 잘 동작할 테니 그대로 가져가서 현장에서 확인해보라고 우겼고, 코치는 테스트 통과를 확인하기 전에는 고객사에 가지 않겠다고 우겼었다. 이때가 우리 둘사이의 갈등이 가장 컸던 것 같다. 조금 싸웠었나 싶다.
결국은 테스트를 하기로 마음을 돌이켰는데, 어찌해야하나 고민하며 살펴보니 소켓이 살아있는지 어떤지를 체크하는 부분에서 netstat 명령을 호출해서 그 결과를 사용하고 있었다. 여기를 건드리면 될 것 같다는 생각이 떠올랐다. 우리는 진짜 netstat 을 지우고, 그 자리에 텍스트 파일을 출력해주는 간단한 스크립트를 넣어주었다. 이제 경고를 울려야하는 소켓연결 상태, 경고를 울리지 말아야하는 소켓연결 상태를 마음대로 테스트 할 수 있었다.
지금 생각하면 너무 간단한 방법인데, 그때는 이 해결책까지 다다르는데 꽤 오래걸렸었다. 아마도 하기 싫다는 감정이 해결책을 가리고 있었던 것 같다.
결과를 보고 코치가 기뻐한 것은 당연하지만, 이때 내가 느꼈던 안도감도 너무 컸었다. 저 코드가 앞으로도 몇년 동안은 잘 동작할 거라는 게 확실해보이는 그런 느낌이었다. 나 말고 누군가가 소스를 건드리게 되어도, 저 기능만큼은 저 명확한 테스트 코드로 인해 실수를 하기 힘들 것이었다. 코드화된 명확한 스펙. 그게 테스트 코드였다. 저것만 통과되면 계약서의 요구사항을 구현한 것이 확실해지는 코드.
그때 느낀 안도감 때문에 지금도 구현할 기능이 어려워 보일 수록 테스트를 만들어보려고 하게 된다.
–
여기까지가 요즘 코딩하면서 떠올랐던 당시의 에피소드들이다. 사실 요즘 이 때의 교훈들을 계속 적용하는데 게을러지고 있었다. 이 글은 나 자신을 위한 되새김질이기도 하다. 이상.