2024. 3. 13. 18:08ㆍGo
1. 테스트
Golang 에서는 테스트를 지원하고 있습니다.
go test 명령을 이용하여 테스트 코드를 실행할 수 있으며,
아래와 같은 표준 규약을 가지고 있습니다.
- 파일명이
_test.go
로 끝납니다 - 테스트 코드는
func TestXxxxx(t *testing.T)
형태의 함수로 작성합니다- testing 패키지 import
- 테스트 함수의 매개변수는
t *testing.T
하나여야 합니다
1.1. 테스트 실행
1.1.1. 테스트 전체 실행
ex28.1.go 라는 이름으로 아래와 같은 간단한 예제코드를 작성하였습니다.
package main import "fmt" func power(num int) int { return num * num } func main() { n := 5 result := power(5) fmt.Printf("%d의 거듭제곱은 %d\n", n, result) }
이제 테스트 코드를 작성해봅시다.
Go 표준 규약에 맞춰 ex28_1_test.go 라는 이름으로 아래와 같은 코드를 작성하였습니다.
t.Errorf 를 이용하여, 테스트중 에러 발생시에 대한 출력문도 정의할 수 있습니다.
package main import "testing" func TestPower(t *testing.T) { result := power(5) if result != 25 { t.Errorf("power(5)의 결과는 25입니다. 하지만 결과가 %d가 나왔습니다.", result) } }
go test 명령을 사용하기 위해서는, 기존 코드가 모듈로 정의되어있어야 하므로
모듈을 생성한 후,
go mod init goplayground/ex28.1
테스트 코드를 실행합니다.
테스트가 모두 통과되었기 때문에 아래와 같이 PASS 가 출력되었습니다.
go test
PASS
ok goplayground/ex28.1 0.496s
테스트 코드 실행 중, 오류가 발생되면 아래와 같이 에러 코드와 함께 FAIL이 출력됩니다.
--- FAIL: TestPower (0.00s) ex28_1_test.go:8: power(5)의 결과는 25입니다. 하지만 결과가 50가 나왔습니다. FAIL exit status 1 FAIL goplayground/ex28.1 0.599s
1.1.2. 특정 테스트 함수만 실행
테스트 실행 중, -run 테스트명 옵션을 이용하면 특정 테스트만 실행시킬 수 있습니다.
go test -run TestPower
PASS
ok goplayground/ex28.1 0.463s
1.2. assert
testify 외부 패키지의 assert
먼저, go get 명령어를 이용하여 외부 패키지를 설치합니다.
go get github.com/stretchr/testify
그 후, testify 패지키 내의 assert 패키지를 import하여 assert 패키지를 활용하여 테스트 코드를 작성합니다.
기본적으로 assert 패키지 내의 함수들은 첫번째 인자로 TestT(= *testing.T) 객체를 받지만,
func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool
assert.New(t)
로 생성한 객체를 활용하면, 맨 첫번째 인자에 TestingT를 입력하는 것을 생략할 수 있습니다.
package main import ( "github.com/stretchr/testify/assert" "testing" ) func TestPower2(t *testing.T) { assert := assert.New(t) assert.Equal(25, power(5), "power(5)의 결과는 25입니다") }
assert 패키지 내에는 아래와 같은 함수를 제공하고 있습니다.
조건에 만족하지 않을시 테스트 FAIL과 함께 msgAndArgs를 출력합니다.
- func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool
- 인자로 입력받는 두 값(expected, actual)을 비교하여 같을 경우 테스트 성공
- func Greater(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool
- expected > actual 일 경우 테스트 성공
- func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool
- object의 개수가 length과 같을 경우 테스트 성공
- func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool
- object가 nil이 아닐경우 테스트 성공
- func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool
- expected != actual 일 경우 테스트 성공
2. 벤치마크
Go에서는 코드 성능을 검사하는 벤치마크 기능을 지원합니다.
벤치마크는 아래와 같은 표준 규약을 가지고 있습니다.
- 파일명이
_test.go
로 끝납니다 - 테스트 코드는
func BenchmarkXxxxx(b *testing.B)
형태의 함수로 작성합니다- testing 패키지 import
- 테스트 함수의 매개변수는 `b *testing.B 하나여야 합니다
먼저 벤치마크 기능을 이용하여 성능 테스트를 하기 위한 코드를 작성하였습니다.
package main import "fmt" func fibonacci1(n int) int { if n < 0 { return 0 } else if n < 2 { return n } return fibonacci1(n-2) + fibonacci1(n-1) } func fibonacci2(n int) int { if n < 0 { return 0 } else if n < 2 { return n } first := 0 second := 1 result := 0 for i := 2; i <= n; i++ { result = first + second first = second second = result } return second } func main() { fmt.Println(fibonacci1(10)) fmt.Println(fibonacci2(10)) }
벤치마크를 돌리기 전에, fibonnaci1, fibonnaci2 함수가 원하는대로 작 돌아가는지 테스트 코드로 확인합니다.
package main import ( "github.com/stretchr/testify/assert" "testing" ) func TestFibonnacci1(t *testing.T) { assert := assert.New(t) assert.Equal(0, fibonacci1(-1), "fibonacci1(-1) 결과는 0이어야 합니다") assert.Equal(0, fibonacci1(0), "fibonacci1(0) 결과는 0이어야 합니다") assert.Equal(1, fibonacci1(1), "fibonacci1(1) 결과는 1이어야 합니다") assert.Equal(21, fibonacci1(8), "fibonacci1(8) 결과는 21이어야 합니다") assert.Equal(55, fibonacci1(10), "fibonacci1(10) 결과는 55이어야 합니다") } func TestFibonnacci2(t *testing.T) { assert := assert.New(t) assert.Equal(0, fibonacci2(-1), "fibonacci2(-1) 결과는 0이어야 합니다") assert.Equal(0, fibonacci2(0), "fibonacci2(0) 결과는 0이어야 합니다") assert.Equal(1, fibonacci2(1), "fibonacci2(1) 결과는 1이어야 합니다") assert.Equal(21, fibonacci2(8), "fibonacci2(8) 결과는 21이어야 합니다") assert.Equal(55, fibonacci2(10), "fibonacci2(10) 결과는 55이어야 합니다") }
PASS
ok goplayground/ex28.2 0.658s
각 벤치마크 함수에서 b.N 만큼 반복문을 실행합니다.
Go에서는 N값을 적절히 증가시키면서 충분히 테스트를 하여 함수 성능을 측정해줍니다.
package main import ( "github.com/stretchr/testify/assert" "testing" ) func BenchmarkFibonacci1(b *testing.B) { for i := 0; i < b.N; i++ { fibonacci1(20) } } func BenchmarkFibonacci2(b *testing.B) { for i := 0; i < b.N; i++ { fibonacci2(20) } }
-bench .
옵션을 이용하여 현재 모듈에 있는 벤치마크를 테스트를 실행합니다.
go test -bench .
goos: darwin goarch: arm64 pkg: goplayground/ex28.2 BenchmarkFibonacci1-10 48760 24825 ns/op BenchmarkFibonacci2-10 167900041 7.157 ns/op PASS ok goplayground/ex28.2 3.546s
fibonacci1 함수는 24825 ns 가 걸렸고, fibonnaci2 함수는 7.157ns 가 걸렸습니다.
fibonacci1 함수가 재귀함수를 사용하고 있기 때문에 성능이 현저히 떨어지는 것을 확인할 수 있었습니다.
'Go' 카테고리의 다른 글
[Go] 18. 채널 (0) | 2024.03.12 |
---|---|
[Go] 17. 고루틴 (0) | 2024.03.11 |
[Go] 16. 에러 핸들링 (0) | 2024.03.10 |
[Go] 15. 자료구조 - list, ring, map (0) | 2024.02.05 |
[Go] 14. 함수 고급편 (0) | 2024.02.04 |