객체지향 시니어 테스트·코드품질 면접

객체지향(OOP) 시니어 (7년+) 테스트 · 코드품질 5문항 조회수 6 · 2026-09-20 (일) 22:11:18
1 테스트 전략
Hard

Q. 레거시 시스템에 테스트 코드가 전혀 없는 상황에서 리팩토링을 진행해야 합니다. 테스트 커버리지를 점진적으로 높이면서 안전하게 리팩토링하기 위한 전략을 단계별로 제시하고, 특히 Golden Master Testing과 Characterization Test를 어떻게 활용할 수 있는지 설명해주세요.

기존 동작을 보존하면서 안전망을 만드는 순서를 고려해보세요.

A. 모범답안

먼저 현재 시스템의 동작을 스냅샷으로 캡처하는 Golden Master Testing을 적용하여 입출력 쌍을 기록합니다. 다음으로 Characterization Test를 작성해 현재 코드의 실제 동작(버그 포함)을 문서화하고, 이를 기반으로 안전망을 구축합니다. Seam을 식별하여 의존성을 분리할 수 있는 지점을 찾고, 해당 부분부터 단위 테스트를 추가합니다. 비즈니스 크리티컬한 경로부터 우선순위를 두어 테스트를 작성하고, Strangler Fig 패턴으로 새 코드를 점진적으로 도입합니다. 리팩토링 후에는 Golden Master와 비교하여 동작 변경이 없음을 검증하고, 점진적으로 더 세밀한 단위 테스트로 교체해 나갑니다.

핵심 포인트
  • • Golden Master Testing으로 현재 동작 스냅샷 캡처
  • • Characterization Test로 실제 동작 문서화 및 안전망 구축
  • • Seam 식별 후 의존성 분리 지점부터 단위 테스트 추가
  • • 비즈니스 크리티컬 경로 우선 테스트 및 점진적 리팩토링
답변에 넣으면 좋은 키워드
Golden Master Testing Characterization Test Seam Strangler Fig 패턴 테스트 커버리지 점진적 리팩토링
실무에서는

10년 이상 운영된 모놀리식 시스템을 마이크로서비스로 전환하거나 대규모 리팩토링을 진행할 때 필수적인 전략입니다.

Follow-up 질문

레거시 코드에서 Seam을 만들기 어려운 경우, 어떤 리팩토링 기법을 먼저 적용해야 할까요?

2 코드 리뷰
Hard

Q. 팀의 코드 리뷰 문화를 개선하려고 합니다. 단순히 버그나 코딩 컨벤션만 체크하는 수준을 넘어서, 아키텍처 품질과 유지보수성을 높이는 코드 리뷰 체크리스트를 설계하고, 리뷰어가 SOLID 원칙 위반이나 디자인 냄새를 효과적으로 발견할 수 있는 구체적인 질문 패턴을 제시해주세요.

각 SOLID 원칙별로 코드 리뷰 시 던질 수 있는 구체적인 질문을 생각해보세요.

A. 모범답안

SRP 검증을 위해 '이 클래스가 변경되어야 하는 이유가 여러 개인가?', '클래스 이름이 And, Or, Manager를 포함하는가?'를 질문합니다. OCP는 '새로운 기능 추가 시 기존 코드 수정이 필요한가?', '조건문 대신 다형성을 사용할 수 있는가?'로 확인합니다. LSP는 '하위 타입이 상위 타입의 계약을 위반하는가?', 'instanceof나 타입 체크가 과도하게 사용되는가?'를 점검합니다. ISP는 '인터페이스 구현체가 사용하지 않는 메서드를 구현하는가?'를, DIP는 '고수준 모듈이 저수준 구현에 직접 의존하는가?'를 확인합니다. 또한 Long Method, Feature Envy, Data Clumps 같은 코드 냄새 패턴을 체크리스트에 포함하고, 테스트 가능성과 Mock 의존도를 평가하여 설계 품질을 판단합니다.

핵심 포인트
  • • SOLID 원칙별 구체적인 질문 패턴으로 설계 품질 검증
  • • 코드 냄새(Code Smell) 패턴 체크리스트 구축
  • • 테스트 가능성과 Mock 의존도로 설계 품질 평가
  • • 변경 이유, 확장 방식, 계약 준수 여부 중심 리뷰
답변에 넣으면 좋은 키워드
SOLID 원칙 코드 냄새 테스트 가능성 디자인 패턴 리팩토링 아키텍처 품질
실무에서는

대규모 팀에서 코드 품질을 일정 수준 이상으로 유지하고, 기술 부채 축적을 예방하는 데 핵심적인 역할을 합니다.

Follow-up 질문

코드 리뷰에서 주니어 개발자가 SOLID 원칙 위반을 이해하지 못할 때, 어떻게 교육적으로 피드백을 제공하시겠습니까?

3 통합 테스트
Hard

Q. 마이크로서비스 아키텍처에서 여러 서비스 간 통합 테스트를 수행할 때, Contract Testing과 End-to-End Testing의 차이를 설명하고, Pact나 Spring Cloud Contract 같은 CDC(Consumer-Driven Contract) 도구를 활용한 테스트 전략을 어떻게 수립할 것인지 구체적으로 답변해주세요.

서비스 간 계약을 누가 정의하고 검증하는지, 그리고 테스트 비용과 신뢰성의 트레이드오프를 고려해보세요.

A. 모범답안

Contract Testing은 서비스 간 인터페이스 계약을 검증하는 것으로, Consumer가 기대하는 계약을 정의하고 Provider가 이를 준수하는지 독립적으로 확인합니다. E2E 테스트는 전체 시스템을 실제로 구동하여 통합 동작을 검증하지만, 환경 구성 비용이 크고 실행 속도가 느립니다. CDC 전략으로는 먼저 Consumer 팀이 Pact 파일로 기대 계약을 정의하고, 이를 Pact Broker에 공유합니다. Provider는 CI/CD 파이프라인에서 Consumer의 계약을 검증하는 테스트를 실행하여, 배포 전에 호환성을 보장합니다. 버전별 계약을 관리하고, Can-I-Deploy 도구로 배포 가능 여부를 사전 검증합니다. E2E 테스트는 핵심 비즈니스 시나리오만 선별하여 최소화하고, 대부분의 통합 검증은 빠르고 안정적인 Contract Testing으로 대체합니다.

핵심 포인트
  • • CDC는 Consumer가 계약 정의, Provider가 준수 검증하는 방식
  • • Pact Broker로 계약 공유 및 버전 관리
  • • CI/CD 파이프라인에서 계약 검증 자동화
  • • E2E 테스트는 핵심 시나리오만 최소화하고 Contract Testing 활용
답변에 넣으면 좋은 키워드
Contract Testing Consumer-Driven Contract Pact E2E Testing Pact Broker Can-I-Deploy
실무에서는

수십 개의 마이크로서비스가 독립적으로 배포되는 환경에서 서비스 간 호환성을 보장하고 배포 리스크를 줄이는 데 필수적입니다.

Follow-up 질문

Contract Testing으로 검증할 수 없는 통합 이슈에는 어떤 것들이 있으며, 이를 어떻게 보완하시겠습니까?

4 TDD
Medium

Q. TDD의 Red-Green-Refactor 사이클을 실무에 적용할 때, 테스트를 먼저 작성하는 것이 오히려 생산성을 떨어뜨린다는 팀원의 반대에 직면했습니다. TDD의 실질적인 이점을 설명하고, 특히 객체지향 설계 관점에서 테스트 우선 작성이 어떻게 더 나은 설계를 유도하는지 구체적인 예시와 함께 답변해주세요.

테스트 작성 과정에서 자연스럽게 드러나는 설계 문제와 의존성 이슈를 생각해보세요.

A. 모범답안

TDD는 테스트를 먼저 작성함으로써 클라이언트 관점에서 API를 설계하게 하여, 사용하기 쉬운 인터페이스를 만들도록 유도합니다. 테스트 가능한 코드를 작성하려면 의존성을 주입 가능하게 만들어야 하므로, 자연스럽게 DIP를 따르고 결합도가 낮아집니다. 예를 들어, 테스트에서 Mock 객체를 주입하려다 보면 구체 클래스 대신 인터페이스에 의존하게 되고, 이는 OCP와 LSP 준수로 이어집니다. Red 단계에서 실패하는 테스트를 작성하면 요구사항이 명확해지고, Green 단계에서 최소 구현으로 빠르게 피드백을 받으며, Refactor 단계에서 안전하게 설계를 개선할 수 있습니다. 초기 투자 시간은 있지만, 디버깅 시간 감소, 리팩토링 안정성, 회귀 버그 방지로 장기적 생산성이 향상됩니다.

핵심 포인트
  • • 클라이언트 관점 API 설계로 사용성 향상
  • • 테스트 가능성이 낮은 결합도와 DIP 준수 유도
  • • Red-Green-Refactor 사이클로 안전한 설계 개선
  • • 장기적으로 디버깅 시간 감소 및 회귀 버그 방지
답변에 넣으면 좋은 키워드
TDD Red-Green-Refactor 의존성 주입 테스트 가능성 인터페이스 분리 리팩토링
실무에서는

복잡한 비즈니스 로직을 구현할 때 요구사항을 명확히 하고, 리팩토링 과정에서 기능 퇴행을 방지하는 데 효과적입니다.

Follow-up 질문

TDD가 적합하지 않은 상황이나 도메인이 있다면 무엇이며, 그때는 어떤 테스트 전략을 사용하시겠습니까?

5 테스트 더블
Hard

Q. Mock, Stub, Spy, Fake의 차이를 설명하고, 각각을 사용하기 적절한 상황을 제시해주세요. 특히 과도한 Mock 사용이 테스트를 취약하게 만드는 이유와, Mock 대신 실제 객체나 Fake를 사용해야 하는 판단 기준을 구체적으로 답변해주세요.

각 테스트 더블이 검증하는 대상과 구현의 복잡도를 비교해보세요.

A. 모범답안

Stub은 미리 정의된 응답을 반환하여 간접 입력을 제어하고, Mock은 호출 여부와 순서 등 상호작용을 검증합니다. Spy는 실제 객체를 래핑하여 일부 동작만 감시하고, Fake는 실제 동작하는 경량 구현체입니다. 과도한 Mock 사용은 구현 세부사항에 의존하게 만들어 리팩토링 시 테스트가 깨지기 쉽고, 실제 통합 문제를 놓칠 수 있습니다. Value Object나 Entity는 실제 객체를 사용하고, 외부 시스템이나 느린 I/O는 Stub이나 Fake를 사용합니다. 협력 객체 간 상호작용이 중요한 경우에만 Mock을 사용하며, Repository는 In-Memory Fake를 만들어 실제 동작을 검증하는 것이 좋습니다. Mock 사용은 최소화하고, 행위 검증보다 상태 검증을 우선하며, 테스트가 구현이 아닌 인터페이스에 의존하도록 설계합니다.

핵심 포인트
  • • Stub은 입력 제어, Mock은 상호작용 검증, Fake는 경량 실제 구현
  • • 과도한 Mock은 구현 세부사항 의존으로 리팩토링 저해
  • • Value Object는 실제 객체, 외부 시스템은 Stub/Fake 사용
  • • 행위 검증보다 상태 검증 우선, Mock 사용 최소화
답변에 넣으면 좋은 키워드
Mock Stub Spy Fake 테스트 더블 상호작용 검증 상태 검증
실무에서는

외부 API, 데이터베이스, 메시징 시스템과 통합하는 코드를 테스트할 때 적절한 테스트 더블 선택이 테스트 신뢰성을 결정합니다.

Follow-up 질문

Mockist vs Classicist 논쟁에서 어느 쪽을 선호하시며, 그 이유는 무엇입니까?

댓글 0

로그인 후 댓글을 작성할 수 있습니다.

아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!