본문 바로가기
Language/Go

Go - Go with TDD

by ocwokocw 2021. 12. 4.

참조: https://quii.gitbook.io/learn-go-with-tests/

- 개요

Go 는 자체적으로 testing 모듈을 내포하고 있기 때문에 TDD 를 이용하여 배우기가 수월하다. 참조의 URL 에서는 TDD 를 이용하여 Go 언어의 문법과 유용한 기능들을 다루고 있다. Go 의 공식문서인 A Tour of Go (https://go.dev/tour/list) 를 보고 참조를 학습해도 되지만 다른 프로그래밍 언어에 대한 개념이 있다면 오히려 더 자세한 설명을 해주기 때문에 처음부터 봐도 괜찮다고 생각한다.
 
Go 에 대한 기본적인 모듈, package 개념과 기본적인 실행은 할 수 있다고 가정한다.

- TDD cycle

해당 Site 에서는 TDD 의 프로세스 주기인 RED, GREEN, REFACTOR 3 단계를 반복하면서 코드를 완성해나가고 있다.
 
RED: 개발자는 기능을 구현 했다고 가정하고 해당 함수를 호출하여 기대하는 값을 검사하는 테스트 코드를 작성한다. 구현을 하지 않았으니 당연히 컴파일 오류가 난다. 하지만 한번에 끝내고 싶고 빨리 구현하고 싶은 마음에 이 단계를 소홀히 하면 안되는데, 이 테스트 단계의 코드가 깔끔해야 함수의 인자와 반환 형을 사용하는 입장에서 이해할 수 있고 결국 코드의 완성도가 높아진다. 급한 마음은 금물이다.
 
GREEN: RED 에서 작성한 테스트 코드를 Pass 하기 위한 코드를 작성한다. 이때 컴파일 오류가 나지 않는 최소한의 코드만 작성한 후 테스트를 수행해보아야 하는데, 컴파일은 되지만 본격적인 구현은 하지 않고 최소한의 코드만 돌려서 RED 에서 작성한 테스트코드가 실패값을 뱉어내는지(값을 검사하는 부분을 잘 작성했는지) 확인해야 한다. 그후 Pass 하기 위한 본격적인 구현을 완성한다.
 
REFACTOR: Pass 한 코드를 기반으로 리팩토링을 한다. 변수명을 바꾸거나 중복된 로직을 인지하여 함수로 추출한다. 이 단계에서는 코드의 내부구현이 변경되지 않아야 한다.

- Example code

TDD cycle 에 대한 설명을 보고 구체적으로 와닿지 않을 수 있다고 생각한다. 실질적인 코드 작성과정을 보면서 이해해보도록 하자. integers 폴더를 만들고 adder_test.go 파일을 생성한다.
 
TDD 중 첫번째인 RED 단계를 수행해보자. 더하기 기능을 구현한다고 가정해보자. Test 코드를 아래와 같이 작성한다.
 
package integers

import "testing"

func TestAdder(t *testing.T) {
    sum := Add(2, 2)
    expected := 4

    if sum != expected {
        t.Errorf("expected '%d' but got '%d'", expected, sum)
    }
}
 
 
Add 라는 함수는 2 개의 인자를 받아서 합을 반환한다. 그리고 2와 2를 인자로 넘겼으므로 4가 나와야하고, 4가 나오지 않는다면 오류로 간주한다. 터미널에서 go test 명령어를 수행하면 Add 를 정의하지 않았다고 나올것이다.
 
Test 코드를 작성하면서 이미 Add 함수를 만든 사람이 있을것이다. 당연히 최종적으로는 구현을 해야하지만 지금은 테스트 코드를 작성하는데 집중해야 한다. 내가 Add 함수를 위와 같은 형태로 작성하면 코드를 사용하는데에 무리가 없는지도 생각해보자.
 
이제 GREEN 단계를 수행한다. 컴파일러가 만족하는 최소한의 코드를 작성하자.
 
package integers

func Add(x, y int) int {
    return 0
}
 
 
이 함수를 작성하면서 return x + y 를 곧바로 쓰는 사람도 있을거라고 생각한다. 하지만 내가 테스트함수를 올바르게 작성해서 구현을 잘못했을 때 실패한 메시지가 나오는지 확인하는 과정도 중요하다.
 
이제 test 가 pass 하도록 제대로 구현한다.
 
func Add(x, y int) int {
    return x + y
}
 
 
go test 를 수행하면 원하는 결과가 나올것이다. 
 
이제 REFACTOR 단계를 수행한다. 사실 우리가 작성한 코드는 리팩토링할게 별로 없다. 함수 이름과 인자, 반환형도 사용자가 이해하기에 합리적이다. 실제 업무에서 구현하는 코드 같이 복잡한 로직의 경우 중복코드 추출이나 변수 추출 등 여러가지 할 일이 많을 것이다. 리팩토링을 수행하면서 구현 알고리즘이 변경되지 않도록 주의하자.

- 마치면서

TDD에 기반한 Go 배우기에서 소개하는 방식을 간단히 소개하였다. Learn Go with tests(https://quii.gitbook.io/learn-go-with-tests/) 에서는 한글로 번역도 많이 되어있고 설명도 친절하게 해놓아서 공부하기에 무리가 없을거라고 생각한다. TDD에 기반한 코드를 배워보면서 Go 를 같이 배우고 싶다면 유용한 Site 인것 같다.

'Language > Go' 카테고리의 다른 글

Go - array, slice, test coverage  (0) 2021.12.04
Go - Iteration & Benchmark  (0) 2021.12.04
Go - Go 와 Gin 을 활용한 RESTful API 개발  (0) 2021.11.28
Go - compile 과 install  (0) 2021.11.28
Go - test  (0) 2021.11.28

댓글