December 30, 2021
새로운 프로젝트를 시작할 때면, ‘TDD를 제대로 해보자!’ 라는 결심을 새해 다짐처럼 하곤 했습니다. 그리고 대부분의 다짐 처럼, 그리 성공적이지 못했습니다. 스펙변경/일정압박/귀찮음 등 다양한 이유로 포기하기 일쑤였습니다. 그러면서 코딩하는 매순간 마음 한켠에 불편함이 함께 자리잡게 됐습니다.
‘나중에 이 코드에서 오류가 난다면, 테스트를 작성하지 않은 탓인데…’ 하는 걱정과 ‘모두가 테스트 코드를 꼼꼼히 작성하진 않잖아… 누군가 테스트 없이 짠 코드를 고치는 내 꼴을 봐…! 그리고 쌓여있는 저 태스크들 안보여?’ 라는 자기위안이 늘 충돌하곤 했습니다.
다행히 현 직장(KCD)에서 이러한 걱정들을 조금씩 덜 수 있게 됐습니다. 프로덕트 안정성을 위해 세운 여러 initiative중, TDD를 분기 목표로 잡을 수 있게 됐습니다. 그리고 때마침 팀 리드(Ted)와 1on1 미팅에서 ‘개발 커뮤니케이션 코스트’를 주제로 이야기를 나누다 다음과 같은 조언을 받게 됩니다.
“Shortcut*에 기능 설명이 아닌 유저 스토리를 작성해보시죠!”
Shortcut: 업무관리 툴, Trello나 Jira와 비슷한 서비스입니다. Shortcut에서는 하나의 업무 단위를 Story라 표현합니다. Trello의 Card, Jira의 Issue 같은 개념입니다. 조금 더 고객향으로 사고를 전환할 수 있을 것 같지 않나요?
조언대로 Story에 유저의 여정을 쪼개 작성했습니다. 개발 관련 표현은 최대한 피했습니다.
PM, 디자이너 혹은 관련자가 이 Story를 봤을 때 충분히 이해할 수 있는 수준으로 작성했습니다.
위 원칙을 기반으로 더 촘촘한 설계를 할 수 있으리라 기대했습니다. ‘개발 커뮤니케이션 코스트를 줄이기’ 액션 아이템으로써, 기대했던 대로 기획 당시 보이지 않았던 부분들을 발견할 수 있었습니다. 코딩을 시작하기 전 미리 PM/디자이너와 논의하였고 수정할 수 있었습니다. 만약 기능에 대한 설명만 Story에 작성했다면, 개발자 외에는 이러한 허점을 잘 발견하지 못했을 부분이었습니다. 논의를 마치고 본격적인 개발에 착수했습니다. 새로운 브랜치를 만들고 시작하려는 찰나, 불편한 감정이 피어올랐습니다.
‘TDD 안할거야…?’
쓰라린 지난 기억들을 떠올리며 조금 망설였습니다. ‘그래도 시도해보자’ 마음을 다잡으며 이내 테스트 파일을 먼저 만들고 테스트를 작성했습니다. 그리고 신기하게도, 앞서 Story에 작성한 유저의 여정을 테스트 코드에 동일하게 작성하기 시작했습니다. 이게 무슨 의미일까요?
생각해보면 유저의 요구사항은 자연어로 등장합니다.
“유저들의 포스트들을 필터링 해서 보고 싶어”
이를 듣고 필요한 기능들을 생각해봅시다.
여기서 개발자라면 위 불렛 포인트들을 Task 관리 툴로 그대로 들고가서 똑같이 작성할겁니다. 여기에 조금 더 상세한 기술적 디테일을 추가 하겠죠. 그리고 당연하게 이 목록을 업무 진행 척도로 삼을겁니다. 하지만 이 티켓(숏컷이라면 스토리)를 보게될 PM이나 디자이너의 생각은 다를 수 있습니다.
일단 무슨 말인지 모를 확률이 높습니다. 개발언어는 개발자들이나 알아듣습니다. 함께 일하는 사람들은 개발자일 수도 있지만 아닐 수도 있습니다. 티켓에서 어떠한 일들이 일어나는지 협업하는 사람들과 같은 Page에서 논의가 이루어져야합니다. 그러기 위해서 유저의 여정 처럼 고차원적이고 추상화된 레벨에서 이야기를 나누어야 합니다. 우리의 제품은 결국 유저를 위해 존재하니까요.
기술 언어들만 기입돼 있다면 놓친 스펙을 발견한다거나, 더 나은 유저 경험을 제공할 방법을 찾는 등 가치있는 논의는 멀어지게 됩니다. 그럴경우 해당 티켓은 작업이 진행되는 동안 오로지 개발자 혼자만의 판단에 의존하게 됩니다. 커뮤니케이션, 피드백을 통해 얻을 수 있는 좋은 기회를 놓치게 되는 꼴이죠. 개발 진행중 개발자가 발견한 기획/설계 미스로 인해 발생하는 일정 지연, 커뮤니케이션 코스트를 생각한다면 이는 프로젝트의 큰 리스크로 이어집니다.
협업 레벨(티켓, 스토리 등)에서 알맞게 추상화된 언어(유저 여정 중심)로 이야기를 나누고 실무자들은 각자의 필드에서 전문화된 언어로 업무를 진행하면 됩니다. 마치 컴퓨터의 Low-Level에서 사용하는 언어와 High-Level에서 사용하는 언어가 다르듯, 우리의 업무도 이와 동일해야합니다. 그렇게 최적화된 커뮤니케이션으로 최선의 제품을 생산할 수 있게됩니다.
예측한 일정 안에 개발을 완료했더라도 리뷰가 길어지는 경우도 있습니다. 이때 티켓과 일치된 테스트 시나리오는 리뷰어가 보다 쉽게 컨텍스트를 파악하도록 도와줍니다. 티켓과 PR을 오갈 필요 없이 테스트 시나리오를 통해 무슨 목적으로 코드가 작성됐는지 쉽게 파악이 가능합니다. 더 나아가 단순히 코드가 동작하냐 아니냐의 수준의 리뷰를 넘어, 작업자와 동일한 컨텍스트 상에서 PR에 몰입하도록 도와주어 수준높은 리뷰를 진행할 수 있게 도와줍니다.
또한 잘 작성한 유저 여정(=테스트 시나리오)는 개발자 스스로에게도 도움이 됩니다. 개발자가 하나 이상의 프로젝트를 진행할 수도 있습니다. 혹은 많은 미팅에 참석할수도 있죠. 이때 몰입하여 코딩을 시작한다는 건 꽤나 에너지가 많이 필요한 일입니다. 이러한 컨텍스트 스위칭 과정에서 유저 여정을 읽는 것 만으로도 내가 어디까지 작업했는지 몰입하는데 상당한 도움을 줍니다. 시간이 지나 코드를 다시 살펴볼때도 동일한 효과를 누릴 수 있습니다.
그동안 저는 TDD의 정의를 좁게만 생각하고 있었습니다.
틀린 말은 아니지만 무언가 부족해 보입니다. 그저 개발자의 자기 만족을 위한 수단이자, 책임을 회피하기 위한 피난처로 TDD를 사용한 것처럼 보입니다. TDD를 지속하기 위한 강력한 동기로는 불충분 합니다. 그러다보니 그간 TDD를 쉽게 포기했던 것 같습니다.
하지만 유저 스토리 작성과 그 과정속의 커뮤니케이션 과정을 함께 떠올리자, 더이상 TDD는 단순한 코딩이라는 행위가 아님을 깨달았습니다. 유저의 여정을 작성하여 코딩으로 이를 완성 시키는 것. 그렇게 성공적인 프로덕트를 만들기 위한 과정에서 TDD가 의미를 갖는다는 것을 말입니다. 그리하여 TDD는 테스트 커버리지 숫자로 그 존재감을 드러내는 것이 아니라 프로젝트가 원활히 진행되고 생산적인 커뮤니케이션이 이루어질 때 빛을 발하는 것이었습니다.