본문으로 건너뛰기

Don't Make Me Think 원칙과 Minitest Intuitive Expectations: 직관적인 테스트 경험

Don’t Make Me Think Principle, Testing, and Intuitive Expectations

작성자
Rails Upgrade News
발행일
2025년 11월 25일

핵심 요약

  • 1 저자는 'Don't Make Me Think'(DMMT) 원칙을 API 설계와 소프트웨어 테스트에 적용하며, 개발자가 테스트 작성에 들이는 인지적 부담을 최소화해야 한다고 주장합니다.
  • 2 RSpec의 복잡한 DSL과 Minitest Assertions의 한계를 비판하며, 기존 Minitest Expectations의 'must_*'/'wont_*' 매처를 넘어선 더욱 직관적인 테스트 구문이 필요함을 역설합니다.
  • 3 새롭게 개발된 'Intuitive Expectations'는 Ruby의 일반적인 연산자와 메서드를 활용하여 체인 가능한(chainable) DSL을 제공함으로써, 테스트 코드를 더 자연스럽고 읽기 쉽게 만들어 DMMT 원칙을 완벽하게 구현합니다.

도입

본 글은 저자가 'Don't Make Me Think'(DMMT)라고 명명한 원칙이 새로운 API 설계와 소프트웨어 테스트에 어떻게 적용되는지를 탐구합니다. DMMT는 개발자가 최소한의 생각으로 코드를 이해하고 사용할 수 있도록 하는 것을 목표로 하며, 이는 '최소 놀람의 원칙'과도 연결됩니다. 특히 소프트웨어 테스트 영역에서는 이 원칙이 더욱 중요하게 작용해야 한다고 저자는 강조합니다. 저자는 TDD(테스트 주도 개발)를 실천하지 않으며, 테스트 작성을 문제 해결의 '부작용'으로 간주하여, 가능한 한 빠르고 효율적으로 테스트를 작성하고자 하는 철학을 가지고 있습니다.

테스트 프레임워크가 개발자의 테스트 작성 부담을 줄이지 못한다면 그 역할을 다하지 못하는 것이라는 저자의 관점에서, RSpec과 Minitest의 여정을 통해 ‘Intuitive Expectations’의 필요성을 설명합니다.

RSpec 비판

RSpec은 겉보기에는 멋진 Ruby DSL처럼 보이지만, DMMT 원칙을 심각하게 위반한다고 지적합니다. 다음은 주요 비판점입니다.

  • expect(actual).to be_within(delta).of(expected)와 같은 문법에서 .to의 존재 이유와 not_to를 함께 기억해야 하는 부담.

  • be_*로 시작하는 매처들의 불일치성 및 비문법적인 표현 (satisfy 매처 예시).

  • 특정 매처에서만 사용되는 .of와 같은 일회성 DSL 요소가 ‘최소 놀람의 원칙’을 위반.

Minitest Assertions의 장점과 한계

RSpec의 복잡성에 질린 저자는 Minitest Assertions의 간결함(assert something_is)에 매력을 느낍니다. 이는 DMMT 원칙의 훌륭한 예시로 평가됩니다. 그러나 다음과 같은 한계도 존재합니다.

  • assert_equal에서 예상 값(expected)이 실제 값(actual)보다 먼저 오는 ‘역방향’ 인자 순서 문제.

  • 수많은 assert_* 또는 refute_* 문장으로 인해 테스트 코드가 장황해지는 문제.

  • describe/it와 같은 스펙 스타일 테스트 작성을 선호하지만, Assertions만으로는 부족함을 느낌.

Minitest Expectations의 도입과 개선 필요성

Minitest 자체적으로 제공하는 Expectations(expect(first_name).must_equal "Jared")는 must_*wont_* 매처를 사용하여 스펙 스타일 테스트에 적합합니다. 예외 발생 여부 확인과 같은 블록 내 코드 테스트에도 유용합니다. 그러나 저자는 여전히 새로운 must_* 또는 wont_* 매처를 학습해야 하는 부담이 DMMT 원칙에 위배된다고 생각합니다. Ruby의 가장 표준적이고 명확한 언어 코드를 사용하여 테스트를 작성할 수 있어야 한다는 질문에서 ‘Intuitive Expectations’가 탄생합니다.

Intuitive Expectations 소개

Bridgetown Foundation gem의 새로운 기능인 ‘Intuitive Expectations’는 Minitest의 Expectations를 기반으로 더욱 단순하고 체인 가능한(chainable) 변형을 제공합니다. 이는 Ruby의 일반적인 연산자와 메서드를 활용하여 직관적인 테스트 구문을 구현합니다.

  • expect(some_int) != 123

  • expect(some_big_str) << "howdy" (또는 include?)

  • expect(some_bool).true?

  • expect(2..4).within?(1..6)

  • expect(food_tastes) =~ /g(r+)eat/ 체인 가능한 DSL을 통해 여러 기대를 연속적으로 표현할 수 있습니다.

  • expect(big_string).include?("foo").include?("bar").exclude?("baz")

  • expect(user).is?(:moderator?).isnt?(:admin?) 대부분의 명명된 매처는 match?not_match?처럼 ‘not’ 쌍을 가지고 있어 쉽게 유추할 수 있습니다.

활용 예시 및 확장

Bridgetown Core 팀은 기존의 Jekyll 포크 기반 테스트 스타일에서 Minitest 스펙 스타일과 ‘Intuitive Expectations’로 전환하고 있습니다. 실제 테스트 코드 예시를 통해 그 간결함과 가독성을 보여줍니다. 저자는 이 문법이 너무나 익숙하고 편리하여, JavaScript 환경에서도 Node의 내장 Assertions와 테스트 기능을 기반으로 유사한 ‘Intuitive Expectations’ 버전을 구현했습니다.

결론

결론적으로, 'Intuitive Expectations'는 'Don't Make Me Think'(DMMT) 원칙을 테스트 코드 작성에 완벽하게 구현한 결과물입니다. 이는 Minitest 스펙 스타일과 결합하여 저자가 경험한 가장 우아한 테스트 문법을 제공합니다. 개발자가 새로운 매처를 학습할 필요 없이 Ruby의 자연스러운 표현을 사용하여 테스트를 작성할 수 있게 함으로써, 테스트 작성을 더 이상 번거로운 작업이 아닌, 개발 과정의 자연스럽고 즐거운 부분으로 변화시킵니다. 이처럼 직관적인 테스트 경험은 일단 익숙해지면 다른 방식을 사용하기 어렵게 만들 정도로 강력한 이점을 제공합니다.

댓글 0

댓글 작성

댓글 삭제 시 비밀번호가 필요합니다.

이미 계정이 있으신가요? 로그인 후 댓글을 작성하세요.

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