본문 바로가기
SW

커리어 스킬 - 3부 : 소프트웨어 개발에 대해 알아야 할 것 (27 ~ 29장) (The Complete Software Developer's Career Guide)

by 라꾸스떼(YR) 2019. 12. 21.
반응형

[27장] 소프트웨어 개발 방법론

[전통적인 폭포수 개발]

말 그대로 폭포수처럼 한 단계식 아래 단계로 진행해 가는 방식.

소프트웨어 개발 생명주기(Software Development Life Cycle, SDLC)가 순차적으로 진행된다.

 

[SDLC를 반대하는가?]

SDLC : 소프트웨어를 개발하기 위해 요구사항 분석부터 시작해 소프트웨어 설계, 구현, 테스트, 배포, 유지 보수로 끝나는 일련의 과정.

폭포수 개발을 반대하거나 애자일 개발만을 고집하지는 않는다.

뭐가 되었든 프로세스를 제대로 지켜나가는 개발이 되었음 한다...

 

<요구사항 분석>

'어떤 방법을 쓰든 제작에 들어가기 전에 알아야한다. 하지만 그게 늘 가능하진 않다는 걸 금방 알게 된다.'

동감한다... 요구사항은 살아있는 생명체와 같다... (그래서 애자일 개발 방법론이 좋지 않을까..?)

 

<소프트웨어 디자인>

'알아낸 요구사항을 바탕으로 시스템 아키텍쳐를 설계하고, 저수준 알고리즘과 (원한다면) UML 다이어그램을 만들며 그 시스템을 어떻게 만들고 동작하게 할지 결정한다. 방대한 사전 설계란 세부 사항 대부분에 대한 계획을 아주 낮은 수준까지 설게 단계에서 정해두는 걸 가리킨다. '

이건 정말 이상적인 방안이다... 솔직히 UML 다이어그램이 꼭 필요한가도 싶다... 코드만 잘 만들어 놓는다면 소프트웨어 사용법 외의 문서는 낭비가 아닐까...? 시스템 아키텍쳐는 '클린 아키텍쳐'에서 다룰 예정 :)

 

<구현>

-

 

<테스트>

테스트는 필수다. 버그는 늘 있기 때문... 최대한 버그를 잡아내고 배포하자. 제발!

 

<배포>

-

 

<유지 보수>

'대부분의 경우 다른 단계보다 유지 보수 단계에 더 오랜 시간이 든다. 소프트웨어는 세상에 내보낸 후에도 계속 지원해야 한다. 고객이 찾아내는 버그를 고치고 새로운 기능을 추가하고 다른 모든 일이 순조롭게 흘러가게 해야 한다.'

물론 한번만 코드를 들여보고 말 단발성(?) 소프트웨어도 존재를 한다. 하지만 사람 일 모른다... 다시 들여다볼 가능성이 늘 존재하기 때문.

한번 코드 작성할 때 유지보수도 제발 고려하자.

 

[애자일]

-

 

[애자일 선언문] (책 발췌)

<애자일 선언문>

우리는 소프트웨어를 개발하고 다른 사람의 개발을 도와주면서 소프트웨어 개발의 더 나은 방법을 찾아나가는 과정에 있다. 이 작업을 통해 우리는 과정이나 도구보다 개인이나 상호작용을, 포괄적인 문서보다 작동하는 소프트웨어를, 계약 협상보다 고객과의 협력을, 계획을 따르는 것보다 변화에 대응하는 것을 가치 있게 여긴다는 결론에 이르렀다. 이 말인즉 먼저 언급한 것도 가치가 있지만, 우리는 뒤에 언급한 것에 더 높은 가치를 둔다는 뜻이다.

 

<12가지 원칙>

1. 우리는 가치 있는 소프트웨어를 빠르게 그리고 지속적으로 제공해서 고객을 만족시키는 것을 가장 중요하게 생각한다.

2. 개발의 후반부일지라도 요구사항 변경을 환영하라. 애자일 프로세스는 변화를 활용해서 고객의 경쟁력을 높이는 데 기여한다.

3. 새로운 소프트웨어는 몇 주나 몇 달의 주기로 자주 제공하라. 간격은 짧을수록 좋다.

4. 프로젝트가 진행되는 동안 사업부서 사람들과 개발자는 매일 만나서 함께 일해야 한다.

5. 의욕 있는 사람들 위주로 팀을 구성하라. 그들이 필요로 하는 환경과 지원을 제공하고 그들이 맡은 일을 완수할 거라고 믿어라.

6. 개발팀으로, 혹은 개발팀 내에서 정보를 전달하는 가장 효율적이고 효과적인 방법은 서로 얼굴을 보고 하는 소통이다.

7.업무 진척을 측정하는 기본 척도는 작동하는 소프트웨어다.

8. 애자일 프로세스는 지속 가능한 개발을 장려한다. 후원자, 개발자, 사용자는 일정한 속도를 계속 유지할 수 있어야 한다.

9. 기술적 우수성과 좋은 설계에 대한 꾸준한 관심이 기민성을 높인다.

10. 해야 할 일의 양을 최소화하는 단순성이 꼭 필요하다

11. 최고의 아키텍쳐, 요구사항, 설계는 자기 조직적인 팀에서 나온다.

12. 팀은 정기적으로 더 효과적으로 일할 방법을 고민하고 이를 통해 이른 결론에 따라서 팀이 어떻게 움직일지 조율하고 조정한다.

 

[애자일은 방법론이 아니다]

애자일은 단순한 소프트웨어 개발 방법론이 아니라고 생각한다. 위 선언문과 원칙처럼 소프트웨어 개발자가 갖추어야 소양(?)이 아닐까 싶다.

 

[폭포수 방식의 문제]

'폭포수 개발에서는 요구사항 변화가 문제가 된다. 소프트웨어 개발자 입장에서는 아무것도 바뀌지 않는 게 좋다. 모든 요구사항이나 설계, 해결책을 미리 다 알아낸 후에 이를 구현할 수 있다면 좋을 것이다. 하지만 세상은 그렇게 돌아가지 않는다.'

저자의 말에 10000% 공감한다. 앞서 말했듯 우리의 고객(?)은 늘 요구하고 요구사항은 살아있는 생명체와 같다.

 

[스크럼]

스크럼, 스프린트 등에 대해 부정적인 의견들도 많이 들어보았지만, 단기간에 결과물을 만드는데 이만큼 좋은 프로세스가 또 있나 싶기도 하다.

 

[스크럼 직책]

1. 제품 책임자 : 고객 소통, 작업의 우선 순위를 결정

2. 개발팀 : 제품 개발

3. 스크럼 마스터 : 개발팀과 제품 책임자 사이에서 소통 및 스크럼의 방해물을 제거해주는 팀의 코치 역할

 

[스크럼 진행 방식]

스크럼 : 스프린트라는 작은 반복 주기(1~2주)로 이루어진다.

스프린트 : 각 스프린트마다 해야할 일의 양을 정해 결과를 점진적으로 고객에게 전달한다. 

                   개발해야할 모든 기능은 제품 백로그에 넣어 둔 후 우선 순위를 정한다.

                  스프린트 시작시 계획 회의를 통해 스프린트 백로그에 제품 백로그 항목 중에 골라 모아둔다.

스크럼 회의 : 매일 모든 팀원이 짧게 진행 상황을 공유하는 회의

1. 어제는 팀의 스프린트 목표 달성에 도움이 될 만한 어떤 일을 했는가?

2. 오늘은 팀의 스프린트 목표 달성에 도움이 될 만한 어떤 일을 할 것인가?

3. 본인이나 팀의 스프린트 목표 달성을 막는 장애물이 있는가?

소멸 차트(burndown chart) : 업무 진행 상황과 속도를 추적. 남은 시간, 스토리 포인트, 업무 난이도를 비롯해 남은 업무의 양을 확인할 때 필요한 거라면 무엇이든 추적.

리뷰 : 마지막으로 지난 스프린트를 돌아보고 다음 스프린트에 대한 아이디어를 떠올리는 회고 회의.

 

[스크럼 관련 문제]

저자는 스크럼이 성공적으로 구현되지 못하는 이유로 '헌신'을 꼽았지만... 일정 부분 동의할 수 있겠지만, 개발자는 로봇이 아니다.

책임자의 현실적이지 못한 계획에 대해 책임을 물어야하지 않을까...?

 

[칸반]

칸반 : 도요타 생산 체계와 린(lean) 제조 방식에 기원을 둠.

            개발 프로세스가 진행되는 업무 단계를 표현.

            칸반 보드를 통해 프로세스를 시각화하여, 병목 현상을 제거 및 동시에 진행하는 업무의 양을 제한함(WIP:Work in Progress)

백로그에 할 일들을 적고 우선순위를 정하면 팀원들이 각자 할 일을 골라 칸반 보드에 올린다.

업무의 진행 상황에 따라 보드에 위치하기 때문에 한 눈에 진행 상황을 파악하기 쉽다.

스크럼은 정형적인 것에 비해 칸반은 비교적 간단하여 개인적으로 일할 때도 칸반보드를 활용하려고 하고 있다.(Trello 이용중)

 

[익스트림 프로그래밍]

저자는 XP를 단위 테스트, 테스트 주도 개발, 객체지향 프로그래밍, 고객 중심 등을 통해 극한의 경지라고 부를 수준까지 끌어올렸다고 한다. 또한 XP는 미래보다는 현재의 필요를 염두에 두고 기능을 최대한 단순하게 설계해서 구현하는 것이 목표이며, 코드 공동 소유와 코딩 표준이라는 개념이 XP에서는 매우 중요하다라고 말한다. 

XP는 페어 프로그래밍에 크게 의존하는 것으로 아는데, 페어 프로그래밍을 간접적으로만(?) 경험해 보았을 뿐 이에 대한 제대로된 경험이 없기에 뭐라 평할 수가 없다. 하지만 간접체험한 어깨넘어 훈수(?)는 때때로 훌륭한 도구임이 분명하다고 생각하는 바, 간헐적인 페어 프로그래밍은 실보다는 득이 많은 방법론이 되지 않을까 싶다.

- 단위 테스트 : 실제 코드를 작성하기 전에 코드가 다양한 상황에서 해야 할 일을 정확히 정의하는 테스트

 

[다른 방법론과 비(非)방법론]

저자는 방법론을 배울 때 염두에 두어야 할 두 가지 사항을 당부하고 있다.

1. 어떤 방법론을 선택하느냐보다 반복 가능한 프로세스를 갖췄느냐가 중요하다.

2. 여기에 언급하지 않았다는 이유로 부적합한 방법론이라고 생각하면 안 된다.

무엇보다도 동감하는 것은 '반복 가능한 프로세스'이다. 심사숙고(?)하여 선택한 방법론이 잘못되었을 가능성보다는 반복 불가능한 프로세스를 선택함으로서 매번 변경되는 프로세스에 우왕좌왕하는 경우가 더 많다. 엄청난 낭비다... 

 

[28장] 테스트와 QA 기초

'의도한 대로 바르게 작동한다.' 테스트의 기초다.

 

[테스트의 핵심 목표]

필자는 테스트의 핵심 목표는 위험 부담을 줄이는 것이라고 한다. TDD에서의 테스트는 개발자의 자신감을 향상시킨다는 점에 있어서 같은 의미라고 생각된다. 테스트는 버그를 찾기 위한 것이 아닌 소프트웨어 사용자에게 부정적인 영향을 미칠 만한 위험 요소를 감소시키는 최소한의 안전 장치이다.

 

[일반적인 테스트 유형]

<블랙박스 테스트>

소프트웨어를 내부가 보이지 않는 검은 상자라고 생각하고 진행하는 테스트다. 블랙박스 테스트는 입력과 출력만 신경 쓰면 된다. 코드나 코드의 작동 방법에 대해 모르는 상태로 소프트웨어에 정해진 입력을 넣고 정해진 출력이 나오는지 보는 것이다.

 

<화이트박스 테스트>

화이트박스 테스트는 시스템의 내부 구조를 이해하고 소스 코드에 접근할 권한이 있어야만 제대로 해볼 수 있다.

 

<인수 테스트>

소프트웨어가 고객의 요구사항이나 기대에 맞게 제작되었는지 확인하는 테스트로 시스템을 전체적으로 점검하는 테스트다.

인수 테스트라고 하니 무슨 테스트인지 잘 와닿지 않는다...

 

<자동 테스트>

테스트 실행이나 결과 검증이 자동으로 이루어지는 모든 테스트. 테스트에 있어서 필수다.

 

<회귀 테스트>

시스템이 과거에 작동했던 방식 그대로 작동하고 있는지 확인하는 테스트다. 애자일 방법론에 있어서 회귀 테스트는 필수다. 새로운 기능을 꾸준히 추가하며 소프트웨어를 점진적으로 발전시키기 때문에 기존 기능에 대해 늘 확인해 보아야 한다. 

 

<기능 테스트>

시스템의 기능을 대상으로 진행하는 테스트. 원하는 결과가 나오는지만 보면 된다.

 

<탐색적 테스트>

탐색적 테스트를 제대로 수행하려면 애플리케이션의 어떤 영역을 어떤 방식으로 테스트할지에 대한 기본 계획과 가이드라인부터 세워야 한다. 테스트 케이스 없이 애플리케이션을 탐색하면서 예상치 못한 문제를 찾아본다.

 

<부하 테스트>

과부하 상태에서 애플리케이션이 어떤 성능을 보이는지 확인한다.

 

<성능 테스트>

특정 시나리오에서 애플리케이션의 성능을 확인한다.

 

<회복 테스트>

에러가 나거나 하드웨어에 문제가 생겼을 때 어떻게 회복하는지 확인한다.

 

<보안 테스트>

-

 

<스트레스 테스트>

부하 테스트랑 뭐가 다른거지..?

 

<상용성 테스트>

-

 

[테스트 절차] (책 발췌)

테스트는 보통 테스트 계획을 세우는 것으로 시작한다.

1. 어떤 방식으로 테스트할 것인가?

2. 테스트 전략은 무엇인가?

3. 어떤 유형의 테스트를 할 것인가?

4. 어떤 기능을 테스트할 것인가?

5. 일정은 어떻게 되는가?

이 모든 질문에 대한 답이 테스트 계획서에 있어야 한다.

테스트 실행 결과는 녹화되고 평가하며, 버그나 결함은 보통 버그 추적 시스템에 기록되어야 한다.

 

[애자일 팀의 테스트 방식]

애자일에 있어서 회귀 테스트는 필수이다. 따라서 테스트는 자동화되어야 한다. TDD는 아니더라도 테스트 케이스와 테스트 시나리오가 고려되어야하며 소프트웨어를 개발할 때처럼 테스트 절차를 더 작은 단계로 나누어서 줄여야 한다.

 

[테스트, 당신 그리고 개발자]

긴말 필요없이 개발자라면 자신이 만든 코드의 품질에 책임감을 가져야 한다.

 

[29장] 테스트 주도 개발과 단위 테스트

단언문(assert statement)은 테스트 중 대상을 실제로 테스트할 때 쓰는 구문으로 상이 참이어야 하는지 거짓이어야 하는지 혹은 주어진 조건을 만족시켜야 하는지 단언한다. 단언문이 하나도 포함되지 않은 테스트라면 애초에 실패하는 게 불가능하다.

 

[단위 테스트란 무엇인가?]

단위 테스트 : 코드를 가능한 한 작은 '단위'로 실행해보는 테스트.

코드가 정확히 무슨 일을 하는지 밝히는 것이며 코드에 추가된 신기능이 기존 기능을 망가뜨리지 않게 해주는 회귀 테스트 역할도 한다.

저자는 단위 테스트를 절대적 요구사항이라고 생각하라 한다. 즉, 단위 테스트는 특정한 코드의 단위에 특정 상황에서 특정 입력을 넣을 때 어떤 결과가 출력되어야 하는지 명시한다. 그리고 테스트의 마지막에는 테스트 통과 여부를 결정하는 확인 장치인 단언문이 있어야 한다.

 

[단위 테스트라고 오해하는 것]

저자는 단위 테스트를 통합 테스트(integration test)와 헷갈리면 안된다고 한다. 진정한 단위 테스트는 가능한 한 작은 단위의 코드를 고립된 상태로 테스트한다는 것이다. 

 

[단위 테스트의 가치]

저자는 단위 테스트를 수행하는 이유 두가지를 말하였다.

1. 코드 설계가 개선된다. 단위 테스트를 제대로 작성하려면 코드를 가능한 한 작은 단위로 고립시켜야 한다. 그 과정에서 코드 설계의 문제점을 알게 된다. 단위 테스트 작성 원칙을 엄격히 지키기 위해 코드를 고립된 상태로 가능한 한 작게 만들다 보면 그 코드와 단위 설계에 존재하는 온갖 문제가 드러난다.

2. 자동화된 회귀 테스트를 만드는 것이다. 이렇게 작성한 테스트는 소프트웨어의 동작이 저수준에서 반드시 지켜야 할 명세가 되기도 한다.

결론적으로 단위 테스트 그 자체가 명세서이자 회귀 테스가 아닐까?

 

[테스트 주도 개발(TDD)이란 무엇인가?]

TDD의 개본 개념은 코드를 작성하기 전에 테스트부터 작성해서 그 코드가 해야 할 일을 명확하게 정의하는 명세로 쓰는 것이다. TDD에서는 코드를 먼저 작성하고 그 코드에 대한 단위 테스트를 나중에 작성하던 방식을 완전히 뒤집어서 단위 테스트를 먼저 작성하고 그 테스트를 통과할 코드를 나중에 작성한다. 마지막에 코드를 리팩토링. '빨간색, 녹색, 리팩토링'.

"You Ain’t Going to Need It(나중에도 필요하지 않을 거야)". TDD는 YAGNI원칙을 지킬 수 있게 해준다.(?)

추후 읽을 TDD 책에서 보다 자세히...

 

[TDD의 목적은 무엇인가?]

-

 

[TDD의 일반적인 작업 흐름]

-

 

[이 정도는 기본이다]

-

반응형

댓글