엔지니어링··5분 읽기

오류를 내지 않는 결함

잘린 알림 문구와 랜드마크 뒤에 숨은 나무는 오류를 내지 않았습니다. 하나씩 고치는 대신 그릇을 고치고, 있는지가 아니라 보이는지를 재게 했습니다.

#품질#테스트#시각 검사#HappyBirthTown

대부분의 결함은 어딘가에 흔적을 남깁니다. 예외가 던져지고, 테스트가 빨개지고, 로그에 줄이 하나 생깁니다. 그런데 어떤 결함은 아무 흔적도 남기지 않습니다. 화면 밖으로 잘린 문장, 다른 그림 뒤에 숨은 물체 같은 것들입니다. 코드는 정상적으로 끝났고, 원하던 값은 전부 그 자리에 있습니다. 다만 사람의 눈에 닿지 않을 뿐입니다.

친구들이 함께 키운 픽셀 마을을 생일 선물로 건네는 해피버스타운에서 이런 결함을 두 번 만났습니다. 한 번은 알림 문구였고, 한 번은 친구가 심은 나무였습니다. 두 번 다 처음 떠오른 해법은 눈에 띈 것을 고치는 일이었고, 두 번 다 그것으로는 멈추지 않는다는 것을 배웠습니다.

눈으로 찾으면 셋, 자로 재면 스물일곱

화면 아래에 잠깐 떴다 사라지는 알림이 있습니다. 이 알림은 오랫동안 한 줄로 고정되어 있었습니다. 화면보다 긴 문구는 양쪽이 잘려 나갔는데, 아무 오류도 나지 않으니 그 문구를 실제로 폰에서 띄워 보기 전에는 아무도 몰랐습니다. 새 기능의 문구 길이를 재다가 우연히 걸렸습니다.

처음에는 잘린 문구 세 개를 찾았고, 그게 전부라고 생각했습니다. 그런데 소스에 있는 알림 문구를 전부 긁어 폰 폭으로 재 보니 157개 중 27개가 이미 잘려 있었습니다. 그 가운데에는 하루를 마무리하는 마지막 안내도 있었습니다. 눈으로 셋을 찾고 다 찾았다고 믿었던 셈입니다.

이런 결함은 세어 보기 전까지 늘 실제보다 적게 어림하게 됩니다. 오류가 나지 않는다는 것은 곧 아무도 세지 않는다는 뜻이고, 세지 않는 것은 눈에 띈 만큼만 존재하는 것처럼 보이기 때문입니다.

문구를 줄이지 않고 그릇을 고쳤다

스물일곱 개의 문구를 하나씩 줄이는 길도 있었습니다. 하지만 그것은 지는 싸움입니다. 스물일곱을 고쳐도 다음 기능이 스물여덟째를 데려옵니다. 문구를 쓰는 사람이 매번 폰 폭을 머릿속으로 계산해야 하는 구조라면, 언젠가는 반드시 넘칩니다.

뿌리도 문구에 있지 않았습니다. 알림 상자가 화면 가운데에서 시작하도록 짜여 있어서, 쓸 수 있는 폭이 처음부터 화면의 절반뿐이었습니다. 그래서 상자를 좌우로 펼치고, 한 줄로 끝나면 알약 모양으로, 넘치면 두 줄로 접히게 바꿨습니다. 두 소식을 가운뎃점으로 이어 붙였던 문구는 알림 두 개로 나눴습니다. 알림이 세로로 쌓이기 때문입니다.

그리고 자를 붙였습니다. 소스의 알림 문구를 전부 모아 폰 폭으로 재는 검사를 두고, 두 줄을 넘으면 빨개지게 했습니다. 그릇을 고치면 지금의 스물일곱이 사라지고, 자를 붙이면 다음의 스물여덟째가 들어오는 순간 걸립니다. 하나만 해서는 멈추지 않습니다.

섰다와 보인다는 다른 검사다

얼마 전 이 서비스의 선물은 «자라는 마을»이 됐습니다. 친구가 편지나 사진을 남기면 그 사람의 나무가 한 그루 서고, 함께 돌보면 자랍니다. 맵은 열두 개이고, 맵마다 나무 모양이 다릅니다. 기능을 다 만든 뒤 열두 맵을 하나씩 다시 열어 봤습니다.

기능은 전부 동작했습니다. 그런데 스물세 자리의 나무가 왕벚나무, 에펠탑, 관람차 같은 랜드마크 그림 뒤에 숨어 있었습니다. 막 심은 묘목은 사람 캐릭터나 이름표보다 작아서, 심은 사람조차 심은 줄 모를 정도였습니다. 자동 검사는 통과했습니다. 검사가 확인한 것은 «나무가 그 자리에 섰다»였지 «나무가 보인다»가 아니었기 때문입니다.

랜드마크를 옮기지 않고 나무 자리를 옮겼습니다. 랜드마크는 그 맵의 얼굴이고, 옮기면 맵이 맵이 아니게 됩니다. 묘목은 처음부터 사람보다 크게 키웠습니다. 그리고 «앞의 그림에 가리지 않는다»를 두 겹의 검사로 세웠습니다. 좌표로 계산하는 검사 하나, 실제로 그려진 화면에서 확인하는 검사 하나입니다. 맵이 바뀌면 둘 중 하나가 바로 걸립니다.

검사는 사람이 보는 자리에서 재야 한다

두 사례를 나란히 놓으면 같은 모양이 보입니다. 데이터는 맞았습니다. 문구는 정확했고, 나무는 정확한 좌표에 섰습니다. 틀린 것은 그 데이터가 사람의 눈에 도착하는 마지막 구간이었고, 기존 검사들은 모두 그 구간 앞에서 멈춰 있었습니다. 조용한 폴백은 조용한 거짓말이 된다에서 다룬 결함은 그래도 코드 안에서 무언가를 삼켰습니다. 이번 것들은 삼킨 것조차 없었습니다.

참여형 제품에서 이 마지막 구간은 특히 비쌉니다. 친구가 남긴 흔적이 배경에 묻히면 참여할 이유가 조용히 꺾이고, 그 꺾임은 어떤 대시보드에도 오류로 찍히지 않습니다. 기록됐다는 것과 보인다는 것 사이의 거리가 곧 기능의 일부라고 보기로 했습니다.

오류를 내지 않는 결함 앞에서 배운 것은 두 가지입니다. 사례를 고치지 말고 그 사례를 만드는 그릇을 고칠 것. 그리고 무언가가 있는지를 재지 말고, 사람이 보는 자리에서 그것이 보이는지를 잴 것. 둘 다 하고 나서야, 고친 것이 다시 돌아오지 않았습니다.