백엔드 Back-end/테스트 Test

전통적인 개발과 테스트 주도 개발, 그리고 애자일

Tap to restart 2023. 6. 1. 22:00
반응형

팀내에서 전통적인 개발과 테스트 주도 개발, 그리고 애자일을 주제로 발표를 했다. 요며칠 밤마다 작업한 결과물이다.
 
슬라이드쉐어에 발표자료를 올려 놓았다. 
긴 문장도 넣었지만, 짧은 문장으로 표현한 것도 있어서 잘 이해가 안 될 수도 있어 발표 설명을 각 장마다 적어 본다.
 

발표 슬라이드

https://www.slideshare.net/taptorestart/ss-258182158

 

 
 

발표 스크립트

지금 여기 모인 대부분의 개발자들이 하는 개발 방식은 전통적인 개발에 가깝습니다.
 

전통적인 개발에서는 기능 구현부터 합니다. 기능을 구현하고, POSTMan 같은 테스트 툴, 웹 등을 활용해서 기능을 구현한 부분을 개발자가 직접 테스트합니다. 
 

그림 속 네모 칸은 기능을 뜻합니다. 이미 구현한 기능이 2개이고, 세 번째 기능을 구현한다고 할 때 전통적인 방식으로 개발해도 큰 문제는 없습니다. 세 번째 기능을 구현하고 이미 구현한 기능을 일일이 테스트해도 그리 길게 시간이 걸리지 않으니까요. 
 

하지만 이미 구현된 기능이 엄청나게 많다면 어떻게 될까요?
 

작업하고 있는 부분과 관계가 없어 보이는 멀리 떨어진 부분에서 오류(불로 표현했습니다)가 발생합니다. 기능 개발을 할 때 테스트를 하더라도 작업 중인 기능과 관계가 없어 보이는 곳까지 테스트하지는 않습니다. 따라서 저 오류는 QA 때나 QA 때도 발견이 안 되어서 실제 고객들한테 배포가 된 뒤에 발견되기도 합니다. 
 

시간이 지남에 따라 기능이 많아지고 기능을 추가하거나 변경할수록 비용이 많이 듭니다. 기능이 많아질수록 전체 기능을 테스트 하기 위해서는 많은 인력과 시간이 필요하게 되기 때문이죠. 
 

과연 이런 개발 방식밖에 없을까? 더 좋은 개발 방식은 없는 것일까 고민한 한 남자가 있습니다. 그의 이름은 켄트 벡입니다.
 

정신나간 것 같은 아이디어를 하나 냅니다. 
 

제가 말한 것이 아니라 그의 책에 정말 '정신나간 것 같은 아이디어'라고 적혀 있답니다. 
 

그의 정신나간 것 같은 아이디어에서 탄생한 것이 바로 테스트 주도 개발입니다.
전기로 작동하는 기계를 영어로 번역하면 a machine driven by electricity 입니다(출처: drive 다음 사전).
Test-driven Development는 development driven by test라고 적을 수도 있습니다. 곧 테스트로 작동하는 개발이란 뜻입니다. 개발의 핵심이자 동력이 바로 테스트라는 의미입니다.
 

테스트 주도 개발은 기존 개발 방식을 뒤집습니다. 말그대로 전복입니다. 혁명과 같은 변화죠. 테스트 코드를 작성하고 기능을 구현하자는 주장입니다. 제가 켄트 벡의 친구였다면, 이렇게 말했을지도 모릅니다.
"너 정말 미쳤구나. 그게 말이 돼?!"
 

테스트 주도 개발의 궁극적인 목표는 작동하는 깔끔한 코드입니다. Clean code that works. 결국 목표는 두 가지입니다. 작동과 깔끔함. 두 가지 목표를 한꺼번에 이룰 수는 없습니다. 하나씩 달성해야 합니다. 작동과 깔끔한 코드 둘 중 우선 달성해야하는 것은 바로 작동이라고 켄트 벡은 말합니다.
 

테스트 주도 개발의 규칙은 "1번 오직 자동화된 테스트가 실패할 경우에만 새로운 코드를 작성한다 2번 중복을 제거한다"입니다. 1번 규칙 이 바로 작동이고 2번 중복을 제거하는 것이 깔끔한 코드를 목표로 하는 것을 알 수 있습니다.
 

프로그래밍 순서는 빨강/초록/리팩터링 순서입니다. 실패하는 작은 테스트를 작성합니다. JUnit, Pytest 등 테스트 자동화툴을 사용하면 실패하는 경우 빨간색 원으로 표시가 됩니다. 그래서 빨강입니다. 빨리 테스트를 통과하게 만듭니다. 통과하면 초록색 원으로 표시가 됩니다. 그래서 초록입니다. 작동하는 코드가 우선입니다. 이제 리팩터링을 통해서 깔끔한 코드를 만들 차례입니다. 테스트를 통과하게 만드는 중에 생겨난 중복을 제거합니다. 중복을 제거하다보면 또 빨간불이 뜰 것이고, 그것을 해결하면 초록불이 뜰 것입니다. 또 리팩터링을 하고.. 이 과정을 계속 반복합니다.
 

파이썬을 예로 들면 위 예처럼 덧셈 테스트를 만듭니다. 함수명은 sum으로 해야지 하면서 함수 선언도 없이 위처럼 테스트 코드에 넣습니다. 그리고 나서 sum 함수를 만듭니다. 제대로 3이 나올 때까지요. 
 

테스트 주도 개발에 대해서 사람들이 가장 많이 하는 말입니다. 언제 테스트를 작성하냐, 바빠 죽겠는데, 기능 요구사항이 산더미인데... 이 말은 테스트 주도 개발은 느리다란 말입니다. 정말 느릴까요?
 

2개 테스트를 만들고 기능도 만들었습니다. 초록 원이 바로 테스트 코드 통과 표시입니다. 그리고 세 번째 기능을 만듭니다. 물론 테스트부터 작성합니다. 그러니 기능만 구현하는 경우보다 느립니다. 초반에는 기능만 구현하는 경우가 더 빠릅니다.
 

기능이 많아졌을 때입니다. 테스트 코드를 모두 작성해 놓아서 초록불로 표시가 뜹니다.
 

리팩터링 중에 여기 저기 빨간불이 들어옵니다. 자동화된 테스트를 계속 하기 때문에 오류를 바로 인지하게 됩니다. 오류를 바로 고칩니다. QA 때 오류가 나타나는 경우가 확 줄어듭니다.
 

테스트 주도 개발을 할 경우 시간이 지남에 따라 변경 비용이 완만하게 증가합니다. 앞에서 살펴봤던 전통적인 개발의 변경 비용 곡선을 떠올려 보십시오. 얼마나 큰 차이인지. 기능이 많아질수록 테스트 주도 개발이 빠릅니다. 그리고 안전합니다. 아파트로 치면 각 호마다 각 방마다 화재 경보기가 달려 있어 불이 나면 어디서 나는지 관리사무소에서 바로 알 수 있는 것과 비슷합니다.
 

다른 개발자 얘기도 들어볼까요. 마틴 파울러입니다. 그 유명한 의존성 주입 등 용어를 유행시킨 분이죠. 
 

바로 그 유명한 리팩터링 책의 저자입니다.
 

그의 이야기를 들어볼까요. 사실 다른 사람에게 이런 식으로 개발하라고 설득하기는 녹록지 않다고 합니다. 테스트가 실제로 프로그래밍 속도를 높여주는 경험을 직접 해보지 않고서는 자가 테스트의 진가를 납득하긴 어렵습니다. 
테스트 주도 개발은 느리다고 생각하는 사람에게 테스트 주도 개발을 경험하게 할 수 있을까요? 이게 정말 어렵습니다.
 

테스트를 작성하기 가장 좋은 시점은 프로그래밍을 시작하기 전이라고 말합니다. 켄트 벡과 같은 주장입니다.
 

구현보다 인터페이스에 집중하게 되는 장점이란 말은 무슨 의미일까요?
사실 고객 입장에서 구현은 중요하지 않습니다. 어떤 값을 입력했을 때 원하는 결과가 나오는 것이 중요합니다.
앞의 예를 생각해보죠. 더하기를 했을 때 1, 4를 입력하면 5만 나오면 됩니다. 어떻게 구현하든 그리 중요하지 않습니다. 맞습니다. 테스트 코드가 바로 고객이 원하는 것과 같습니다.

코드 완성 시점도 확인할 수 있습니다. 테스트가 통과한 시점입니다.
 

또 다른 분을 만나볼까요? 로버트 마틴입니다. 엉클 밥이란 애칭으로 불리죠. 읽어보지도 않았는데 왠지 모르게 아는 것 같을 정도로 자주 듣는 클린 코드, 클린 아키텍처 등 그 유명한 클린 시리즈 책을 펴낸 분입니다.

그 분이 쓴 책 중 애자일 소프트웨어 개발: 원칙들, 패턴들, 연습들이란 책이 있습니다. 번역서 제목은 역시나 클린 시리즈를 따라서 클린 소프트웨어입니다.
 

켄트 벡의 테스트 주도 개발과 같은 이야기를 하고 있다는 것을 알 수 있습니다.
 

테스트를 기반으로 단계적으로 기능을 추가해나가자는 것. 애자일입니다.
 

각 함수마다 테스트를 갖게 되고 이 테스트는 화재 경보기 같은 역할을 하게 되죠. 
 

중요한 것을 망가뜨릴 염려 없이 함수를 추가하거나 구조를 바꿀 수 있다는 말은 리팩터링을 할 수 있다는 말입니다. 여기서 눈에 띄는 단어는 자유롭게 입니다. 안전할 때 자유롭게 놀 수 있습니다. 안전을 보장해주는 것은 테스트입니다.
 

세 명의 개발자 얘기를 들어봤습니다. 마틴 파울러, 켄트 벡, 로버트 마틴.
 

이 세 사람의 공통점은 무엇일까요? 생각나는대로 말씀해보세요. 맞습니다. 셋 다 남자입니다. 
 

바로 애자일 소프트웨어 개발 선언에 함께 한 17명 중 3명입니다. 작동하는 깔끔한 코드란 말을 했다는 론 제프리도 보입니다. 세 명 모두 테스트 주도 개발을 말합니다. 그리고 세 명 모두 애자일을 말합니다. 테스트 주도 개발과 애자일은 어떤 관계일까요?
 

테스트 주도 개발 없는 애자일이 가능할까요? 어떻게 생각하시는지요?

날마다 모여서 스크럼을 하면 애자일이 되는 것일까요? 애자일 개발 방법론의 기본 바탕 중 하나가 테스트 주도 개발 아닐까요? 테스트 주도 개발 없이 잘 작동하는 기능을 스프린트 때마다 고객에게 인도할 수 있을까요? 자전거를 만드는데 잘 작동하는 바퀴를 만들었습니다. 바퀴 2개를 만들어서 이제 뼈대를 만듭니다. 뼈대를 완성했더니 바퀴가 고장납니다. 이것도 애자일이라고 할 수 있을까요.
 

같이 고민해보면 좋을 거 같습니다. 감사합니다.

반응형