개발자 99% 커뮤니티에서 수다 떨어요!
오늘 TIL 3줄 요약
소프트웨어 개발의 목적은 코드를 짜는 것이 아니라 사용자를 기쁘게 하는 것이다.
버전관리, 철저한 테스트, 자동화를 사용하라.
자신의 작품이 곧 자신이 되도록 서명하라.
TIL (Today I Learned) 날짜
2022. 05. 31
오늘 읽은 범위
9장. 실용주의 프로젝트
책에서 기억하고 싶은 내용을 써보세요.
소프트웨어 개발 방법론의 목표는 사람들이 함께 일하는 것을 돕는 것이다. 여러분과 여러분의 팀은 여러분에게 잘 맞는 방법론을 사용하고 있는가, 아니면 사소한 표면적인 과제만 따라하느라 애쓸 뿐 여러분이 얻어야 할 진짜 이득은 얻지 못하고 있는가?
실용주의 팀은 작다. 구성원이 대략 10~12명 이하여야 하고, 구성원이 추가되거나 빠지는 일은 드물어야 한다. 모두가 서로 잘 알고, 신뢰하며, 의존해야 한다.
품질은 팀의 문제다. 아무리 부지런한 개발자라 해도 품질에 무심한 팀에 배치된다면, 자질구레하게 계속되는 문제를 고치는 데 필요한 열정을 유지하긴 어려울 것이다. 개발자가 이런 수정 작업을 하느라 시간을 쏟는 것을 팀이 적극적으로 방해하고 나선다면 문제는 더욱 커진다.
팀은 개인보다 더 삶은 개구리가 되기 쉽다. 사람들은 누군가가 문제를 처리하겠거니 생각하거나, 사용자가 요청한 변경 사항을 팀 리더가 이미 동의했겠거니 하고 여긴다.
모든 사람이 적극적으로 환경 변화를 감시하도록 권장하라. 범위(Scope)의 확장, 일정 단축, 추가 기능, 새로운 환경 등 무엇이건 간에 애초에 인지하고 있던 것과 다른 것들을 늘 깨어서 의식해야 한다. 새 요구사항에 대한 수치를 관리하라. 이미 일어난 변화를 거부할 필요는 없다. 단지 그런 일이 벌어지고 있다는 것을 파악하고 있으면 된다.
'번다운(burndown) 차트'보다 '번업(burnup) 차트'가 더 낫다. 번업 차트가 있으면 추가 요구사항이 어떻게 목표 지점을 옮겼는지 명확하게 볼 수 있다.
"시간이 나면 그때" 하겠다는 것은 "영원히 하지 않겠다"는 것이다.
개인적으로 배우고 역량을 키우는 것은 좋은 시작점이다. 하지만 많은 기술이 팀 전체로 퍼졌을 때 더 효과적이다.
훌륭한 프로젝트팀은 뚜렷한 특성이 있다. 사람들은 이 팀과의 회의를 기대한다. 모든 사람이 좋아할 만한 잘 준비된 퍼포먼스를 보게 될 걸 알기 때문이다. 이들이 생산해 내는 문서는 깔끔하고 정확하며 일관적이다. 팀은 한 목소리로 이야기한다.
팀은 개인들로 이루어진다는 사실을 명심하라. 각 팀원이 자기 방식대로 빛나게 하라. 팀원들을 지원하기에, 그리고 프로젝트가 가치를 만들어 내기에 딱 좋을 만큼의 구조를 제공하라.
'화물 숭배(cargo cult)'를 경계하라. 화물 숭배의 함정은 너무 솔깃해서 빠지기 쉽다. 눈에 잘 띄는 결과물을 만드는 데만 투자하면서 기반이 되는 작업이 마법처럼 끝나 있기를 소망한다. 하지만 멜라네시아의 원래 화물 숭배가 그랬듯이 코코넛 껍질로 만든 모조 공항은 진짜를 대체할 수 없다.
소프트웨어 개발 방법론의 목표는 사람들이 함께 일하는 것을 돕는 것이다. 여러분이 소프트웨어를 개발할 때 늘 따를 수 있는 단 하나의 계획이란 것은 없다. 다른 회사의 누군가가 들고 온 계획이 들어맞을 리는 더욱 없다.
필요할때마다 출시한다는 것이 끊임없이 1분에 한 번씩 배포한다는 뜻은 아니다. 사용자가 필요로 할 때마다, 사업적으로 배포가 의미 있을 때마다 배포하는 것이다.
진짜 목표는 작동하는 소프트웨어를 제공 함으로써 사용자가 즉각적으로 새로운 일을 할 수 있게 되는 것이다. 지금으로부터 몇 주일 후나 몇 달, 몇 년 후가 아니라 지금. 지속적 배포(continuous delivery가 이상적이지만 도달 불가능한 목표라고 생각하는 팀이나 조직이 많다. 특히 배포를 몇 달 내지 몇 주에 한 번으로 제한하는 프로세스를 따르고 있다면 더 그럴 것이다. 하지만 모든 목표가 그렇듯 계속 올바른 방향을 바라보는 것이 중요하다. 사용자가 필요로 할 때마다, 사업적으로 배포가 의미 있을 때마다 배포하는 것이다.
방법론이나 언어, 기술 스택에 상관없이 모든 팀에게 필요한 가장 기본적이고 중요한 요소에서 시작해야 한다고 보았다. 그렇게 '프로그래머를 위한 시작 도구(Pragmatic Stater Kit)' 시리즈가 탄생했다. 다음 세 가지 핵심적이고 서로 밀접하게 연결된 주제를 다룬다.
버전 관리
회귀 테스트
전체 자동화
이 셋은 모든 프로젝트를 지탱하는 기둥이다.
프로젝트를 빌드하는데 필요한 모든 것을 버전 관리하에 두어야 한다. 이는 프로젝트 전체의 관점에서 보면 더 중요하다.
그렇게 하면 빌드 장비를 일시적으로 쓰고 없앨 수 있다. 빌드 머신이나 빌드 클러스터를 필요할 때마다 클라우드의 스폿 인스턴스(spot instance)를 이용하여 만들어 쓸 수 있다. 배포 설정도 역시 버전 관리 시스템 안에 있으므로 실제 서비스에 릴리스하는 것도 자동으로 처리된다.
프로젝트 차원에서는 버전 관리 시스템이 빌드와 릴리스 프로세스를 운용한다.
코드를 작성하자마자 테스트해야 한다. 훌륭한 프로젝트에는 제품 코드보다 테스트 코드가 더 많을 수도 있다. 테스트 코드를 만들기 위해 들이는 시간에는 그 노력만큼의 가치가 있다. 길게 보면 이쪽이 훨씬 더 싸게 먹히며, 결함이 거의 없는 제품을 만드는 꿈이 정말 이루어지기도 한다.
테스트 환경은 실제 환경과 최대한 비슷해야 한다. 두 환경의 차이에서 버그가 번식한다.
단위 테스트
'단위 테스트'는 하나의 모듈을 테스트하는 코드다. 부분으로 떼어 놓았을 때 제대로 작동하지 않는다면 합쳤을 때도 역시 제대로 작동하지 않을 것이다.
통합 테스트
'통합 테스트(integration test)'는 프로젝트를 구성하는 주요 서브시스템이 다른 부분과 제대로 작동하는지 보여준다. 통합 테스트는 앞서 설명한 단위 테스트의 확장에 지나지 않는다. 단지 전체 서브시스템들이 모두 계약을 제대로 지키는지 테스트하는 것뿐이다.
유효성 평가 및 검증(Validation and Verification)
실행 가능한 사용자 인터페이스나 프로토타입이 갖춰지자마자 가장 중요한 다음 질문에 대답해야 한다. 사용자들이 필요한 것을 이야기해 주긴 했지만, 그게 정말 사용자들이 필요로 하는 것인가? 시스템의 기능적 요구 사항을 충족하는가?
성능 테스트
성능(performance)테스트 혹은 스트레스 테스트 역시 프로젝트의 중요한 측면이다.
테스트를 테스트하기
우리는 완벽한 소프트웨어를 작성할 수 없기 때문에, 완벽한 테스트 소프트웨어 역시 작성할 수 없다. 그렇다면 테스트를 테스트할 필요가 있다.
정말 진지하게 테스트해 보고 싶다면 소스 트리에서 별도의 브랜치를 하나 만든 다음 고의로 버그를 심어 놓고 테스트가 잡아내는지 검증하라.
철저한 테스트
일단 테스트가 올바르다는 확신이 들고 여러분이 만들어 넣은 버그도 찾아냈더라도, 코드 전체를 필요한 만큼 철저하게 테스트했다는 것은 어떻게 알 수 있을까? 한마디로 답하자면 "알 수 없다." 그리고 앞으로도 알 수 없을 것이다.
속성 기반 테스트
테스트하려는 코드의 계약과 불변식에 따라 테스트 데이터를 생성하는 '속성 기반'테스트 기법을 사용하라.
그물 조이기
버그가 기존 테스트의 그물을 빠져나갔다면 다음번에는 그걸 잡아낼 수 있도록 새 테스트를 추가해야 한다. 한번 인간 테스터가 버그를 찾았다면 더는 인간 테스터가 그 버그를 만나서는 안 된다.
현대 소프트웨어 개발은 스크립트화된 자동 절차에 의존하고 있다. 사람들은 컴퓨터처럼 같은 일을 반복할 수 없을 뿐더러 그런 것을 기대해서도 안된다.
모든 것이 자동화에 의존한다.
개발자로서 우리의 목표는 사용자를 기쁘게 하는 것이다. 여러분의 사용자가 진짜로 원하는 것은 코드가 아니다. 그들에겐 자신의 목적과 예산에 맞추어 풀어야 하는 사업상의 문제가 있다. 그리고 여러분의 팀과 일하면서 문제를 풀어낼 수 있으리라 믿는다.
여러분의 고객을 기쁘게 하고 싶다면 고객이 문제를 풀 때 적극적으로 도와줄 수 있는 관계를 구축하라. 여러분의 직함이 명목상으로는 "소프트웨어 개발자"나 "소프트웨어 엔지니어" 비슷한 이름일지 몰라도 진정한 여러분의 직함은 "문제 해결사"다. 이것이 우리가 하는 일이고, 실용주의 프로그래머의 본질이다.
실용주의 프로그래머는 책임을 회피하지 않는다. 그 대신 도전을 수용하고 자신의 전문성이 널리 알려지는 것을 기뻐한다. 설계 혹은 코드를 맡는다면 자신이 보기에 자랑스러운 작품을 만들어 낼 것이다.
자신의 작품에 서명하라.
오늘 읽은 소감은? 떠오르는 생각을 가볍게 적어보세요
9장의 내용은 전반적으로 1장의 내용을 다시 한 번 강조하는 느낌이었다. 무엇보다, 마지막의 두 구절이 기억에 남는다.
개발자로서 우리의 목표는 사용자를 기쁘게 하는 것이다.
실용주의 프로그래머는 책임을 회피하지 않는다. 그 대신 도전을 수용하고 자신의 전문성이 널리 알려지는 것을 기뻐한다.
내 자신의 작품에 서명을하고, 해당 서명을 보고 다른 사람들이 해당 코드를 믿는다는 것. 개발자가 그것보다 더 좋아할 일은 아마 없지 않을까? 실용주의 프로그래머란 결국 자신이 개발한 코드에 자신감을 갖고, 해당 코드가 그 무엇보다 좋을 것이라는 자신을 가질 수 있도록 끊임없이 테스트하고, 개발하고 그것을 사용하는 사용자와 프로그램 간의 관계까지도 고려하는 완성된 사람이라는 생각이 든다.
무엇보다 몇 페이지에 걸쳐서 테스트 방법에 대해 설명하는 것과 테스트를 테스트하기 위한 테스트라는 점에서 광기가 느껴지는 듯 하긴 했다. 테스트를 테스트하기 위한 테스트의 테스트...식으로 어디까지 갈 수 있나 버그가 어디까지 숨어있을 수 있나 하는 느낌. 그럼에도 불구하고 반복적인 테스트의 필요성은 절실하게 느껴졌다.
사람은 완벽하지 않음을 인정하고 대비하자. 개발자 또한 사람이고, 사람은 프로그래밍 된 대로 움직이지 않는다.
궁금한 내용이 있거나, 잘 이해되지 않는 내용이 있다면 적어보세요.
오늘 읽은 다른사람의 TIL