
ADD(Artificial Intelligence Driven Development; 내가 지은 단어) 를 진행하며, 오히려 기본기가 더 중요하다는 점을 실감하고 있는 요즘이다.
가장 최근에 읽었던 여러 아티클만 봐도, 좋은 코드란 무엇인가? 또 나는 좋은 코드의 기준을 잘 알고 있는지? 에 대한 고민을 끝없이 하고 있다.
좋은 코드를 잘 알고 있어야, 충분히 좋은 생산물이 나올 수 있기 때문이다.그러던 중, 백엔드 개발자에게 바이블로 취급되는 몇몇 책을 접하게 되었고 시간이 날 때마다 완독을 목표로 조금씩 읽을 예정이다.
제목에서 언급했듯이 이번에 다룰 TDD도 조금씩 알고 있었던 내용이지만, 당연히 따라야 하는 내용이지! 라는 생각을 갖고 있었지만, 마음에 와닿지 않았던 과거가 있었다. 그리고 지금은 와닿을 순간이 왔다고 생각했기에 TDD 의 Red-Green Refactor 에 대해 정리해보고자 한다.
테스트 코드를 통해 개발자가 느끼는 두려움을 관리하고, 결함이 적으면서도 설계가 깔끔한 코드를 작성하자.
개발의 리듬 구축하기
가장 빠른 방법을 찾는다.실패 로 간주한다.아직 존재하지 않는 클래스나 메서드를 작성하여 호출하는 단계이기 때문이다.최소한의 코드만 작성한다.성공하게 만드는 것이다.아래 예제는 책에서 다뤄지는 금액 곱셈 예제를 발췌했다.
이때,
Dollar클래스는 존재하지 않는다.
public void testMultiplication() {
Dollar five = new Dollar(5);
five.times(2);
assertEquals(10, five.amount);
}
이때, Kent Beck 은 테스트를 통과시키기 위한 최단 루트로 하드코딩을 권장한다.
class Dollar {
int amount = 10; // 테스트를 통과시키기 위한 최소한의 하드코딩!
Dollar(int amount) {}
void times(int multiplier) {}
}
실제 코드의
10과 테스트 코드의 (5 * 2) ` 사이의 중복을 발견하고, 이를 수식으로 바꾼다.
class Dollar {
int amount;
Dollar(int amount) {
this.amount = amount;
}
void times(int multiplier) {
amount *= multiplier; // 하드코딩을 실제 로직으로 교체
}
}
줄인다 의 정의는 다음과 같다.
책 속에서 말하는 이유는 다음과 같다.
① 제어(Control): "심리적 확신과 문제 범위의 축소"
초보 개발자가 처음부터 실제 로직(amount * multiplier)을 짜다가 실수로 amount + multiplier라고 적었다고 가정했을 때, 개발자는 내가 짠 로직이 틀렸나?' 와 '내 테스트 코드가 잘못됐나?'라는 두 가지 변수를 동시에 고민해야한다.
② 설계의 명확성: "추상화를 향한 힌트 발견"
Kent Beck은 구현 코드의 10과 테스트 코드의 5 * 2가 중복(Duplication) 이라고 한다.
이를 삼각 측량(Triangulation) 과 연결시키면 다음과 같다.
만약 상수 10만 적고 넘어가면 어떻게 될까? 다른 값(예: $5 * 3)을 넣었을 때 테스트가 깨질 것이다.
이때, Kent Beck은 두 번째 테스트 케이스를 추가하라고 한다.
testMultiplication(5, 2) -> 구현에 10 적음 (Green)
testMultiplication(5, 3) -> Red! (이제 10으로는 부족함)
두 테스트를 모두 만족하는 일반적인 해인 amount * multiplier를 작성함 (Green)
동작하는 깔끔한 코드(Clean code that works)를 얻을 수 있다.
지금을 기점으로 테스트를 먼저 작성해보려는 시도를 해볼 것이다. 그리고 시간에 쫓겨서 테스트 코드를 작성하지 않았던 과거처럼 느릴 것 같다는 생각이 들었다.
하지만, AI 와 함께 개발하는 지금 AI 가 우후죽순으로 쏟아내는 코드를 더 좋은 품질로 도출시키기 위해선, 더 좋은 설계서가 필요하고 이를 위해 개발자인 내가 무엇을 원하는지 또는 무엇을 구현하려고 하는지 를 명확하게 인지하고 전달할 수 있어야 한다고 생각한다. 🤔