PHP 미드레벨 테스트 및 코드품질 기술면접
새 면접Q. PHPUnit을 사용하여 외부 API 호출이 포함된 서비스 클래스를 테스트할 때, 실제 API를 호출하지 않고 테스트하는 방법을 설명해주세요. Mock, Stub, Spy의 차이점과 각각을 사용하는 적절한 시나리오를 포함해서 답변해주세요.
테스트 더블(Test Double)의 종류와 각각이 검증하는 대상이 무엇인지 생각해보세요.
Mock은 메서드 호출 여부와 호출 횟수, 인자 등 행위를 검증하는 테스트 더블로, 외부 의존성과의 상호작용을 확인할 때 사용합니다. Stub은 미리 정의된 값을 반환하도록 설정하여 테스트 대상 코드의 로직만 검증할 때 사용하며, 호출 여부는 검증하지 않습니다. Spy는 실제 객체를 래핑하여 일부 메서드만 가로채고 나머지는 실제로 동작하게 하면서 호출 정보를 기록합니다. API 호출 결과에 따른 비즈니스 로직 테스트는 Stub을, API 호출 시 올바른 파라미터가 전달되는지 검증은 Mock을, 기존 객체의 특정 메서드만 감시하려면 Spy를 사용합니다. PHPUnit에서는 createMock(), createStub(), getMockBuilder()를 통해 구현할 수 있습니다.
- • Mock은 행위 검증(호출 여부, 횟수, 인자)에 사용
- • Stub은 상태 기반 테스트를 위한 미리 정의된 응답 제공
- • Spy는 실제 객체를 부분적으로 감시
- • 외부 의존성 격리를 통한 단위 테스트 독립성 확보
결제 게이트웨이, 이메일 발송, SMS 전송 등 외부 서비스 연동 코드를 실제 호출 없이 안정적으로 테스트할 때 필수적입니다.
의존성 주입 없이 하드코딩된 외부 의존성이 있는 레거시 코드를 테스트 가능하게 리팩토링하는 전략은 무엇인가요?
Q. TDD(Test-Driven Development)의 Red-Green-Refactor 사이클을 설명하고, 실무에서 TDD를 적용할 때 겪을 수 있는 어려움과 해결 방법을 제시해주세요. 특히 데이터베이스 트랜잭션이 포함된 복잡한 비즈니스 로직을 TDD로 개발할 때의 전략도 포함해주세요.
각 단계의 목적과 테스트의 범위(단위/통합), 그리고 테스트 속도와 신뢰성 사이의 균형을 고려해보세요.
Red-Green-Refactor는 먼저 실패하는 테스트를 작성하고(Red), 테스트를 통과하는 최소한의 코드를 구현한 후(Green), 코드를 개선하는(Refactor) 사이클입니다. 실무에서는 초기 설계 부족으로 인한 잦은 테스트 수정, 느린 테스트 실행 속도, 레거시 코드와의 통합 문제가 발생할 수 있습니다. 이를 해결하려면 인터페이스 기반 설계로 유연성을 확보하고, 단위 테스트와 통합 테스트를 분리하여 빠른 피드백 루프를 유지해야 합니다. 데이터베이스 트랜잭션이 포함된 로직은 Repository 패턴으로 데이터 접근을 추상화하여 단위 테스트에서는 Mock Repository를 사용하고, 통합 테스트에서는 인메모리 DB나 트랜잭션 롤백을 활용해 격리된 환경을 구성합니다. 비즈니스 로직은 도메인 모델에 집중시키고 인프라 관심사는 분리하여 테스트 가능성을 높입니다.
- • Red-Green-Refactor 사이클의 각 단계별 목적 이해
- • 단위 테스트와 통합 테스트의 적절한 분리
- • Repository 패턴을 통한 데이터 접근 계층 추상화
- • 인메모리 DB 또는 트랜잭션 롤백을 통한 테스트 격리
- • 비즈니스 로직과 인프라 관심사의 분리
새로운 기능 개발 시 요구사항을 테스트로 먼저 명세화하고, 리팩토링 시 기존 동작 보장을 위한 안전망으로 활용됩니다.
레거시 코드베이스에 TDD를 점진적으로 도입할 때, 어느 부분부터 시작하는 것이 효과적이며 그 이유는 무엇인가요?
Q. 팀에서 코드 리뷰 문화를 정착시키기 위한 구체적인 가이드라인과 체크리스트를 제안해주세요. 특히 PHP 코드의 품질을 평가할 때 중점적으로 확인해야 할 항목들과, 코드 리뷰가 단순한 결함 발견을 넘어 팀의 코드 품질을 향상시키는 방법을 설명해주세요.
기술적 측면뿐만 아니라 커뮤니케이션 방식, 리뷰 크기, 자동화 도구 활용 등을 종합적으로 고려해보세요.
효과적인 코드 리뷰를 위해서는 먼저 리뷰 단위를 작게 유지하여(200-400줄 이하) 집중도를 높이고, 자동화 가능한 부분(코딩 스타일, 정적 분석)은 PHP CS Fixer, PHPStan, Psalm 등의 도구로 처리해야 합니다. 체크리스트는 기능 요구사항 충족 여부, 테스트 커버리지와 테스트 품질, 보안 취약점(SQL Injection, XSS 등), 성능 이슈(N+1 쿼리, 불필요한 반복문), 코드 가독성과 유지보수성(SOLID 원칙, 적절한 추상화)을 포함해야 합니다. 건설적인 피드백을 위해 비판보다는 제안 형식으로 작성하고, 코드가 아닌 코드의 문제에 집중하며, 좋은 코드에 대한 칭찬도 포함시킵니다. 리뷰 과정에서 발견된 공통 패턴은 팀 코딩 가이드에 반영하고, 정기적인 회고를 통해 리뷰 프로세스 자체를 개선합니다. 페어 프로그래밍이나 몹 프로그래밍을 병행하면 사전에 품질을 높이고 리뷰 부담을 줄일 수 있습니다.
- • 작은 단위의 리뷰로 집중도 향상
- • 정적 분석 도구를 통한 자동화
- • 기능, 테스트, 보안, 성능, 가독성을 포함한 체크리스트
- • 건설적이고 존중하는 커뮤니케이션
- • 발견된 패턴의 가이드 문서화
- • 리뷰 프로세스의 지속적 개선
Pull Request 기반 협업에서 코드 품질 유지, 지식 공유, 버스 팩터 감소, 팀 전체의 코드베이스 이해도 향상에 필수적입니다.
코드 리뷰에서 의견 충돌이 발생했을 때(예: 추상화 수준, 성능 vs 가독성), 어떻게 합의점을 찾으시겠습니까?
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!