Agile 방벙론, TDD에 대한 개념과 TDD를 사용하는 이유 등에 대해서 정리해본다.
BDD에 대한 간략한 설명도 덧붙이도록 한다.
ref. wiki-애자일 소프트웨어 개발
Agile : 기민한, 좋은 것을 빠르고 낭비없게 만드는 것
전통적 개발 프로세스
애자일 개발 프로세스
애자일 방법론은 소트프웨어 개발 방법에 있어서 아무런 계획이 없는 개발 방법과 계획이 지나치게 많은 개발 방법들 사이에서 타협점을 찾고자 하는 방법론이다.
🤔계획이 없는 방법론 ... 앞으로의 일을 예측하기 힘들고, 효율적이지 못하다는 점에서 취약점을 가지고 있다
🤔그럼 계획이 엄청난 방법론은 ... 형식적인 절차를 따르는데 필요한 시간과 비용 증가, 전체적인 개발 흐름 자체를 느리게 한다.
애자일 방법론은 문서를 통한 개발이 아니라, 실질적인 코딩을 통한 방법론이라고 할 수 있다.
애자일 개발 프로세스은 특정 개발 방법론을 가리키는 말은 아니고 "애자일" 개발을 가능하게 해주는 다양한 방법론 전체를 일컫는 말이다.
우리는 소프트웨어를 개발하고, 또 다른 사람의 개발을 도와주면서 소프트웨어 개발의 더 나은 방법들을 찾아가고 있다.
이 작업을 통해 우리는 다음을 가치있게 여기게 되었다 :
✔️공정과 도구보다 개인과 상호작용을
✔️포괄적인 문서보다 작동하는 소프트웨어를
✔️계약 협상보다 고객과의 협력을
✔️계약을 따르기보다 변화에 대응하기를
이 말은, 왼쪽에 있는 것들도 가치가 있지만, 우리는 오른쪽에 있는 것들에 더 높은 가치를 둔다는 것이다.
💁 애자일의 핵심 : 협력과 피드백
애자일 방법론은 개발 주기(=스프린트)를 통해 프로젝트의 방향과 목표를 가늠하도록 도와준다.
단축된 일의 반복과 제품 기능 개발에 중점을 두기 때문에 애자일 방법론은 반복적이고 증가적이라고 표현된다.
폭포수 모델에서 개발자들은 단 한 번, 프로젝트의 모든 측면을 검토하는 것과 달리 일정한 주기를 통해 지속적으로 모든 측면을 재검토할 수 있다.
특정 스프린트마다 프로젝트를 재검토하며 처음과 또 다른 방향으로 전환할 기회를 주어준다.
스크럼이 애자일 개발 프로세스로 불리는 개발 방법론 중 하나라는 사실을 알았다! 🤔
"30일마다 동작 가능한 제품을 제공하는 스프린트(Sprint)를 중심으로 하고 있다. 매일 정해진 시간에 정해진 장소에서 짧은 시간의 개발을 하는 팀을 위한, 프로젝트 관리 중심의 방법론이다."
ref. https://gmlwjd9405.github.io/2018/06/03/agile-tdd.html
ref. https://web.archive.org/web/20070628064054/http://xper.org/wiki/xp/TestDrivenDevelopment
ref. TDD에 대한 오해와 진실
int testAdd(){
assert 5+4 == add(5,4)
assert -4+9 == add(-4,9)
}
📌결정과 피드백 사이의 갭을 조정하기 위한 테크닉
📌테스트 코드를 먼저 작성하는 것은 목표를 시각화하는 작업이다.
기대하는 input, output 또는 메소드의 signature(메소드 이름과 파라미터) 등을 미리 고민하게 되는데 이는 모듈 개발자와 사용자에게 모두 도움이 된다.
즉, TDD는 구현보다 인터페이스에 집중하게 해준다.
📌TDD를 수행하다보면 '어떻게'보다 '무엇'에 집중하게 된다.
객체가 어떻게 만들어졌는가, 혹은 어떤 방식으로 비즈니스를 수행하는지 보다는 객체가 무슨 역할을 가져야 하는지, 그리고 이러한 역할을 위해 무엇을 노출해야하는지 등에 집중할 수 있다.
초기에 테스트 코드를 작성하는 부담으로 인해 비용이 더 들고 개발 속도를 저하시킨다.
👉테스트 코드를 먼저 작성하면 개발해야하는 것에 대한 목적과 요소들을 명확히할 수 있다. 이는 구현체 코드를 작성할 때 고민 시간을 줄여준다.
👉테스트 코드를 작성하기 어렵다? = 설계가 잘못되었음을 암시(해주기도 한다)
👉이는 설계 미스로 인한 유지 보수 비용의 증대를 대폭 감소 시킬 수 있음을 뜻한다.
테스트 코드가 없다면, 요구 사항이 변경되는 상황에서..
👉변경된 요구사항을 구현한 후 연관된 요소들이 문제 없을 것을 확신할 수 있는가?
👉TDD는 코드 수정에 대한 불안감을 해소시켜주고 즉각적으로 확신을 줄 수 있다.
소프트웨어 복잡도가 증가함과 비례하여 테스트 코드를 추가로 작성하는 부담이 있다
👉오히려 TDD를 적용하지 않는다면 복잡도가 증가함에 따른 유지보수 비용이 기하급수적으로 증가하는 것이 일반적
👉일정수준까지는 테스트 코드 작성이란 부담이 있을 수 있으나, 특정 시점을 기준으로 거의 비용이 증가하지 않고 일정하게 유지된다.
테스트 코드를 작성해야하는데 필요한 모듈이 미처 완성되지 않은 상황에서 우리는 'Mock'을 활용할 수 있다!! (🤔애자일-TDD-Mock이 이런관계가 있다는걸 처음 알았다.)
단, Mock 객체가 행위에 대한 기능 검증을 빠르게 수행할 때는 도움이 되지만 너무 남용할 경우 테스트 코드 자체의 가치를 깨뜨릴 수 있다.
예를 들어,
Mock으로 처리한 모듈에 사용되는 argument가 이전에는 유효했지만, 현재는 유효하지 않은 경우...
더 이상 기존의 Mock 객체를 이용한 테스트 결과가 시스템이 올바르게 동작함을 보장하지 못한다.
Top-Down 방식으로 설계 및 시나리오를 잡고, Bottom-Up 방식으로 기능에 대한 코드 구현을 구체화 시키면서 문제점을 차례로 해결한다.
📌디자인은 Top-Down, 기능은 Bottom-Up
처음부터 완벽한 코드를 작성하는 것에 집착하지 말자.
이는 개발 속도를 저하하며 개발자의 정신건강🤬에도 좋지않다.
클라이언트 관점에 기대하는 바를 충족하는 정도로 빠르게 구현한 뒤 테스트 코드를 깨트리지 않으며 리팩토링을 해나간다.
📌TDD는 이렇게 해야한다는 틀에 갖히지 말자
'반드시 툴(단위 테스트 프레임워크)을 써서 이렇게 해야된다.'라는 생각/규칙에 얽매이는 것은 애자일이 아니다.
규칙에 얽매이면 결국 똑같은 테스트를 copy&paste하는 것이다. 도구와 규칙에 집착하면 TDD는 어려워진다.
Given / When / Then 템플릿을 통해 기대 행위에 대한 명세화에 초점을 맞춘다.
이는 테스트 메소드 각각의 시나리오 작성을 수월하게 할 수 있도록 돕는다.
테스트 코드는 항상 거의 최신을 유지할 가능성이 높으며, 이 자체가 메소드에 대한 사용법이나 예외 등을 담고 있음으로 좋은 샘플 코드로서도 가치가 있다.
또한, Given / When / Then 구조의 코드를 통해 테스트 코드를 읽는 것만으로도 다른 구현체와의 의존성을 파악할 수 있다. (물론 가독성이 확보된 경우)
If you appreciate challenging video games, run 3 will pleasantly surprise you. I had a lot of fun playing a new game that I just learned about. This challenging running game will put your skills to the test. haphazardly down the incline.