Talet에 테스트 코드를 한 번 넣어보기로 했다.
최근 보는 여러 공고에서 테스트 코드 작성 경험을 요구하기도 하고, 실제 면접에서도 테스트코드를 짜 본 적이 있냐는 질문을 받은 적이 있었기 때문이다.
사실 그동안 테스트 코드를 제대로 작성해본 경험은 없다.
기존 코드 구조를 이해하고 기능을 추가하는 것만으로도 시간이 많이 드는데, 거기에 테스트 코드까지 작성해야 한다는 생각에 부담이 커서 계속 미뤄두고 있었다.
그러다 AI의 도움을 받아서라도 한 번은 제대로 시도해보자는 생각이 들었다.
다만 개념도 모르고 코드도 이해하지 못하고 넣어두기만 하는 건 의미가 없다고 느껴서, 테스트가 무엇인지부터 정리해보고 테스트코드도 공부해보기로 했다.
공부를 시작하기 전까지는 테스트와 디버깅의 차이도 머릿속에서 꽤 모호했다.
둘 다 “버그를 잡는 과정” 정도로만 인식하고 있었는데,
정리해보면 둘은 역할이 다르다.
테스트 코드는 “이 코드는 이런 입력이 들어오면 이런 결과가 나와야 한다”는 기대를 코드로 고정해두는 방식이다.
특히 테스트의 중요한 의의는 지금 당장 잘 되는지를 확인하는 것도 있지만,
이후 구조 변경이나 리팩토링이 일어났을 때 기존 동작이 깨지지 않았음을 자동으로 보장하는 데 있다.
테스트는 흔히 다음 그림과 같이 피라미드로 설명된다고 하는데, 크게 3개로 나눌 수 있다
(더 나눈 그림도 많이 봤지만 일단 세개로...)

테스트에서 '외부 의존성 제거'
테스트에서 말하는 외부 의존성은 보통 이런 것들이다.
- 네트워크 요청
- DB 접근
- 파일 시스템
- 시간, 랜덤 값
- 다른 객체의 실제 구현
이런 것들이 섞이기 시작하면 테스트가 느려지고, 환경에 따라 결과가 달라지고, 어디서 실패했는지 알기 어려워진다.
그래서 Unit Test에서는
이 테스트의 관심사가 아닌 것들을 전부 가짜(Mock, Stub)로 치환해서 테스트 범위를 최대한 좁히는 것이다.
피라미드 구조라는 말 그대로,
UI Test는 적게, Integration Test는 중간 정도, Unit Test를 가장 많이 작성하는 것이 이상적인 구조라고 한다.
테스트 코드를 작성할 때 지켜야 할 기본 원칙들이 있다.
추가로, 테스트 코드를 작성할 때 자주 사용하는 구조 패턴도 있다.
GWT 패턴
- Given: 테스트를 위한 준비
- When: 실제 실행
- Then: 결과 검증
Triple-A 패턴
- Arrange: 준비
- Act: 실행
- Assert: 검증
👉🏻 두 패턴 모두 핵심은 “준비 – 실행 – 검증”의 흐름을 명확하게 나누는 것.
Clean Architecture 관점에서 테스트는 각 계층이 자신의 책임만 수행하는지를 검증하는 데 초점이 있다.
비즈니스 규칙과 계산 로직을 테스트한다.
외부 의존성이 없기 때문에 가장 안정적이고 중요한 테스트 대상이다.
입력이 주어졌을 때 올바른 결과 흐름이 나오는지 검증한다.
Repository는 Mock으로 주입하고, 네트워크나 UI와 분리된 상태에서 테스트한다.
실제 API 호출 여부를 테스트하지 않는다.
어떤 DataSource를 선택하는지, DTO가 Domain 모델로 올바르게 변환되는지를 확인한다.
실제 서버 호출 없이 Stubbed response를 기반으로
요청 생성, 응답 파싱, 상태 코드별 에러 처리를 테스트한다.
UI 없이 Input → Output 변환만 검증한다.
화면 상태 로직이 의도대로 동작하는지를 확인하는 역할이다.
일단 지금까지 개발된 Talet 코드에 대한 Unit Test를 Claude에게 맡겨서 한 번 생성해보려고 한다.
생성된 파일들을 한 줄씩 읽어보면서 공부해 볼 예정
다음 til에는 생성된 코드 예제와 함께 XCTest에 대해서 공부해보도록 하겠당