빈 화면 테스트는 검증이 아닙니다: 원하는 상태를 먼저 만들어야 합니다

앱을 실행했습니다.
스크린샷을 찍었습니다.
화면은 멀쩡했습니다.
그런데 확인하려던 던전 보드, 마감 임박 표시, 위젯 완료 상태는 하나도 없었습니다.
무엇을 검증한 걸까요?
음. 앱이 빈 상태를 잘 보여준다는 사실은 검증했습니다. 그것도 꽤 중요할 수 있습니다. 하지만 채우고 싶었던 상태를 만들지 못했다면, 그 스크린샷은 다른 질문에 대한 답입니다.
스크린샷 도구가 있다고 해서 원하는 화면까지 자동으로 도착하는 것은 아닙니다. (이동 기능이 없으면 관광도 못 합니다.)
테스트는 상태를 읽는 도구입니다
테스트나 스크린샷은 마법 카메라가 아닙니다.
어떤 상태를 만들고, 그 상태를 도구가 읽고, 기대하는 것을 확인할 때 비로소 검증이 됩니다.
의도한 상태 → 도구가 읽는 화면 또는 값 → assertion 또는 관찰 → 말할 수 있는 결론
첫 단계가 빠지면 뒤의 모든 단계는 빈 화면을 아주 정성스럽게 읽을 뿐입니다.
특히 iOS Simulator에서 도구가 실행과 스크린샷만 지원하고 탭, 입력, 화면 이동을 지원하지 않는다면 더 그렇습니다. 앱 안에서 수동으로 여러 단계를 밟아야만 나오는 상태를, 외부 도구가 우연히 만들어주길 기다릴 수 없습니다.
이때 필요한 것은 더 많은 자동화가 아니라 명시적인 상태 진입구입니다.
launch argument는 디버그용 비상구입니다
한 가지 방법은 DEBUG 빌드에서만 동작하는 launch argument를 두는 것입니다.
예를 들어 DEBUG 빌드에서 -uiTestingInMemoryStore와 -storeScreenshotFixture 인자를 함께 주면, 앱은 메모리 전용 저장소에 대표 fixture를 넣고 곧바로 원하는 보드 상태로 시작합니다.
이 방식의 좋은 점은 특별한 동작이 숨지 않는다는 것입니다.
- 인자가 없으면 일반 debug 실행과 같습니다.
- DEBUG가 아니면 컴파일되지 않습니다.
- 저장소는 메모리 전용이라 실제 사용자의 데이터를 건드리지 않습니다.
- 필요한 상태를 이름으로 호출할 수 있습니다.
여기서 “대표 fixture”가 중요합니다. 퀘스트 한 줄만 넣은 화면은 보기 좋을 수 있지만, 계층, 색 대비, 긴 문자열, 긴급도, 아이콘, 레벨, 완료 상태처럼 실제 화면에서 깨지기 쉬운 조합을 보여주지 못합니다.
빈 접시에 음식 이름만 적고 맛을 확인했다고 하면 곤란하잖아요. (전직 요리사 비유를 너무 오래 아껴두었습니다.)
fixture는 기능이 아니라 검증 장비입니다
이런 seed 코드는 제품 기능으로 자라면 안 됩니다.
앱이 실제 데이터를 정리하는 방법과 fixture가 화면을 채우는 방법은 목적이 다릅니다. fixture는 사람이 보고 확인할 수 있게 만들기 위한 장비입니다.
그래서 세 가지 경계를 지켜야 합니다.
- DEBUG에서만 컴파일합니다.
- 명시적 인자가 있을 때만 실행합니다.
- 운영 저장소와 절대 같은 데이터를 쓰지 않습니다.
자동화된 회귀 테스트로 키우고 싶다면 그때는 별도 일이 됩니다. 스크린샷 비교, artifact 보관, fixture 유지보수, 테스트 실패 기준을 새로 설계해야 합니다. 지금 필요한 것이 화면을 한 번 제대로 보는 일이라면, 임시 디버그 진입구가 더 작고 정직한 해결책입니다.
화면은 사실에서 파생되어야 합니다
알림과 위젯처럼 앱 밖의 표면까지 다루면, fixture가 만든 상태와 실제 제품의 사실도 맞아야 합니다.
예를 들어 위젯에서 퀘스트 완료를 눌렀을 때, 앱 본문과 위젯이 서로 다른 완료 사실을 갖고 있다면 멋진 스크린샷도 소용이 없습니다. 화면은 현재 사실에서 파생되어야 하고, 오래된 알림은 현재 퀘스트 사실을 기준으로 정리되어야 합니다.
테스트가 보여줘야 할 것은 “예쁜 정지 화면”만이 아닙니다. 그 상태가 어떤 사실에서 왔고, 다른 표면에서도 같은 사실을 읽는지까지 확인해야 합니다.
찍기 전에 한 번만 물어보세요
다음에 화면 검증을 시작할 때는 스크린샷 버튼보다 먼저 이것을 확인해보세요.
이 fixture가 정말 제가 보고 싶은 상태를 만들었나요?
아니라면 테스트를 더 돌리지 마세요. 먼저 상태를 만드세요.
테스트는 실행 횟수가 아니라, 읽을 수 있는 상태가 있을 때 힘을 냅니다.
다음 글도 받아보세요.
글을 끝까지 읽으셨다면, 다음 글은 받은편지함이나 RSS 리더에서 만나보세요.