무언가를 계획할 때, 우리는 대개 잘 풀리는 그림을 그립니다. 새 사업을 구상하면 손님이 줄을 서는 모습을, 여행을 계획하면 날이 맑고 모든 일정이 착착 맞아떨어지는 모습을 먼저 떠올립니다. 일이 어그러지는 경우를 굳이 상상하는 것은 어쩐지 불길하고 김 빠지는 일처럼 느껴집니다. “초 치지 마라”는 말이 괜히 있는 게 아닙니다. 우리는 본능적으로, 자신이 의도한 대로 흘러가는 세계를 머릿속에 그립니다.
그런데 개발자들의 일에는 이 본능을 정면으로 거스르는 작업이 하나 있습니다. 일이 어그러지는 경우를 일부러, 그것도 체계적으로 상상해보는 일입니다.
통과하는데도 버그가 나는 이유
개발자는 코드를 만들고 나면 그 코드가 제대로 동작하는지 확인하는 또 다른 코드를 함께 작성합니다. 이것을 ‘테스트 코드’라 부릅니다1. 사람이 매번 손으로 일일이 확인하는 대신, 기계가 알아서 “이 상황에서는 이런 결과가 나와야 한다”를 자동으로 검사하게 해두는 것입니다. 물론 모든 개발자가 늘 이것을 작성하는 것은 아닙니다. 일정에 쫓겨 건너뛰기도 하고 어디까지 검사해둘지는 사람마다 팀마다 다릅니다. 다만 ‘내가 만든 것이 제대로 동작하는지 따로 확인해둔다’는 이 습관은 개발이라는 일에 꽤 깊이 자리 잡고 있습니다.
테스트를 작성할 때 가장 먼저 떠오르는 것은 ‘잘 될 때 잘 되는지’를 확인하는 일입니다. 로그인 화면이라면 “올바른 비밀번호를 넣으면 로그인이 된다”를 확인하는 식이지요. 이런 검사는 짜기도 쉽습니다. 내가 이 코드를 왜 만들었는지를 그대로 적으면 되니까요. 만든 사람의 의도가 곧 정답이라, 사실 따로 상상할 것도 없습니다.
그렇다고 이 ‘잘 되는 경우’ 검사가 시시한 것은 아닙니다. 오히려 여기에는 또 다른 쓸모가 있습니다. 소프트웨어는 한번 만들고 끝나는 것이 아니라 끝없이 고쳐지는데, 한 군데를 손보다 보면 엉뚱한 데서 멀쩡하던 것이 슬그머니 망가지곤 합니다. 잘 되는 경우를 검사하는 코드를 미리 박아두면 무언가를 고칠 때마다 그 검사를 다시 돌려 “예전에 잘 되던 것이 지금도 여전히 잘 되는지”를 단번에 확인할 수 있습니다. 사람이 매번 전부 손으로 짚어볼 수는 없으니, 기계가 그 파수꾼 노릇을 대신 서주는 셈입니다.
다만 잘 되는 경우만 검사해서는 놓치는 것이 있습니다. 이런 ‘잘 되는 경우’만으로 테스트를 가득 채우면 묘한 일이 벌어집니다. 모든 검사가 초록불을 켜며 통과하는데도, 실제로 써보면 버그가 튀어나오는 것입니다. 분명 “다 통과했다”고 하는데 왜일까요.
답은 간단합니다. 그 초록불이 증명하는 것은 “이 코드가 다 잘 된다”가 아니라, 내가 의도한 대로는 잘 된다일 뿐이기 때문입니다. 그런데 버그는 거의 언제나 내가 의도하지 않은 자리에서 태어납니다. 미처 생각 못 한 입력, 예상 밖의 상황, 설마 이러겠어 싶었던 경우. 잘 되는 경우만 검사한 초록불은 그래서 일종의 가짜 안심입니다. “전부 괜찮다”와 “내가 생각해본 데까지는 괜찮다”는 다른 말인데, 우리는 그 둘을 자꾸 혼동합니다.
내 의도가 내 눈을 가린다
그래서 노련한 개발자들은 다른 종류의 검사에 공을 들입니다. ‘잘못될 때 제대로 잘못되는지’를 확인하는 일입니다. 빈 칸을 그대로 넣으면 어떻게 되는가. 숫자를 넣어야 할 곳에 글자를 넣으면. 한가운데서 인터넷이 끊기면. 도무지 일어날 것 같지 않은 입력이 들어오면. 어떤 개발자들은 아예 순서를 뒤집기도 합니다. 코드를 짜기 전에 “이건 이렇게 동작해야 하고, 이런 경우엔 이렇게 막아야 한다”는 검사부터 먼저 써두는 것입니다.2 무엇을 만들지, 그리고 무엇이 잘못될 수 있을지를 코드보다 앞서 확실히 해두는 방식이지요.
이런 검사를 짜는 일은 앞의 것과 결이 전혀 다릅니다. 잘 되는 경우는 내 의도를 적으면 그만이지만, 잘못되는 경우는 내 의도 바깥을 상상해야 하기 때문입니다. 즉, 이 작업의 본질은 ‘내가 무엇을 생각하지 않았는가’를 생각하는 일입니다. 자기가 미처 보지 못한 곳, 스스로의 사각지대를 더듬어 찾는 일이지요. 이것이 어려운 것은 당연합니다. 내가 무엇을 생각하지 않았는가를 생각해 냈다면, 그 순간 이미 그 생각을 한 것입니다. 재미있는 역설이지요. 내가 빠뜨린 것을 떠올리는 일은 원래 내 머리만으로는 가장 하기 힘든 일 입니다.
자신이 쓴 글의 오타를 좀처럼 찾지 못하는 경험을 떠올려보면 그 어려움이 손에 잡힙니다. 분명 몇 번을 다시 읽었는데도 오타는 멀쩡히 숨어 있다가, 남에게 한 번 보여주면 단번에 들통이 납니다. 내 눈이 나빠서가 아닙니다. 내가 그 글을 쓸 때 무슨 말을 하려 했는지를 이미 알고 있기 때문입니다. 그래서 눈은 적힌 글자가 아니라 내가 의도한 문장을 읽어버립니다. 틀린 글자 위를 머릿속의 올바른 문장이 덮어버리는 것이지요. 내가 의도한 것은 바로 그 의도 때문에 내 눈에 보이지 않습니다. 잘못될 경우를 스스로 상상하기 어려운 것도 똑같은 이치입니다.
물론 잘못되는 경우부터 먼저 짜는 것이 늘 옳은 정답이라는 말은 아닙니다. 잘 되는 경우를 확인하는 것도 그 자체로 꼭 필요하고, 무엇을 먼저 점검할지는 상황마다 다릅니다. 다만 한 가지는 분명합니다. 자기가 의도한 것만 거듭 확인해서는 점검을 아무리 많이 해도 사각지대는 조금도 줄지 않는다는 것입니다.
점검의 진짜 쓸모
‘점검’이라는 행위의 본질도 여기서 다시 보게 됩니다.
우리는 흔히 점검을 ‘잘 되고 있음을 확인하는 일’로 여깁니다. 그래서 점검을 하고 나면 안심합니다. 그러나 가만히 따져보면, 이미 잘 될 줄 아는 것을 다시 확인하는 데에는 사실 별다른 정보가 없습니다. 같은 것을 백 번 확인해도 내가 몰랐던 사실은 여전히 하나도 드러나지 않습니다. 점검의 진짜 쓸모는 내가 이미 아는 것을 재확인하는 데 있지 않고, 내가 모르던 것을 들춰내는 데 있습니다. 자기가 놓쳤을 법한 자리를 일부러 골라 건드려볼 때에만, 점검은 비로소 점검다워집니다.
문제집을 푸는 일을 떠올려보면 손에 잡힙니다. 이미 풀 줄 아는 문제만 골라 몇 번이고 다시 맞히면, 채점할 때마다 동그라미가 쌓여 기분은 좋습니다. 그러나 그렇게 쌓은 동그라미는 내 실력에 대해 아무것도 새로 알려주지 않습니다. 정작 나를 키우는 것은 틀린 문제를 마주하고 오답노트를 쓰는 일입니다. 내가 무엇을 모르는지가 거기서야 비로소 드러나기 때문입니다. 잘 되는 경우만 거듭 확인하는 점검이 풀 줄 아는 문제에 동그라미를 치는 일이라면, 잘못될 경우를 들춰보는 점검은 틀린 문제로 오답노트를 쓰는 일에 가깝습니다.
이것은 우리가 무언가를 검토하는 거의 모든 순간에 해당하는 이야기입니다. 발표를 앞두고 “준비됐나” 점검할 때, 우리는 자신 있는 부분을 다시 훑으며 안심하기 쉽습니다. 그러나 정작 무너지는 곳은 늘 점검해보지 않은 자리, “설마 그건 안 묻겠지” 하고 건너뛴 자리입니다. 계획을 세울 때도 마찬가지입니다. 잘 풀리는 시나리오는 누구나 선명하게 그리지만, “어디서 어긋날 수 있을까”는 좀처럼 그려보지 않습니다. 그리고 일은 거의 언제나, 그려보지 않은 그 자리에서 어긋납니다.
알고리즘이 보여주지 않는 것
이 함정은 코드 바깥에서 더 은밀하게 작동합니다. 오늘날 우리가 보는 거의 모든 것이 우리가 좋아할 만한 것으로 미리 골라져 있기 때문입니다. 추천 알고리즘은 우리가 동의할 글, 취향에 맞는 영상, 누를 만한 것들을 끝없이 비춰줍니다. 그것은 우리 각자의 세계를 향해 쉴 새 없이 초록불을 켜는 성공 테스트와 같습니다. 보고 있으면 편안하지만, 그 편안함 속으로 내 바깥의 세계는 좀처럼 들어오지 못합니다. 이미 옳다고 여기는 것만 거듭 확인될 뿐, 내가 틀렸을 자리나 미처 몰랐던 지점은 끝내 보이지 않는 것입니다.
그래서 저는 가끔 일부러 다른 입력을 집어넣습니다. 조그만 독립서점에 가면, 겉을 종이로 싸 안의 내용을 가려둔 채 짤막한 소개 글귀 하나만 붙여 ‘책방지기가 추천하는 이번 달의 책’을 만날 때가 있습니다. 표지도 제목도 보이지 않으니, 무슨 책인지 모른 채 그 글귀 하나만 보고 고르는 것입니다. 그렇게 평소라면 거들떠보지도 않았을 분야, 또는 거부감이 드는 분야, 제가 결코 직접 고르지 않았을 책이 손에 들어옵니다. 말하자면 제 일상에 일부러 ‘실패 케이스’를 하나 던져 넣는 셈입니다. 그렇게 들어온 낯선 한 권은 알고리즘이 끝내 닿게 해주지 않았을 자리로 저를 데려갑니다. 그렇게 저는 기독교 신자가 아님에도 성경 이야기를 알아가기도 하고, 여성이 아님에도 여성사회에 대해서 생각해보기도 하며, 지지하지 않는 정치인이 살아온 삶에 대한 이야기를 봅니다. 먼 나라, 다른 인종, 생물이 겪는 문제들을 마주하고 애써 공감해보기도 하고요. 이런 과정은 때로는 시시하고, 때로는 불편합니다. 그러나 그 불편함이야말로, 제가 여태 제 의도 안에만 머물러 있었다는 증거이기도 합니다.
최악을 그려보는 일
다시 실패 테스트 이야기로 돌아가 보겠습니다. 흥미로운 것은, 이렇게 무너질 경우를 미리 헤아려둔 개발자가 오히려 더 과감해진다는 사실입니다.
무너질 자리를 한 번도 상상해본 적 없는 사람은 막연한 불안 속에서 조심조심 움직입니다. 어디가 약한지 모르니 어디를 디뎌도 불안한 것입니다. 반면 일어날 수 있는 모든 어긋남을 미리 그려보고, 그 자리마다 그물을 쳐둔 사람은 다릅니다. 무너질 곳이 이미 받쳐져 있으니, 두려움 없이 앞으로 나아갈 수 있습니다. 무너지는 경우를 상상하는 일은 그래서 비관이 아닙니다. 오히려 가장 단단한 형태의 낙관입니다. 최악을 다 헤아려 대비해둔 사람만이, 진심으로 안심하고 도약할 수 있기 때문입니다.
우리는 잘못될 경우를 떠올리는 일을 불길하게 여겨 자꾸 미룹니다. 그러나 그 ‘초 치는 상상’이야말로 정작 일이 닥쳤을 때 우리를 지켜주는 가장 든든한 준비입니다. 잘 풀리는 그림만 그리는 동안에는 보이지 않던 약한 자리들이, 무너지는 그림을 그려볼 때 비로소 모습을 드러냅니다. 그리고 우리가 손볼 수 있는 것은, 오직 우리가 바라본 자리뿐입니다.
그러니 무언가가 정말 단단한지 알고 싶다면, “이게 잘 될까”를 묻는 것만으로는 부족할 것입니다. 한 번쯤은 반대로 물어야 합니다. 이것은 어디서, 어떻게 무너질 수 있는가. 그 질문을 견뎌낸 자리만이 진짜로 믿을 만한 자리입니다.
혹시, 일을 시작하기도 전에 안 되는 상상부터 하는 부정적인 마인드를 가지라는 것이라고 생각하신다면 오해입니다. 우리가 실패를 상상하는 단계는 어디까지나 테스트 즉, 준비 단계입니다. 준비가 힘겨웠던 만큼, 우리는 실전에서 누구보다 잘 해낼 것입니다. 준비하면서 상상했던 최악의 경우의 수들이 민망해질 만큼요.
댓글 (0)
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요.