면접 코딩 챌린지에서 RSpec 테스트 실패를 겪은 이야기

How trustworthy is Rspec? How I Fell into an RSpec Pitfall - Chenxu Zhao

작성자
Ruby Australia
발행일
2025년 10월 18일

핵심 요약

  • 1 RSpec 테스트가 `SystemExit`로 인해 중간에 종료되어 모든 테스트가 실행되지 않는 문제 발생.
  • 2 `initialize` 메서드 내 `super` 호출과 광범위한 `rescue ArgumentError`가 `exit(1)`을 유발하여 RSpec의 비정상 종료를 초래.
  • 3 RSpec 테스트의 신뢰성을 높이기 위해 테스트 순서 무작위화, 터미널 종료 코드 표시, CI/CD 설정 도입을 권장.

도입

발표자는 면접 코딩 챌린지에서 겪었던 RSpec 테스트 실패 사례를 공유하며, Ruby 개발자들이 흔히 겪을 수 있는 미묘하지만 치명적인 문제점을 조명합니다. 그는 10년간 Ruby, Elixir, Python을 사용했으며, 최근에는 정적 타이핑, 인터페이스, 에러 핸들링 및 네이티브 동시성 지원을 위해 Go 언어로 전환한 경험이 있습니다. 이번 발표는 RSpec의 예상치 못한 동작으로 인해 코딩 챌린지에서 발생한 오류의 원인과 이를 방지하기 위한 실질적인 해결책을 제시하는 데 중점을 둡니다.

발표자는 코딩 챌린지 제출 전, Rubocop의 제안에 따라 initialize 메서드에 super 호출을 추가했습니다. 이 작은 변경 후 로컬에서 RSpec을 실행했을 때는 모든 테스트가 통과하는 것처럼 보였습니다. 그러나 면접관으로부터 코드에 여러 오류가 있다는 피드백을 받았고, 특히 복리 이자 계산 부분에서 문제가 발생했다고 전달받았습니다.

문제의 원인 분석

문제의 원인을 파악하기 위해 발표자는 다음과 같은 과정을 거쳤습니다.

  • RSpec의 불일치한 동작: 특정 파일만 지정하여 RSpec을 실행했을 때는 오류가 명확히 나타났지만, 전체 RSpec을 실행했을 때는 오류가 보고되지 않았습니다. 이는 RSpec이 모든 테스트를 실행하지 않았다는 것을 의미했습니다.

  • SystemExit 문제: 구글링을 통해 RSpec 코어 저장소에서 “Unhandled SystemExit causes later specs to silently not run”이라는 10년 이상 된 이슈를 발견했습니다. RSpec은 SystemExit가 코드 내부에서 발생했는지, 사용자가 Ctrl+C로 종료했는지 구분할 수 없어, 내부에서 발생한 SystemExit도 테스트 실행을 조용히 중단시키는 것으로 밝혀졌습니다.

  • 코드의 문제점: 발표자의 CLI 애플리케이션 main 함수에는 ArgumentError를 광범위하게 rescue하고 exit(1)을 호출하는 로직이 있었습니다. initialize에 추가된 super 호출이 인자를 받지 못해 ArgumentError를 발생시켰고, 이 에러가 rescue 블록에 잡혀 exit(1)을 실행함으로써 RSpec 테스트 스위트 전체를 중간에 종료시켰던 것입니다.

해결책 및 권장 사항

이러한 문제를 방지하고 테스트의 신뢰성을 높이기 위해 발표자는 다음과 같은 방안을 제안했습니다.

  • RSpec 테스트 순서 무작위화: RSpec 설정에서 config.order = :random을 설정하여 테스트 파일 로드 순서를 무작위로 지정함으로써, 특정 순서에 의존하는 숨겨진 오류를 발견할 수 있습니다.

  • 터미널 프롬프트에 종료 코드 표시: 셸 프롬프트에 $? 또는 $LASTEXITCODE와 같은 종료 코드를 항상 표시하도록 설정하여, RSpec 실행 후 비정상적인 종료 코드를 즉시 인지할 수 있도록 합니다.

  • CI/CD 파이프라인 활용: GitHub Actions와 같은 CI/CD 도구를 사용하여 코드를 푸시할 때마다 자동으로 테스트를 실행하고, 실패 시 명확한 피드백을 받아 문제를 조기에 발견할 수 있도록 합니다.

발표자는 Rubocop의 제안이 의도치 않게 RSpec의 취약점을 드러냈다고 언급하며, AI를 활용하여 RSpec 코어의 오래된 이슈를 해결할 수 있을 것이라는 의견을 덧붙였습니다.

결론

이번 발표는 RSpec이 `SystemExit`를 적절히 처리하지 못하여 테스트 실행이 불완전하게 종료될 수 있다는 중요한 문제점을 부각시켰습니다. 이는 로컬 환경에서 모든 테스트가 통과한 것처럼 보이더라도 실제로는 숨겨진 오류가 존재할 수 있음을 보여줍니다. 발표자가 제시한 테스트 순서 무작위화, 터미널 종료 코드 표시, CI/CD 도입과 같은 실천적인 방안들은 개발자들이 이러한 함정을 피하고 테스트의 신뢰성을 확보하는 데 필수적입니다. 궁극적으로 개발자는 테스트 도구의 동작 방식에 대한 깊은 이해를 바탕으로 견고한 개발 워크플로우를 구축해야 할 것입니다.

댓글 0

댓글 작성

0/1000
정중하고 건설적인 댓글을 작성해 주세요.

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!