본문 바로가기
IT일반/SW공학

[SW]NHN은 이렇게 한다! 소프트웨어 품질관리(1)

by 우공80 2023. 2. 17.
728x90

 

NHN은 이렇게 한다! 소프트웨어 품질관리
책이 많이 낡았어요

 

품질관리... 어떻게 하는 거지?


현재 진행하는 프로젝트가 중반에 접어들면서 현재의 품질 수준에 대한 점검이 화두로 떠올랐습니다.
단위테스트를 진행하기는 하지만, 단위테스트만으로는 부족하다는 생각이고, 현재의 품질 수준을 명확하게 알 수가 없었습니다. 업무를 하면서 경험적으로 알고 있는 것을 넘어, 좀 더 체계적으로 정리할 필요를 느꼈습니다.

그래서 도서관에서 소프트웨어 품질 관련 서적들이 모여있는 곳을 뒤지다 이 책을 발견했습니다. 이 책은 NHN의 소프트웨어 품질관리 프로세스인 QP에 대해 설명하고 있습니다. 문제 인식부터 도입, 그리고, 어려웠던 점이나, 좋았던 점, 적용 후까지 체계적이면서도 현실적인 내용들로 구성되어 재미있게 읽었습니다. (왜 이런 게 재미있어진 걸까요..?)

이 책은 총 11개 파트로 구성되어 있습니다. Part 01의 NHN과 소프트웨어 품질에서는 소프트웨어 개발의 특징과 문제점부터 시작해서 QP에 대한 전반적인 설명을 합니다. 그리고 Part 02부터 상세한 QP활동 내용과 도구가 설명되어 있습니다.
리뷰는 책 내용을 되도록 그대로 인용하고, 그에 대한 설명을 붙이는 식으로 작성했습니다.

나중에 잊어버리면 다시 보려고 상세하게 정리하다 보니, 리뷰가 길어져서 리뷰를 1,2부로 나누었습니다.

 

리뷰 1부 목차

01. NHN과 소프트웨어품질
   - QP(Quality Practice)란?
   - 애자일을 도입해야 하는 이유 - 1. 소프트웨어의 특징
   - 애자일을 도입해야 하는 이유 - 2. 높은 품질이 비용을 줄인다
   - 애자일을 도입해야 하는 이유 - 3. 요구사항의 잦은 변경
   - 애자일을 도입해야 하는 이유 - 4. 역할별 이기주의 타파
02. 효과적인 명세 작성
03. 단계적 빌드

 

01. NHN과 소프트웨어품질


QP(Quality Practice)란?

NHN의 품질혁신 활동(Quality Practice, 이하 QP)은 소프트웨어 개발의 특징과 오해에서 비롯되는 각종 문제를 해결하고 품질을 향상하는 것을 목표로 NHN에서 수행하는 활동의 일환이다. 하지만 이 책에서 설명하는 원칙이나 기법이 소프트웨어 개발의 '모든'문제를 해결할 수 있는 만능 치료약은 아니다.
현재 여러분이 어디에서 근무하고 있고, 또 어떤 프로젝트를 진행하고 있든 이 책에 소개된 기술이나 방법론만 적용해서는 NHN에서 이룬 성과를 기대할 수 없다. 정의된 프로세스 하나를 모든 소프트웨어 개발에 동일하게 적용할 수는 없기 때문이다.
각 조직별 구성원의 역할과 책임, 개인과 조직의 역량 그리고 제품의 특징이 같을 수 없으므로 우리가 제안하는 프로세스가 정답일 수는 없다. NHN의 품질 혁신 활동도 애자일(agile)의 여러 방법론 가운데 NHN에 효과적인 것을 선별하여 개발하고 개선해 나간 것이다.

QP는 애자일(agile) 기반의 NHN의 품질혁신 활동을 말합니다. 하지만, NHN이 잘 적용했다고 이것을 그대로 베껴서 자신의 회사에 적용한다고 모든 문제가 해결되지 않습니다. 어떤 방법론도 만능일 수 없습니다. 자기에게 적합한 것을 찾아 적용하고 개선해 나가야 합니다. 
애자일 방법론을 받아들인 많은 회사의 이야기를 들어보아도 대부분 자신들에게 맞는 방법론을 조금씩 적용하며 개선해 나갔습니다. 결국 애자일은 문화인 것이죠.

애자일을 도입해야 하는 이유 - 1. 소프트웨어의 특징

소프트웨어 산업은 생산된 소프트웨어를 고객에게 판매하여 수익을 올린다는 측면에서 물건을 만들어 파는 제조업과 성격이 매우 유사하다. 때문에 제조업에서 발달한 여러 생산관리 기법이 상대적으로 역사가 짧은 소프트웨어 개발 과정에 적용되었다. 흔히 얘기하는 '소프트웨어 아키텍처(software architecture)'라는 용어도 건물을 지을 때 사용하는 '설계(architecture)'라는 말을 빌려온 것이다. 전통적으로 제조업은 연구, 개발, 생산설비 적용이라는 제품 생산 과정을 따른다. 반면 소프트웨어 산업은 생산설비 적용을 통한 대량생산 과정이 없다. 똑같은 소프트웨어를 또다시 개발하는 일은 없기 때문이다. 이런 특성을 이해하지 못하고 전통적인 제조업의 생산관리기법을 소프트웨어 산업에 적용하는 과정에서 현실과 어울리지 않는 소프트웨어 개발 방법론이 양산되었다.

비슷한 말을 피플웨어에서도 본 것 같네요. 기존의 경영학이 제조업 기반에서 연구되었기 때문에, MBA에서 배운 대로 업무에 적용하면, 개발 현실과는 맞지 않는다고요. 애자일이 퍼지게 된 이유라고 볼 수 있는데, 여전히 런 제조업적 마인드를 가지고 IT를 바라보는 사람들이 많습니다. 

요즘 유행하는 애자일(Agile) 방법론은 소프트웨어 개발이 제조업에서 사용하는 정의된 프로세스가 아닌 경험적 프로세스에 더 적합하다고 생각하는 소프트웨어 개발 방법론이다. 애자일 방법론은 이런 관점에서 단 한 번의 설계와 구현, 테스트만을 거쳐 제품을 출시하는 과정을 거치는 기존의 소프트웨어 개발 방법론이 성공하지 못한 원인을 설명한다. 개발 과정을 작은 반복 주기(iteration)로 나눠 사용자의 피드백을 자주 받는 경험적 프로세스가 소프트웨어 개발에 더 적합하다는 것이다.

피드백은 현재까지 구현된 소프트웨어가 사용자의 요구사항과 일치하는 지를 확인하는 과정이다. 개발한 기능이 "사용자 요구사항과 일치하는 것(validation)"은 "명세서(specification)와 일치하는(verification)"보다 포괄적인 개념이다. 구현된 기능이 명세서와 일치하더라도 원래 의도와 다르게 구현된 경우가 많다. 전통적인 개발 방법론에서는 이런 사실을 프로젝트 후반부에서야 확인할 수 있다. 이런 문제를 프로젝트 후반부가 아닌 초기부터 자주 드러내어 문제를 일찍 해결하려는 방법이 반복점진적(Iterative and Incremetal) 개발 방법, 즉 애자일 방법론이며 이를 NHN의상황에 맞춰 적용한 방법이 NHN의 품질 혁신 활동이다.

여기서 말하는 정의된 정의된 프로세스(Defined Process)는 프로세스는 공장의 생산 라인과 같이 반복할 수 있는 과정을 의미하고, 경험적 프로세스(Empirical Process)는 어머니가 음식 하실 때처럼 음식이 완성될 때까지 양념을 넣고 간을 보는 과정을 반복하는 방식입니다.
우리가 폭포수모델(waterfall)을 따르건 애자일( agile) 모델을 따르건 처음의 설계가 유지되는 경우는 없습니다. 대부분 지속적으로 변경이 되는데, 폭포수모델과 애자일 모델의 차이는 발견하는 시점이 언제이냐의 차이입니다.
비단 설계만이 아니라 어떤 일, 이슈, 리스크던 빨리 오픈되어 공유가 되어야 해결이 쉽습니다. 문제를 덮어두면 해결이 되지 않습니다.

애자일을 도입해야 하는 이유 - 2. 높은 품질이 비용을 줄인다

소프트웨어 품질은 어떻게 정의하고 관리할까? 일반적으로 소프트웨어 개발 프로젝트는 '비용', '시간', '품질'을 3대 관리 요소로 보며 이를 "악마의 삼각형(Devil's Triangle)"이라고 한다. 이 삼각형은 3가지 관리 요소가 제한된 자원을 나눠 가지며 서로 제약하는 관계임을 보여준다. 따라서 어느 한 요소를 강조하면 나머지 두 요소를 희생해야 한다. '악마의 삼각형'의 '품질'은 기능이 오류 없이 동작해야 함을 의미한다.(중략)
예를 들어, 파일의 '열기', '저장', '인쇄' 세 가지 기능을 구현하는 프로젝트에서 적은 비용을 투자해서 빠른 시일 내에 결과물을 만들어야 한다면 상대적으로 중요한 '열기', '저장' 기능만 구현하고 출시해야 한다. 하지만 '품질'을 희생할 수 있다고 생각한다면 세 가지 기능이 정상적으로 동작할 확률이 100%가 아니더라도 모든 기능을 구현하고 제품을 출시할 수 있다. “100번 저장을 시도하면 한 번 정도는 실패해 자료가 사라질 수 있겠지만 그래도 99%나 성공하니 훌륭한 소프트웨어다."라고 말할 수 있을까? 소프트웨어 프로젝트에서 '품질'은 양보할 수 있는 관리 요소가 아니 다. 따라서 소프트웨어 프로젝트의 관리 대상은 '비용', '시간', '범위(기능 수)'가 돼야 한다. 기능이 오류 없이 동작해야 하는 조건(품질)이라면 범위는 필수로 고려해야 하는 요소이다. ‘범위’를 고려하려면 먼저 스펙을 명확하게 정의해야 한다.

악마의 삼각형
소프트웨어 프로젝트 관리의 3요소(악마의 삼각형)

저는 "소프트웨어 프로젝트에서 '품질'은 양보할 수 있는 관리 요소가 아니다"라는 말이 확 와닿았습니다. 품질은 개발부서의 자존심이기도 하고, 이것을 양보하고 제품을 출시하면, 반드시 문제가 생겨서, 품질을 희생하면서 얻은 당장의 이익보다 더 큰 손해를 가져오게 됩니다.
개발 부서가 방어적이라는 평을 듣는 가장 큰 이유 중의 하나가 품질에 대한 욕심 때문이 아닐까 합니다. 사용자는 최대한 적은 비용으로 최대한 짧은 시간에 좋은많은 개발을 하기를 바라지만, 개발부서는 품질을 가장 우선시하게 마련이니까요. 물론 무조건 개발부서의 말을 들을 필요는 없지만, 이런 개발부서의 특성도 이해를 해야 하는 것 같습니다.

 

흔히 '오류 없이 동작하는 소프트웨어를 만드는 데는 과도한 품질 비용이 소모된다고 생각한다. 1979년 필립 크로스비(Philip B. Crosby)는 자신의 저서인 “Quality is free”)에서 소프트웨어 품질을 높이기 위해서는 분명 비용이 발생하지만 예방과 평가에 들어가는 비용은 실패 비용에 비하면 아주 적은 비용에 불과하다고 말한다…(중략)

ICST(International Conference on Software Testing, Verification and Validation) 2010에서 발표한 ‘구글의 개발 단계별 결함 수정에 들어간 비용‘ 자료에서도 개발자가 테스트 주도 개발(Test Driven Development, TDD) 과정에서 결함을 발견하면 5달러의 비용으로 결함을 수정할 수 있지만, QA단계인 시스템 테스트 과정에서 결함을 발견하면 5,000달러의 품질 비용이 소모된다고 합니다. NHN은 그래서 프로젝트 초기에 결함을 발견하기 위한 노력을 집중해서 프로젝트의 전체 품질 비용을 줄이는 노력을 하고 있다고 합니다.
얼마 전에 포스팅한 피플웨어 1부에서도 품질의 한계는 없으며, 높은 품질을 추구하는 것이 궁극적으로 생산성과 이어진다고 하였으니, 여러모로 높은 품질을 추구해야 한다는 것은 분명해 보입니다. 아마 여기에 반론이 있는 사람은 없을 것입니다. 하지만, 실제 우리 업무 환경에서는 늘 시간과 비용이 부족하고, 이 비용도 당장의 비용은 적게 들고 길게 보았을 때 높은 비용이 드는 것이므로, 책임감이 없는 사람들, 곧 떠날 사람들은 품질을 쉽게 희생시키는 것이겠죠.

애자일을 도입해야 하는 이유 - 3. 요구사항의 잦은 변경

첫 번째 원인은 이름에서 풍기는 인상처럼 소프트웨어가 변경하기 쉬울 거라는 인식에서 비롯된다..(중략)
두 번째 원인은 소프트웨어가 눈으로 확인할 수 있는 대상이 아니라는 데 있다. 소프트웨어 개발의 모든 단계에서 가시성이 확보되지는 않으므로 고객의 요구 사항은 대부분 구현이 어느 정도 완료된 프로젝트 마지막 단계에 이르러서야 확인할 수 있다....(중략)... 소프트웨어의 최종 UI까지 완료된 후에야 고객은 비로소 "이건 제가 생각했던 것이 아닙니다."라는 이야기를 할 수 있게 되며, 이는 자연스레 요구사항 변경으로 이어진다.
세 번째 원인은 사용하는 언어의 차이에서 비롯된다. 고객이 요구사항을 설명할 때, 고객이 설명한 내용을 기획서에 담을 때, 기획서의 내용을 설계 문서에 옮길 때, 설계한 내용을 코드로 구현할 때, 테스터가 테스트 케이스를 만들 때 쓰는 용어가 모두 다른다...(중략)...
네 번째 원인은 비즈니스 환경의 변화이다... (중략)
따라서 기획서는 변경이 발생하지 않는 불변의 진리가 될 수 없으며 그렇게 만들기 위해 노력하는 것도 효과적이지 못하다. 더 효과적인 방법은 프로젝트 참여자들이 기획서는 언제나 변경될 수 있다는 사실을 인정하고 변경 사항에 빠르게 대응할 수 있는 체계를 만드는 것이며...(중략)

이 단락은 요구사항이 변경되는 네 가지 원인입니다. 첫 번째, 세 번째, 네 번째 원인은 알고 있었지만, 두 번째 원인은 처음 깨달았습니다. 그리고 이 단락을 읽으며, 공감한 만큼 애자일이 필수라고 생각하게 됩니다. 궁금하긴 합니다. 이런 문제는 수십 년 전에도 다를 바가 없었을 텐데, 왜 아직도 폭포수 방법론을 쓰는 걸까요?

회의는 어떤 사안에 대해 각 참석자가 돌일하게 이해하게끔 만드는 훌륭한 수단이다. 그러나 참석자 누구에게나 훌륭한 도구라고 할 수는 없다. 회의 시간 내내 메일만 보고 있는 사람, 자신과 관련된 이슈가 모두 정리되었음에도 어쩔 수 없이 남아있는 사람, 왜 들어와 있는지 이유도 모르는 사람에게 회의는 낭비이다.

많은 사람이 모이는 회의가 효과적이지 못한 의사소통 방법이란 것을 알면서도 없애지 못하는 이유는 무엇일까? 소프트웨어 개발은 수집한 고객의 요구사항을 토대로 제품을 개발하여 인도하는 과정이다. (중략)

전통적인 개발 방법론에서는… (중략) 회의를 통해 내용을 공유하고 공동의 이해를 추구하라고 권장한다. 이런 과정을 통해 의사소통이 정확해질 것이라 기대하는 것이다. 그런데, 소프트웨어 개발의 ‘정확’이란 개념에는 함정이 있다. (중략)

정확함은 자신이 그 내용을 아는 것을 나타내는 것이지 타인이 그 내용을 잘 이해할 수 있는가를 보장하지는 않는다. 무섭지 않은가? 수많은 요구사항 명세서, 상세 요구사항 등에 얼마나 많은 오해가 있을지, 그리고 이런 오해가 얼마나 많은 비용을 지불하게 만들지 상상할 수 있을 것이다. 이런 오해는 회의로도 효과적으로 방지할 수 없다. NHN에서는 이런 오해를 줄이기 위한 수단으로 사용자 관점의 예제와 테스트를 이용한 명세 작성법을 권장한다.

여기서는 명세라고 했지만, 결국 모든 산출물에도 해당되는 것이 아닐까 합니다. 다른 사람을 이해시키는 것이 모든 산출물의 목적이므로 거기에 중점을 두고 산출물이 작성되어야 합니다. 그리고 다른 사람을 이해시키는 데는 "예시", "예제"만큼 좋은 것이 없습니다. 비즈니스 환경의 변화로 발생하는 변경은 어쩔 수 없는 것이지만, 기획자와 개발자 간의 소통 문제로 발생하는 결함은 명세를 효과적으로 작성한다면 줄일 수 있습니다. 

애자일을 도입해야 하는 이유 - 4. 역할별 이기주의 타파

기능적 역할 분담과 순차적 일 흐름은 업무에 몰입할 수 있는 장점이 있지만 각 단계를 넘어가기 위해서는 의사소통 비용이 많이 들고 역할별 이기주의를 만들어낸다. 기획자는 자신의 기획을 개발자들이 잘못 이해했다고 하고, 개발자는 구현할 수도 없는 엉성한 기획서를 주더니 내용도 수시로 변경하여 자원을 낭비한다고 하고, QA/ 테스터는 개발자들이 오류가 너무 많은 산출물을 주어서 매번 테스트를 새로 수행하게 한다고 개발자를 비난하며..(중략)

소프트웨어 개발은 고객의 요구사항을 만족하는 소프트웨어를 만드는 것이 목적이므로 기획, 개발, QA/테스터는 이를 달성할 수 있도록 함께 노력해야 한다. 즉, 기획자의 기획 내용이 고객의 요구 사항과 일치하는 지를 고객, 개발자, QA/테스터가 협업하여 검증하고 피드백을 줘야 한다…(중략) 이런 과정은 일회성 행사로 진행되는 것이 아니라 짧은 주기로 항시 수행돼야만 한다. (Part2 효과적인 명세, Part3 단계적 빌드와 관련)

기능적으로 역할 분담을 했을 때의 문제점을 자주 느끼고 있습니다. IT부서끼리 논의할 때, "장애 나면 책임 안져" 따위의 말을 하는 경우가 있는데, 이런 말이 나오는 건 조직구조의 문제인 것 같습니다. 무조건 가장 나은 방안을 찾아야 하고, 성과도 책임도 같이 가져가야 이런 부서 이기주의가 생기지 않는 것 같습니다.

NHN의 QP이야기

특정 지표 몇 가지를 이용해 개발 생산성을 측정하고 조율하는 것은 효과적인 방법이 아니며, 목표 수치의 달성이 곧 품질과 생산성의 향상으로 연결되지 않는다는 사실을 유념해야 한다. NHN의 QP도 "테스트 커버리지", "잔존 결함 밀도", "코딩 표준 준수율", "코드 리뷰 수행률", "중복코드", "코드 복잡도"와 같은 항목을 측정한다. 하지만 NHN에서는 목표 수치의 달성을 절대적 가치로 생각하지 않으며, 효과적인 개선 방법을 조직 스스로가 결정하고 발전시켜 나갈 수 있는 부가 정보로 활용하고 있다. 특정 항목의 측정 결과가 나쁠 경우, 해당 부분에 잠재적 문제가 있을 수 있음을 관련자에게 알리는 용도로 사용하며 측정 대상도 조직과 비즈니스 상황에 맞게 지속적으로 조정하고 있다. (part4~9)

이 부분이 제가 이 책을 선택한 이유인데, 몇 가지 지표를 개발해서 생산성을 측정한다고 해서, 그것이 품질과 생산성을 객관적이고 정량적으로 표현할 수 있을지 의문이었습니다. 회사에서 측정하는 여러 가지 품질 지표는 그저 숫자놀음에 지나지 않는 경우가 많았습니다. 하지만, 관련 서적을 몇 권 읽으면서 공통적으로 확인한 것은 이런 활동을 지속하여 품질에 대해 고민해 보고, 품질을 개선시키려는 노력을 하는 것 자체가 의미가 있다는 것입니다. 측정할 수 없는 것을 측정할 수 없다고 그대로 내버려 두기보다는 어떻게든 측정을 하는 것이 더 낫습니다.

QP의 목표는 개발 과정에서 코드 품질을 높이도록 개발 조직의 문화와 습관을 바꾸어 개발 결과물의 품질을 개선하는 것이다. 조직의 문화와 습관을 바꾸기 위해서는 강제적인 적용 대신 개발 조직에서 자발적으로 적용하여 서서히 내재화하는 것이 바람직할 것이다. 따라서 처음 NHN에서는 QP를 개발 조직에 소개만 하고 적용 여부는 개발 조직에 맡겼다. 하지만 개발 일정에 대한 부담 속에 기존의 개발 습관을 바꾸는 것은 개개인의 노력만으로는 한계가 있고, 결과적으로 QP를 자발적으로 적용한 개발팀은 많지 않았다.

이런 분위기를 바꾸고자 NHN에서는 위에서부터 아래로(Top-down) 전파하는 정책으로 QP를 적용했다. 개발 조직의 문화와 습관을 바꾸기 위한 방법으로 상위 조직에서 회사 전체로 적용할 QP 목표를 정해서 안내하였다. 회사 전체의 품질 목표를 기준으로 해서 개발 조직별 목표를 수립하도록 했으며 개발 조직에서 수행하는 신규/개편이 개발 과제의 신규/수정 코드를 대상으로 적용하였다. 일부 조직에서는 자발적으로 서스테이닝 개발 업무에 QP를 적용하기도 했다.


앞서 확인한 소프트웨어 개발의 특징으로 인해 개발 조직의 문화와 습관은 개인의 노력으로는 한계가 있다는 것이 명확한 것 같습니다. 개별적으로 이런저런 방법론을 적용하라고 권고해도 늘 시간에 쫓기는 개발자들은 무시하기 마련입니다. 비단 품질 관련 활동뿐 아니라 어떤 것이든 마찬가지입니다. 어느 정도 전담조직을 구성하여 전파하는 것이 필요합니다. 다만, 바람직한 것은 자발적으로 서서히 내재화하는 것이므로 Top-down으로 전파하더라도 그것이 강압적이어서는 안 됩니다. 강압적으로 진행하면 그저 숫자를 맞추기 위한 일을 또 만들어낼 뿐이겠죠. NHN도 충분한 사전 교육과 공감대를 이끌어내는 작업을 거쳤고, 개발자들의 의견을 받아 필요한 도구를 개발하여 지원하기도 하였기 때문에 안정적으로 문화를 개선해 나간 것이 아닌가 싶습니다.

NHN의 QP는 코딩 컨벤션, 코드리뷰, 코드 커버리지, 정적분석, 사이클로매틱 복잡도를 측정하고 관리하였고, QP대상으로 지표를 측정한 것은 아니지만, 중복코드 분석도 함께 진행하였습니다.

 

02. 효과적인 명세 작성


앞서 소프트웨어 관리의 3요소(악마의 삼각형)에서 시간과 비용을 양보할 수 없다면, 품질을 희생시키지 않기 위해 범위를 고려해야 한다고 했습니다. 그리고 범위를 고려하려면 스펙을 명확히 해야 합니다. NHN에서는 스펙을 명확하기 위한 효과적인 명세작성법으로 테이블 형식 명세 작성을 제시하고 있습니다.

테이블 형식을 통해 테스트를 작성한다는 참신한 아이디어는 워드 커닝햄(Ward Cunningham)이 처음으로 고안했다. 테이블로 명세를 작성할 때 특별한 형식이나 규칙이 있는 것은 아니다. 그러나 테이블을 작성할 때도 역시 언어의 중의성과 모호성의 함정을 주의해야 한다. 테이블을 작성한 사람만 알아볼 수 있다든지 이름을 읽는 사람의 지식이나 경험에 따라 다르게 해석된다든지 입력과 출력의 관계가 모호하면 안 된다.
도널드 가우스(Donald Gause)와 제럴드 와인버그(Gerald Weinberg)는 다음 세 가지를 단계별로 고려해서 명세를 작성하라고 제안한다.
1. 정상적인 사용(normal use)
2. 비정상적이지만 합당한 사용(abnormal but reasonable use)
3. 비정상적이고 예외적인 사용(abnormal and unreasonable use)

NHN은 테이블 형식으로 명세를 작성하고 이를 테스트케이스로 만들어 자동화까지 하는 NTAF라는 도구를 개발해서 사용하였습니다. 테이블 형식으로 명세를 작성하면 예제의 모호함을 제거하고, 예외적인 상황을 더 쉽게 파악할 수 있다고 합니다. 다만, 이런 테이블 형식의 명세가 무조건적인 것은 아니며, 중요한 것은 명세가 예제를 통해 구체화되어 요구사항을 잘 반영하는 것입니다. 그리고, 명세가 곧 테스트 케이스가 되므로 기획자, 개발자, QA가 모두 명세를 작성하는 것에 참여하여 합의를 이루는 것이 중요하다 하겠습니다. 

 

03. 단계적 빌드

각 개발자는 자신의 로컬 환경에 로컬 웹 테스트 서버 환경을 구축해 테스트를 수행한다. 자신이 개발한 기능의 단위 테스트를 수행하기 위해 다른 모듈이나 데이터베이스를 사용하는 부분은 임시로 만든 객체나 메서드로 대체
(mocking)해서 의존성을 제거한다. 소스 코드는 형상 관리 시스템에서 공통으로 관리하고 단위 테스트에 성공한 소스 코드를 커밋한다. 여기까지는 아무런 문제가 없어 보인다.

각 개발자가 어느 정도 개발을 완료한 프로젝트 후반에는 통합 테스트를 수행한다. 통합 테스트란 서비스를 제공하는 실제 환경과 동일한 환경에서 수행하는 테스트라고 할 수 있다. 이 과정에서는 예상치 못한 문제가 발생할 수 있
다. 예를 들면 각 개발자가 단위 테스트를 하려고 임시로 만든 객체가 실제로 다른 개발자가 만든 객체와 다르게 동작할 수도 있다. 이때 다음과 같은 현상이 나타난다.
첫 번째는 '발뺌'이다. 각 개발자는 자신이 작성한 코드가 단위 테스트를 통과한 좋은 코드라고 확신하고 다른 개발자의 잘못으로 문제가 발생했다고 생각한다. 이렇게 서로에게 책임을 전가하면서 문제의 원인은 점점 발견하기 어려워지고 프로젝트 진행에 차질이 생긴다.

두 번째는 '헤맴'이다. 문제를 뒤늦게 발견하면 이 문제가 언제 어디서 발생한 것인지 파악하기 어렵다. 문제와 관련이 있는 변경 사항을 모두 확인해야 할 수도 있으며 원인을 찾아 수정한다고 해도 또 다른 부작용을 일으키기 쉽다.
이 악순환이 반복되면 프로젝트의 전체 일정에 심각한 영향을 미칠 수도 있다.

CI(Continuous Integration, 지속적 통합)의 필요성에 대해 설명하고 있습니다. 앞서 설명한 애자일 도입이유와 동일하게 문제를 더 빨리 드러내어 해결하기 위해 지속적 통합이 필요하다고 하겠습니다.

※ 통합테스트와 테스트 레벨에 대한 참고할 만한 사이트
http://en.wikipedia.org/wiki/Software_testing#Testing_levels

 

Software testing - Wikipedia

From Wikipedia, the free encyclopedia Process of examining software behavior and artifacts Software testing is the act of examining the artifacts and the behavior of the software under test by validation and verification. Software testing can also provide

en.wikipedia.org

 

모든 코드에 단계적 빌드를 수행하면 좋겠지만 소규모 프로젝트에서나 가능한 일이다. NHN에서는 우선 다음 모듈을 단계적 빌드 대상으로 관리했다.

- 오류가 발생하기 쉬운 모듈
- 공통으로 사용하는 모듈
- 자주 코드를 수정하는 모듈

우선 오류가 발생하기 쉬운 모듈만이라도 집중해서 지속적으로 관리한다면 프로젝트의 전체 오류는 크게 줄어들 것이다. 게다가 오류가 발생하기 쉬운 모듈은 복잡한 비즈니스 로직을 포함하고 있으며 복잡한 로직은 프로젝트에서 중요한 모듈일 가능성이 높다. 그다음으로는 프로젝트에서 공통으로 사용하는 모듈을 관리하면 해당 모듈을
사용하는 많은 기능 오류를 예방할 수 있다. 공통 모듈을 빌드하고 나서 빌드 결과에 따라 공통 모듈에 의존하는 모듈을 빌드하도록 설정할 수도 있다. 마지막으로 코드를 자주 수정하는 모듈을 생각해 보자. 코드를 수정할 때마
다 개발자는 테스트 코드를 작성하는데 이 테스트 코드는 100% 성공해야 한다. 또한 연관된 다른 모듈과의 통합 빌드도 성공해야 한다. 여기엔 모듈 간의 통합 테스트도 포함된다. 개발자는 항상 자신이 수정한 부분에 부작용(side
effect)이 없다는 것을 확인해야 하며 이 모든 과정은 단계적 빌드를 통해 가장 효율적으로 수행될 수 있다.

NHN의 단계적 빌드는 개발자 PC, 개발환경, 통합테스트환경, 운영환경에 대해 단계적으로 빌드하는 것을 의미하고, 각 단계에서 CI가 적용되어 있는 것으로 이해됩니다. CI가 적용되어 있어서 빠르게 빌드/배포하고 빠른 테스트가 가능하겠지요.

  개발자 빌드 커밋 빌드 통합 빌드 릴리스 빌드
설명 로컬PC에서 변경한 코드를 형상 관리 시스템에 커밋하기 전에 수행 형상 관리 시스템에 저장된 코드가 변경되었을 때 해당 코드가 다른 코드와 충돌하지 않는지 확인하기 위해 수행 정해진 시간 주기마다 수행. 주기는 일반적으로 24시간이며, 밤에 수행하는 것을 권장, 최종 통합 빌드 완료 후에는 코드 완료(code complete)를 선언 사용자에게 소프트웨어를 배포하기 위해 수행. 빌드 라벨을 붙이면 의사소통에 유용
빌드 환경 로컬PC CI서버 CI서버 빌드 배포 시스템
테스트 다른 모듈에 의존하지 않는 단위 테스트 여러 명의 단위 테스트를 모아 수행하는 테스트(미들웨어에 의존하지 않는 테스트) 데이터베이스, 플랫폼, 네트워크 등의 미들웨어에 의존하는 테스트 기능 테스트, 성능 테스트, 부하 테스트
테스트 권장 소요 시간 5분 이내 10분 이내 2시간 이내  
완료 조건 단위 테스트 성공
정적 분석에서 검출한 결함 수정
코딩 컨벤션 준수
코드 리뷰 수행
정적 분석에서 검출한 결함 수정
품질 지표 기준 모두 만족
새니티 테스트 성공률 90% 이상
테스트 통과 기준 달성
품질 지표 코드 커버리지
정적 분석 결함 밀도
코딩 컨벤션 준수율
코드 커버리지
정적 분석 결함 밀도
코드 리뷰 수행율
코딩 컨벤션 준수율
정적 분석 결함 밀도
코드 리뷰 수행율
코드 복잡도
코드 커버리지
기능 구현율
테스트 케이스 수행률
QA테스트 성공률
중요도별 잔존 결함 수

※ 새니티 테스트: 2~4시간 정도 테스트 범위에 해당하는 주요 기능에 대해 요구 사항에 맞게 동작하는지 테스트를 수행하는 것으로 온정성 테스트라고도 한다. 이 테스트 결과를 통해 본격적인 QA테스트 가능 여부를 판단한다.

메이븐(Maven)
메이븐은 앤트와 같이 빌드 자동화 기능을 제공할 뿐만 아니라, 프로젝트 객체 모델(Project Object Model, 이하 POM)을 제공하여 각 모듈의 복잡한 의존관계를 쉽게 설정할 수 있다. 메이븐을 이용하여 프로젝트를 생성하면 프로젝트 디렉터리를 미리 정의된 규칙에 따라 구성해야 한다는 제약이 있지만 디렉터리 구조를 이해하고 유지 보수하기가 쉽다. 그리고 다양한 플러그인을 사용할 수 있으므로 간편하게 기능을 확장하고 다른 도구와 연동할 수 있다. 메이븐을 설치하고 사용하는 방법은 부록, "메이븐 설치 및 사용"을 참고한다.

메이븐으로 빌드한다는 것이 무엇인지 제대로 이해를 못 하고 있었는데, 관련 설명이 있어서 인용해 둡니다.

CI 서버
CI 서버란 간단히 표현하면 '빌드 자동화 서버'다. 좀 더 구체적으로 말하자면 '정해진 스케줄에 따라 빌드를 수행하는 서버'라고 할 수 있다. CI 서버는 주기적으로 또는 형상 관리 시스템에 변화(커밋)가 발생했을 때 자동으로 빌드를 수행하고 결과를 보고한다. CI 서버는 일반적으로 다음 그림과 같이 형상관리 시스템과 테스트 서버 사이에 위치한다.
CI 서버는 다음과 같은 순서로 빌드를 수행한다.

1. 형상 관리 시스템의 소스 코드 변경 여부를 주기적으로 확인한다(폴링).
2. 개발자가 소스 코드를 커밋하면 형상 관리 시스템으로부터 최신 소스 코드를 체크
아웃해 빌드한다. 빌드 과정은 크게 컴파일, 테스트(단위 테스트, 통합 테스트 등), 분
석(코딩 스타일 점검, 코드 커버리지 측정, 정적 분석, 복잡도 측정, 중복 코드 분석
등)으로 나눌 수 있다.
3. 빌드 결과를 사용자에게 보고한다. 메일, RSS, SMS 등의 다양한 수단을 이용하여
지속적으로 보고받을 수 있다.

CI서버의 역할에 대해서도 어렴풋하게만 알고 있어서 해당 부분 인용하여 정리해 둡니다.

처음에는 의욕적으로 프로젝트의 품질을 관리하려고 해도 시간이 지나고 나면 이처럼 CI 서버의 각종 지표 그래프가 수평선을 그리는 경우가 흔하다. 아무리 훌륭한 도구를 사용해도 이 도구를 사용해서 분석한 내용을 바탕으로 현재 상태를 개선하지 않는다면 아무런 의미가 없다. 폴 듀발(Paul Duvall)은 지속적 통합의 효율을 저해하는 6가지 안티 패턴을 지적했다.

- 게으른 코드 커밋
- 깨진 채로 방치된 빌드
- 부족한 피드백
- 너무 많고 불필요한 피드백
- 성능이 나쁜 빌드 머신
- 팽창된 빌드

허드슨이 제공하는 지표 그래프 중 흔히 볼 수 있는 세 가지 유형을 기준으로 프로젝트 운영 패턴을 알아보자.

이 책이 나온 지 10년이 넘었다 보니, NHN은 형상관리를 위해 SVN을 쓰고, CI서버로 허드슨을 쓴다고 하는데요. 10년이 지난 지금도 그런지는 모르겠네요. 요즘은 대부분 Github/Gitlab과 젠킨스(Jenkins)를 쓰고 있지 않나 싶습니다. Jenkins에서도 허드슨처럼 품질 지표를 제공하므로 동일한 개념으로 이해하면 될 것 같습니다.

지속적 상승 그래프
지속적 상승 그래프

지속적 상승 그래프에 해당하는 가장 대표적인 지표로는 테스트 케이스의 개수, LOC(Line Of Code)등이 있습니다. 이 지표는 빌드가 반복될수록 점차 증가합니다.

낙타형 그래프
낙타형 그래프

낙타형 그래프는 지표가 증가, 감소를 반복하는 그래프입니다. 코드 커버리지, 복잡도, 코딩스타일 점검, 정적 분석의 테스트 결과 지표가 낙타형 그래프에 해당합니다. 왜 지속적으로 상승하지 않고 상승과 하강을 반복할까요? 코드 커버리지를 예로 들자면 개발을 진행할수록 코드의 양은 증가하지만, TDD(Test Driven Development, 테스트 주도 개발) 방식으로 개발하지 않았다면 테스트 코드의 양이 개발 코드만큼 증가하지 않으므로 코드 커버리지가 감소하게 됩니다. 코드 커버리지가 적정 수준이하로 감소하면 테스트 케이스를 추가하므로 이런 과정을 반복하면 낙타형 그래프를 그리게 됩니다. 따라서 낙타형 그래프라고 하더라도 증가 추세에 있다면 문제가 없다고 볼 수 있습니다.

하강 낙타형 그래프
하강 낙타형 그래프

낙타형 그래프가 위 그림처럼 하락 추세에 있다면 문제가 있습니다. 이 패턴이 지속되면 코드 커버리지가 계속 감소하여 종국에는 만회가 불가능해집니다.

폭포수형 그래프
폭포수형 그래프

폭포수형 그래프는 지표가 폭포수처럼 급격하게 떨어지는 모습을 볼 수 있습니다. 폭포수형 그래프는 지속적으로 오류를 검출하고 개선하기보다는 특정 시점에 몰아서 처리하는 경우에 나타납니다. 예를 들어 측정 항목이 버그의 수라면, 어떤 품질게이트 앞에서 오류를 대대적으로 수정하게 되면 버그가 거의 없어졌다가 다시 개발이 지속되면서 늘어나는 형태가 됩니다. 아주 나쁜 패턴은 아니지만, 문제를 방치했다가 일괄적으로 처리하다 보면 문제를 해결하기 쉽지 않게 됩니다.
따라서 지속적 상승, 혹은 상승 낙타형 그래프의 형태를 가지도록, 개발과 테스트를 조금씩 진행하면서 문제를 일찍 발견하여 해결하는 것이 가장 효과적이고 효율적인 방법입니다.

 

...2부에 이어집니다...

2023.02.18 - [IT 말고/책] - [SW][리뷰] NHN은 이렇게 한다! 소프트웨어 품질관리(2)

 

[SW][리뷰] NHN은 이렇게 한다! 소프트웨어 품질관리(2)

2023.02.17 - [IT 말고/책] - [SW][리뷰] NHN은 이렇게 한다! 소프트웨어 품질관리(1) [SW][리뷰] NHN은 이렇게 한다! 소프트웨어 품질관리(1) 품질관리... 어떻게 하는 거지? 현재 진행하는 프로젝트가 중반

woogong80.tistory.com

 

"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."

728x90

댓글