혼자 앱 만들 때 검증 — 시뮬레이터를 믿으면 안 되는 이유
검사는 통과했는데 실제 홈화면의 위젯은 깨져 있었어요. 혼자 앱을 만들며 확인한 정상·실패·복귀 장면과 출시 전 증거를 남기는 순서를 적었어요.
혼자 앱을 만들면 검증을 어디까지 해야 끝인지 알려 주는 사람이 없습니다. 그래서 저는 오랫동안 "검사 통과"를 끝이라고 읽었어요. 그러다 한 번 크게 데였습니다.
검사는 전부 초록불이었어요. 일정도 만들어졌고 앱 안 미리보기 속 위젯도 멀쩡했고요. 다 됐다 싶어서 실제 휴대전화 홈화면을 열었는데, 위젯 높이만큼 큰 빈 공간이 덩그러니 남아 있더군요.
컴퓨터 안에서 본 화면과 사용자가 매일 보는 화면이 달랐던 겁니다. 코드가 맞는지 확인하는 검사, 앱 안의 미리보기, 운영체제가 직접 그리는 실제 위젯은 서로 다른 길을 지나가거든요. 한 곳의 통과를 다른 곳의 통과로 읽어 버리면 마지막 장면은 아무도 본 적 없는 상태로 출시됩니다.
혼자 만들 때 제일 위험한 말은 "이 정도면 됐겠지"예요. 사람이 부족해서가 아닙니다. 통과를 증거로 바꿔 주는 사람이 만든 사람과 같은 한 명이기 때문이죠. 만든 사람은 의도한 길을 너무 잘 알아서, 사용자가 엉뚱한 데를 누르는 순간을 그냥 지나칩니다.
기능 하나에 장면 셋을 적어 둡니다
정상 장면은 쉬워요. 로그인하고, 일정을 추가하고, 위젯에서 확인하는 길이니까요. 그런데 제품의 신뢰는 정상이 아니라 실패와 복귀에서 갈립니다.
일정 추가라면 통신이 끊긴 상태에서 저장을 눌렀을 때 같은 일정이 두 개 생기지 않는지 봐야 하고, 로그인이라면 계정 전환을 시작했다가 취소했을 때 이전 계정으로 안전하게 돌아오는지 봐야 하고요. 로그아웃은 앱 화면만이 아니라 홈화면과 알림에서도 이전 정보가 사라지는지까지 봐야 합니다.
저는 기능 이름 옆에 이렇게 세 문장을 적어 둡니다.
"정상: 일정이 앱과 위젯에 같은 시간으로 보여요."
"실패: 통신이 끊겨도 같은 일정이 두 번 생기지 않아요."
"복귀: 다시 연결하면 한 번만 저장되고 화면이 맞아져요."
셋 중 하나라도 제 눈으로 직접 못 봤으면 완료가 아니라 확인 필요입니다. 코드에 처리 문장이 들어 있다는 사실과 사용자가 보는 결과는 별개의 일이거든요. 이 차이가 왜 중요한지는 기능보다 신뢰가 먼저인 이유에 더 자세히 적어 뒀어요.
개수가 맞는 것과 화면이 맞는 것
자동 검사는 세는 걸 잘합니다. 이미지 파일 수, 번역 키 수, 일정 레코드 수처럼 규칙으로 쓸 수 있는 건 빠르고 정확하게 잡아 줘요. 문제는 개수가 맞아도 짝이 틀릴 수 있다는 겁니다. 표지 이미지와 설명이 서로 바뀌어 붙어도, 오늘 위젯에 내일 일정이 들어가도 항목 수는 똑같거든요.
그래서 구조 검사가 통과한 다음에 표본을 직접 엽니다. 한 장만 보라는 뜻은 아니고요, 위험한 종류마다 하나씩 봅니다. 빈 상태, 긴 제목, 여러 날에 걸친 일정, 계정이 바뀐 상태, 삭제 직후. 서로 다른 실패를 대표하는 장면을 골라 두는 거죠.
숫자가 예상과 다를 때는 자동 검사도 제 눈도 바로 믿지 않습니다. 같은 대상을 세었는지부터 확인해요. 화면에 보이는 카드 수와 데이터의 일정 수가 다를 수 있고, 반복 일정 한 규칙이 여러 회차로 펼쳐지기도 하니까요. 무엇을 한 건으로 셌는지가 맞아야 비교가 성립합니다.
실기기가 아니면 아예 못 보는 것들
첫째는 위젯입니다. 크기, 빈 상태, 새로고침, 로그아웃 뒤 정리, 계정 전환. 위젯은 앱 바깥에서 운영체제가 다시 그리기 때문에 앱 화면과 다르게 나올 수 있어요. 이 별도 경로가 실제로 어떻게 생겼는지는 위젯 하나가 오래 걸린 이유와 위젯 설정 가이드에 나눠 적었습니다.
둘째는 알림. 앱이 열려 있을 때와 닫혀 있을 때가 다르고, 잠금화면에 제목이 어디까지 보이는지도 다릅니다. 이미 지나간 일정이 뒤늦게 울리지 않는지도 봐야 하고요. 발송 기록만 봐서는 사용자가 실제로 받은 문장을 알 수 없습니다.
셋째는 권한과 계정이에요. 처음 허용할 때, 거절했을 때, 나중에 설정에서 허용했을 때가 전부 다릅니다. 이미 한 번 선택한 동의창이 또 뜨지는 않는지, 계정 전환을 취소했는데 이전 화면이 남지는 않는지도 같이 봅니다.
넷째는 결제. 구매 성공만 보면 안 되고 취소, 복원, 다시 누르기, 이미 가진 상품을 또 열었을 때의 문장까지 확인해야 해요. 결제의 가장자리에서 배운 건 결제를 붙이며 배운 것과 앱스토어 심사에서 배운 것에 적어 뒀습니다.
증거를 남기는 법, 그리고 못 본 것을 남기는 법
"봤어요"만 적어 두면 다음 버전에서 뭘 다시 봐야 하는지 알 수가 없습니다. 장면 이름, 기기 종류, 앱 버전, 결과, 캡처를 짧게 남기세요. 민감한 일정과 계정 정보는 캡처하기 전에 가려야 하고요. 화면을 흐리게 덮었다고 원본 파일까지 안전해지는 건 아니니 공유 범위도 확인합니다.
모든 기기와 모든 조합을 혼자 볼 수는 없어요. 그래서 위험 순으로 자릅니다. 실패하면 남의 정보가 보이는 장면, 돈이 중복으로 빠지는 장면, 사용자가 지운 게 되살아나는 장면, 앱을 아예 못 쓰게 되는 장면. 글자 간격과 작은 애니메이션은 그다음이에요.
2026년 8월 데이리플 App Store 공식 설명에는 공유 일정·할 일·기념일, 관계별 공간, 알림, 홈화면 위젯, 서로 다른 휴대전화 지원이 적혀 있습니다. 공식 페이지의 문장 하나하나가 곧 검수 항목이에요. 양쪽 기기에서 같은 일정이 보이는지, 관계별 공간이 섞이지 않는지, 위젯이 갱신되는지를 확인하지 못했다면 설명에 적혀 있다는 이유만으로 검증된 게 아닙니다.
아이폰에서는 확인했는데 갤럭시 실기기를 못 봤다면 "교차 기기 통과"가 아니라 "아이폰 확인, 갤럭시 미확인"이라고 적으세요. 그래야 다음에 같은 장면을 이어서 볼 수 있고, 공식 설명을 실제 결과로 착각하지 않습니다. 미확인은 나쁜 점수가 아니라 증거의 빈칸이에요.
되돌리기 어려운 것부터 본다
첫 번째는 남의 정보가 보이는 문제입니다. 로그아웃 뒤 위젯, 계정 전환 취소, 공간을 나간 뒤의 일정처럼 공개 범위가 줄어드는 장면을 제일 먼저 봐요. 한 번 노출된 정보는 다음 업데이트로 완전히 되돌릴 수가 없거든요.
두 번째는 돈과 데이터. 결제를 두 번 누른 경우, 복원이 안 되는 경우, 삭제한 일정이 돌아오는 경우입니다. 화면이 조금 흔들리는 문제보다 사용자가 실제로 잃는 게 있는 문제가 먼저죠.
세 번째는 핵심 약속이에요. 공유 캘린더라면 한쪽의 추가·변경·삭제가 다른 쪽 앱과 위젯에 제대로 보이는지 확인합니다. 일정 앱인데 이 흐름이 틀리면 장식 기능이 아무리 매끈해도 소용없어요.
마지막이 표현과 미세 동작입니다. 오탈자와 간격도 고쳐야 하지만 앞의 위험들과 같은 줄에 놓지는 않습니다. 혼자서는 시간을 무한히 쓸 수 없으니까요. "다 봤다"고 말하는 것보다 위험 순서대로 무엇을 봤고 무엇을 못 봤는지 남기는 편이 정직합니다. 미검증 목록은 실패 보고가 아니라 다음 버전의 출발점이에요.
짧은 일정만 시험하면 안 보이는 것
"가족 식사"처럼 짧은 일정만 넣어 보면 실제 사용에서 나는 잘림을 못 봅니다. 장소와 준비물이 줄줄이 붙은 긴 제목을 넣고 앱, 알림, 작은 위젯에서 어디까지 보이는지 확인하세요. 잘린다는 사실 자체보다 앞부분만 보고 다른 약속으로 오해하지 않는지가 중요해요. 시험값에 실명이나 건강 정보 같은 걸 쓰지 말고 가상의 문장을 쓰는 것도 잊지 마시고요.
자정을 넘는 일정과 여러 날에 걸친 일정도 따로 봐야 합니다. 앱에서는 하나로 보이는데 위젯에서는 날짜마다 중복되거나 마지막 날이 통째로 사라질 수 있거든요. 항목 수만 세지 말고 시작일·중간일·종료일의 모양을 각각 캡처하세요. 한 화면이 멀쩡하다고 전체 기간을 통과 처리하면 안 됩니다.
저장 버튼을 눌렀는데 화면이 멈춘 상황도 마찬가지예요. 사용자는 버튼을 또 누르거나 앱을 닫았다 엽니다. 이때 일정이 두 개 생기지 않는지, 사실은 첫 저장이 성공했는데 실패 문구만 보인 건 아닌지 확인해야 해요. 실패 메시지를 봤다는 사실과 저장되지 않았다는 사실은 다릅니다. 결제와 초대도 같은 방식으로 봅니다. 응답이 늦을 때 다시 눌러 보고, 상품이나 멤버가 중복되지 않는지, 취소하면 원래 상태로 돌아오는지. 정상 흐름의 마지막 화면보다 실패한 뒤 제자리로 돌아오는 과정이 제품의 안전성을 훨씬 잘 보여 줍니다.
제가 오래 잘못 알고 있던 것
"시뮬레이터에서 되면 실기기에서도 된다." 앱 안의 기본 흐름은 비슷하게 확인할 수 있는 게 맞아요. 그런데 위젯, 알림, 권한, 결제, 백그라운드 복귀는 실제 환경에서 다르게 나옵니다. 그렇다고 시뮬레이터가 쓸모없다는 말은 아니고요. 반복 개발은 시뮬레이터로 빠르게 하고 경계 장면은 실기기에서 끝내는 역할 분담이라고 보시면 됩니다.
"테스터가 많으면 검증은 충분하다." 열 명이 봤어도 열 명 다 정상 로그인만 했다면 로그아웃 뒤 위젯은 아무도 본 사람이 없는 겁니다. 인원 수가 아니라 어떤 장면을 실제로 봤느냐가 중요해요. 뒤집어서 혼자 봤으니 부족하다는 뜻도 아닙니다. 혼자라면 장면 목록을 더 명시적으로 남겨야 할 뿐이죠.
"자동화 통과는 객관적인 증거다." 검사가 확인하도록 짜인 범위 안에서만 증거입니다. 화면의 짝이 맞는지, 잠금화면에 뭐가 노출되는지, 손가락으로 취소한 뒤 상태가 어떤지는 검사 범위 밖일 수 있어요. 통과 문구 옆에 무엇을 확인한 검사인지 같이 적어 두세요.
"출시 직전에 발견하면 바로 고치는 게 책임감이다." 원인이 재현되지도 않은 상태에서 급하게 고치면 심사 범위와 위험만 커집니다. 재현 장면과 영향 범위를 먼저 남기고, 개인정보·결제·데이터 손상처럼 지금 당장 막아야 하는 문제인지 판단하세요. 모든 발견을 같은 속도로 고치는 게 책임은 아닙니다.
체크리스트가 오히려 눈을 가릴 때
체크리스트를 완료 표시 모으기로 쓰면 "봤다"의 의미가 흐려집니다. 로그인 항목 하나에 성공·실패·취소·복귀가 전부 뭉뚱그려져 있을 수 있잖아요. 체크박스는 기능명이 아니라 사용자 장면으로 쪼개야 합니다.
이전 버전의 통과를 그대로 가져오는 것도 위험해요. 관련 코드가 바뀌었거나 운영체제가 올라갔으면 다시 봐야 하니까요. 반대로 아무 관련 없는 장면까지 매번 전부 반복하면 지쳐서 정작 중요한 검수를 대충 하게 됩니다. 변경된 경로와 위험한 고정 경로를 구분하는 게 현실적인 QA예요. AI에게 어디까지 맡길지는 AI에게 맡기면 안 되는 일에, 비개발자가 제품을 만들며 겪은 건 코딩보다 어려웠던 것에 이어집니다.
남는 질문들
기기가 한 대뿐이면요? 그 기기에서 로그아웃, 계정 전환 취소, 빈 상태, 알림, 위젯을 반복해서 보고, 확인 못 한 다른 운영체제는 미검증으로 남기세요. 보지 않은 장면을 통과로 적지 않는 것이 먼저입니다.
스크린샷만 있으면 증거가 되나요? 화면 결과의 증거는 되지만 동작 전체를 증명하지는 못해요. 버전과 기기, 어떤 순서로 그 화면까지 왔는지를 같이 남겨야 재현이 됩니다.
자동화 검사에는 어디까지 맡기나요? 문법, 파일 존재, 정해진 데이터 규칙, 반복 가능한 흐름까지요. 짝의 의미, 실제 위젯의 모양, 잠금화면 정보 노출, 취소 뒤 흐름이 자연스러운지는 사람이 봐야 합니다.
그럼 언제 "출시 완료"라고 말할 수 있나요? 빌드나 심사 통과만으로는 부족합니다. 공개 설명에 적힌 핵심 기능과 위험한 실패 장면을 실제 기기에서 확인했고, 못 본 조합은 미검증으로 남겨 뒀을 때 — 그때 비로소 현재 범위에서의 완료라고 말할 수 있어요.