훌륭한 개발자라면 코드에 테스트를 작성해야 한다는 것을 압니다. 하지만 현실에서는 테스트가 자주 생략되거나, 대충 때우거나, 아예 시작조차 되지 않곤 합니다. 많은 개발자들이 반복적으로 빠지는 전형적인 함정들이 있는데, 이 함정들은 매번 테스트를 작성하려는 동기를 꺾어버립니다. 오늘은 그 함정 다섯 가지와 극복 방법을 살펴보겠습니다. 1. RSpec? Cucumber? Capybara? Minitest? 무엇을 써야 할까? 새 프로젝트를 시작할 때 가장 좋은 도구를 고르느라 지나치게 많은 시간을 소모하기 쉽습니다. 사실 이런 미
소프트웨어 개발 경력에서 읽은 가장 가치 있는 책 중 하나에서 배운 가장 유용한 개념이 바로 Dont Repeat Yourself(DRY)입니다. 중복 코드를 리팩토링으로 제거할 수 있다면, 더 범용적이고 안정적인 코드를 만들 수 있습니다. 하지만 코드에 DRY를 적용하기 시작하면 여러 문제에 부딪히게 됩니다. 엣지 케이스(edge case)를 제대로 처리하지 못하는 코드, 지나치게 일반화되어 읽기 어려운 코드, 심지어 찾기조차 힘든 코드가 대표적입니다. DRY를 향한 리팩토링이 항상 옳지 않다면, 대체 언제 리팩토링해야 하는 걸까
다음 프로젝트에서 rails new를 입력한 순간, 이제 무엇부터 해야 할까요? 모든 코드를 하나의 앱에 담을까요, 아니면 서비스 지향 아키텍처(SOA)를 선택할까요? RSpec을 배우기 좋은 타이밍일까요? 데이터 모델을 모두 설계하는 게 좋을까요, 아니면 몇 가지 기능을 처음부터 끝까지 동작하게 만드는 게 나을까요? 프로젝트 초기에 내려야 할 결정은 셀 수 없이 많습니다. 그래서 길을 잃고, 미루고, 답답해지다가 결국 앱을 완성하지 못하는 일이 자주 생깁니다. 이 문제는 놀랍도록 흔합니다. 정보가 가장 부족한 시점에 너무 많은
지난주에는 미루는 습관을 극복하고 새 Rails 프로젝트를 시작하는 데 도움이 되는 세 가지 원칙을 소개했습니다. 지금쯤이면 눈앞의 작업량에 압도되는 느낌은 한결 줄었을 것입니다. 하지만 여전히 어려운 선택이 남아 있습니다. 어떤 코드부터 작성해야 할까요? 인증 기능일까요? Twilio와 통신하는 부분일까요? 아니면 포럼 게시글 추천 엔진은 대체 어디서부터 손을 대야 할까요? 그렇습니다. 결국 언젠가는 실제로 코드를 작성해야 하고, 그러려면 명확한 시작점이 필요합니다. 좋은 시작점이란 무엇일까요? 먼저 몇 분 정도 시간을 내어
하고 싶은 일은 분명한데 코드가 말을 안 듣는 경험, 누구나 한 번쯤 겪어봤을 겁니다. 들여쓰기가 몇 단계나 깊어졌거나, 메서드 체이닝이 여섯 개쯤 이어져 있거나, 어딘가 비대칭스럽게 보입니다. 원인이 무엇이든, 뭔가 어색하게 느껴집니다. 그냥 무시할 수도 있습니다. 아직 작성해야 할 기능이 백로그에 산더미처럼 쌓여 있고, 사실 그렇게 심각하지 않다고요. 하지만 그건 실수입니다. 당신의 코드는 지금 무언가를 말하려 하고 있으며, 그 신호를 놓쳐서는 안 됩니다. 코드가 어색하게 느껴지는 순간을 알아차릴 줄 안다면, 소프트웨어 설계
부분 캐싱(Partial Caching)은 큰 작업 없이도 페이지 로딩 속도를 크게 개선할 수 있는 훌륭한 기능입니다. 하지만 어소시에이션(association) 중 하나에 touch: true 옵션을 빠뜨리거나, 템플릿 의존성(template dependency)이 제대로 동작하지 않으면 캐시된 부분 템플릿이 갱신되지 않는 문제가 발생합니다.더 골치 아픈 점은 개발 환경에서는 보통 캐싱이 비활성화되어 있기 때문에, 이런 버그는 스테이징에서야 발견되고 최악의 경우 운영 환경(production)에서 겨우 알아차리게 된다는 것입니다.
Ruby로 무언가를 구현해야 한다면, 이미 그 기능을 담당하는 젬(gem)이 존재할 가능성이 높습니다. 사실 하나가 아니라 열두 개쯤 존재하죠. 어떤 젬은 우아하고 기능이 풍부하며 꾸준히 관리되는 반면, 어떤 젬은 작성자가 한 번 겪은 특정 상황을 해결하려고 급조된 것입니다. 선택지가 워낙 많다 보니 올바른 젬을 어떻게 고를지가 중요한 문제가 됩니다. 이 선택은 결코 가볍지 않습니다. 프로젝트에 젬을 추가한 뒤 후회하게 되면, 되돌리는 과정이 매우 고통스럽기 때문입니다. 통계부터 확인하세요 문제를 해결해 줄 라이브러리가 필요할
Rails 개발을 하다 보면 언젠가 프로그래밍을 그만두고 싶어질 만큼 끔찍한 컨트롤러와 마주치게 됩니다. 하나의 기능에 필요한 코드가 전부 한곳에 들어 있고, 인스턴스 변수로 서로 통신하는 before_filter가 15개쯤 달려 있는데, 반드시 특정 순서로 호출해야 하고 순서가 어긋나면 코드가 폭발합니다. 그리고 필연적으로 그 컨트롤러의 테스트는 대략 이런 모습입니다: test index do get :index assert_response :success end 멋지네요. 100% 테스트 커버리지라고 할 수 있겠죠?
(필자는 이번 주 시카고에서 열리는 RailsConf에 참석 중입니다. 현장에서 필자를 발견하면 꼭 인사해 주세요! 사이드바 사진 속 나이가 지긋한 분이 바로 필자입니다.) 독자의 질문: TDD, 어디서부터 시작해야 할까? 최근 한 독자가 제 글에 댓글로 테스트에 관한 훌륭한 질문을 남겼습니다: TDD 플라이휠을 굴려야 한다는 것은 알고 있지만, TDD 자체가 너무 낯설습니다. RSpec으로 시작하기 가장 좋은 방법에 대한 조언이 있으신가요? 아니면 그냥 일단 부딪혀 보면서 배워야 하는 것인가요? 그래서 이렇게 답변했습니
필자는 TDD(테스트 주도 개발)에 대해 수없이 많은 글을 써왔습니다. 그래서 지난번 글을 거의 정확히 같은 시각에 발행했는데, 마침 David Heinemeier Hansson(DHH)이 RailsConf 기조연설에서 TDD를 언급하면서 몇 가지 질문이 들어오기 시작했습니다. DHH의 TDD에 대한 견해에 동의하시나요? 아직도 TDD를 추천하시나요? 아니라면 무엇을 해야 하죠? DHH가 말한 것들 기조연설을 놓쳤다면, DHH가 작성한 에세이가 핵심을 잘 담고 있습니다. 아마도 테스트 우선 방식은 업계 전반의 자동화된
그 거대한 if 문 덩어리가 눈앞에서 계속 쳐다보고 있습니다. 분명 단순화할 수 있을 것 같은데, 막상 손대면 비즈니스 로직이 발목을 잡죠. 예를 들어 견적서(Quote)를 만들어 판매하는 플랫폼이 있다고 해보죠. 견적서에는 여러 개의 품목(LineItem)이 담깁니다. 그런데 규칙이 좀 꼬여 있습니다. 광고(Ad) 품목은 중복으로 담을 수 있는데, 웹사이트(Website) 품목이 여러 개라면 가격을 합산해 한 줄로 표시해야 합니다. 게다가 웹사이트를 구매하려는데 견적서에 이미 광고가 5개 이상 들어 있다면, 웹사이트 가격에 20
배우고 싶은 것은 산더미인데 시간은 언제나 부족하기 마련입니다. 그나마 확보한 시간조차 다른 일들에 뺏기곤 하죠. 그래서 루비(Ruby) 지식을 꾸준히 쌓아가는 일이 쉽지만은 않습니다. 책이나 스크린캐스트도 훌륭한 학습 자료지만, 그만큼 시간과 집중력이 필요합니다. 반면 설거지, 출퇴근길, 강아지 산책 같은 시간은 지루하게 느껴질 때가 많죠. 물론 그런 순간을 그저 생각하거나 휴식하는 시간으로 보내는 것도 좋습니다. 하지만 대부분의 경우, 저는 그 지루한 몇 분을 활용해 무언가를 배우고 싶어집니다. 이럴 때만큼은 팟캐스트보다 좋
Rails 관련 블로그나 책을 읽거나 컨퍼런스 발표를 보다 보면, 모델을 더 가볍게(skinny) 만드는 방법에 대한 이야기를 자주 접하게 됩니다.이런 기법들은 분명 훌륭합니다. 모델은 언젠가 감당하기 어려울 만큼 커지고 복잡해지기 때문입니다. 하지만 정말로 모델의 역할을 영속성(persistence), 연관관계(association), 유효성 검증(validation)만으로 제한하고 싶으신가요? 대체 어느 정도의 로직까지 ActiveRecord 모델에 남겨두어야 하는 걸까요?가벼워야 하지만, 너무 가볍게는 말고Active Reco
소프트웨어를 개발하다 보면 매번 작성할 때마다 짜증 나는 코드가 있습니다. 지저분해 보이는 코드 조각, 혹은 도무지 작성 방법이 기억나지 않아 코드베이스 곳곳에서 예제를 찾아 복사·붙여넣기 해야 하는 그런 줄들 말입니다. 이런 것들이 바로 여러분의 개발 흐름(flow)을 깨뜨립니다. 그렇기 때문에 이런 부분들을 미리 인식하고, 더 편리하게 만들어 주는 것이 중요합니다. Rails 설정 파일 로딩의 번거로움 예를 들어, Rails 앱에서 커스텀 설정이 필요할 때가 있습니다. 앱 고유의 추가 설정이 필요할 수도 있고, 사용하는 라이
(이 글은 원래 제 뉴스레터에 쓴 글입니다. 이런 내용을 더 읽고 싶으시다면 뉴스레터 구독을 추천합니다!) Rails 커뮤니티는 테스트, 그중에서도 TDD(Test-Driven Development)에 대한 강한 집착으로 유명합니다. 이러한 테스트 문화는 Rails가 가진 가장 큰 장점 중 하나죠. 하지만 테스트해야 하고, 올바르게 테스트해야 한다는 압박감은 초보자에게 상당히 부담스러울 수 있습니다. 특히 테스트를 전혀 작성해 본 적 없는 환경에서 넘어온 개발자라면 TDD 학습이 더욱 어렵게 느껴집니다. TDD를 제대로 하려면
Angular vs Ember. RSpec vs Minitest. Haml vs Slim vs ERB. 새 프로젝트를 시작하면 수많은 선택의 기로에 서게 됩니다. 진영마다 열렬한 지지자들이 목소리를 높이죠. 그러다 문득 깨닫게 됩니다. 네 번째 튜토리얼을 끝까지 읽고, Sass가 Less보다 나은가를 두고 30개 댓글이나 달린 논쟁을 추적하는 데 낭비한 시간으로는 이미 프로젝트를 시작할 수 있었다는 사실을요. 그렇다면 어떻게 해야 올바른 라이브러리를 골라 실제 코드 작성에 착수할 수 있을까요? 선택의 압박감, 생각보다 큽니다
Rails 앱을 몇 개 만들다 보면 자신만의 선호하는 작업 방식이 생기기 마련입니다. Rails 콘솔에서 항상 awesome_print를 사용하고 싶을 수도 있고, rails new로 프로젝트를 생성할 때 minitest 대신 rspec을 사용하도록 만들고 싶을 수도 있습니다. 물론 명령어를 실행할 때마다 이런 환경설정을 일일이 지정하는 것이 크게 번거롭지는 않습니다. 하지만 이런 옵션들은 쉽게 잊어버리기 마련입니다. 그리고 컴퓨터가 내가 지시한 대로 동작하지 않을 때의 짜증은 이루 말할 수 없죠: $ rails new best
이 글에서 소개하는 아이디어 대부분은 제가 가장 좋아하는 루비 책 중 하나인 『Confident Ruby』에서 배운 것입니다. 이 글이 마음에 드셨다면 직접 구매해서 전체를 읽어보시길 권합니다. 정말 유용한 내용이 가득합니다. current_user 메서드는 User 객체를 반환하지만, 로그인한 사용자가 없으면 nil을 반환합니다. search 메서드는 결과를 담은 Array를 반환하지만, 결과가 하나뿐일 때는 배열이 아닌 그 객체 자체를 그대로 돌려주죠. 얼핏 보면 합리적이고, 어쩌면 편리해 보일 수도 있습니다. 하지만 곧 이
지난주에는 일관된 반환 값을 가진 메서드가 어떻게 코드를 더 단순하게 만들어 주는지 이야기했습니다. 하지만 그것은 어떻게 가능할까요? 올바른 리팩토링은 어떻게 코드를 다루기 쉽게 만들 수 있을까요? 좋은 추상화가 좋고 나쁜 추상화가 나쁜 이유는 무엇일까요? 코드를 무작정 재배치한다고 해서 고품질 소프트웨어가 저절로 완성되는 것은 아닙니다.이러한 기법들이 왜 효과가 있는지 그 원리를 이해하면, 코드의 어느 부분에 개선이 필요한지 더 잘 파악할 수 있습니다. 그리고 가장 중요한 곳에 적절한 도구를 적용할 수 있게 됩니다.소프트웨어 개발
좋은 무료 Rails 자료는 정말 많습니다. 하지만 개발 실력이 늘어갈수록 오히려 자신에게 유용한 지식을 찾기가 어려워집니다. 너무 기초적인 글은 이미 아는 내용뿐이고, 너무 어려운 글은 눈이 슬며시 감기면서 뇌가 멈춰버립니다. 세 문단쯤 읽다 보면 내 이름이 뭔지도 기억나지 않을 정도죠! 구글에 중급자용 Rails 블로그라고 검색한다고 좋은 사이트가 저절로 나오지 않습니다. 원하는 정보를 얻으려면 직접 파헤쳐야 합니다. 찾고 걸러내기 먼저 넓고 얕게 살펴보세요. Reddit, X(트위터), Stack Overflow 같은