최근에 테스트 주도 개발(Test Driven Development, TDD)에 관해 관심이 있어서 알아보았고,
그러던 중 당근마켓에서 쓴 글을 읽다가 알게된 테이블 주도 테스트라는 것이 있어 새롭게 배운 것 같아
몇개 더 알아보다가 글을 써본다.
https://medium.com/daangn/how-to-write-a-testable-golang-code-4c0e67612bb8
먼저 TDD를 간단하게 설명을 하면 테스트를 통해 개발해보자는 의미로,
개발을 한다음에 테스트하는 구현의 중요성보다 로직이 가질 수 있는 문제점을 생각해보며 개발을 진행한다는 점에서
기존의 개발과는 접근하는 방식이 다르다.
TDD를 왜 쓸까에 대해서 생각해보면 그만큼의 테스트도 없으면 실전에서는 더 무너지기 때문일 거라 생각한다.
실제로 나도 테스트 코드없이 디버깅을 하면서 개발을 진행했다가 다른 사람들에게 나의 로직을 증명할 일이 생기고 보니,
나의 로직을 증명하는 테스트 코드가 필요하다는 걸 절실히 깨달았다.
(이 마저도 없으면 나는 아무 근거도 없이 나의 코드가 된다고 하는 놈이 될 수도 있다.)
Go에서도 TDD가 가능하지만 모처럼 특별한 개념인 테이블 주도 테스트(Table Driven Test)라는 개념이 등장했으니
무엇이 다른지 알아보았다.
테이블 주도 테스트 - Table Driven Test(TDT)
테이블 주도 테스트는 조금 바뀐만큼 사실은 크게 별거는 없다.
TDD(Test Driven Development) 와는 다르게 Table 이라는 개념이 추가됐는데,
여기서의 Table은 DB에서의 Table처럼 여러 개의 테스트 케이스를 한 데 묶은 경우를 테스트 기법을 테이블 주도 테스트라고 한다.
아래는 간단한 TDD 케이스 중 하나를 가져와봤다.
(출처 : https://velog.io/@tmdgh0221/TDD로-배우는-Golang#테스트-코드---arrays)
package sum
import "testing"
func TestSum(t *testing.T) {
t.Run("collection of 5 numbers", func(t *testing.T) {
numbers := []int{1, 2, 3, 4, 5}
got := Sum(numbers)
want := 15
if got != want {
t.Errorf("got %d want %d given, %v", got, want, numbers)
}
})
t.Run("collection of any size", func(t *testing.T) {
numbers := []int{1, 2, 3}
got := Sum(numbers)
want := 6
if got != want {
t.Errorf("got %d want %d given, %v", got, want, numbers)
}
})
}
테스트 내용을 보면 숫자들이 입력되었을 때, 그 합이 want 와 같은지 테스트하는 코드로
테스트 2번 했구나 정도로 이해하고 넘어가보자.
아래는 구글에서 제공하는 Table Driven Test 의 예시다.
(출처 : https://github.com/golang/go/wiki/TableDrivenTests)
var flagtests = []struct {
in string
out string
}{
{"%a", "[%a]"},
{"%-a", "[%-a]"},
{"%+a", "[%+a]"},
{"%#a", "[%#a]"},
{"% a", "[% a]"},
{"%0a", "[%0a]"},
{"%1.2a", "[%1.2a]"},
{"%-1.2a", "[%-1.2a]"},
{"%+1.2a", "[%+1.2a]"},
{"%-+1.2a", "[%+-1.2a]"},
{"%-+1.2abc", "[%+-1.2a]bc"},
{"%-1.2abc", "[%-1.2a]bc"},
}
func TestFlagParser(t *testing.T) {
var flagprinter flagPrinter
for _, tt := range flagtests {
t.Run(tt.in, func(t *testing.T) {
s := Sprintf(tt.in, &flagprinter)
if s != tt.out {
t.Errorf("got %q, want %q", s, tt.out)
}
})
}
}
테스트를 여러 개 두었는데도 코드가 깔끔해보인다.
TDT의 장점을 단적으로 보여주기 위해 의도적으로 코드를 가져왔다.
내 생각에는 테스트 케이스를 여러개 작성하는 것에 비해 테이블처럼 한 데 묶음으로써,
코드가 간결해지고, 가독성도 향상되는 게 장점인것 같다.
케이스를 여러 개 적을 수 있는 상황이라면 TDT가 깔끔해보인다.
참고
https://simplear.tistory.com/23
https://velog.io/@tmdgh0221/TDD로-배우는-Golang
https://github.com/golang/go/wiki/TableDrivenTests
https://medium.com/@dog156987/test-driven-development-tdd-란-무엇인가-59b7b4a65c4
'Programming Language > Go' 카테고리의 다른 글
[Golang] 자료형, 배열, 슬라이스 (0) | 2022.02.23 |
---|---|
[Go] Gin 에러 Error:Field validation for 'Value' failed on the 'required' tag (0) | 2022.02.22 |
[Go] $GOPATH/go.mod exists but should not 에러 (0) | 2022.02.17 |
[Go] Gin 설치 에러 (0) | 2022.02.17 |
[Go] Go 공부 시작 (0) | 2022.02.17 |