공부/Go

Go 테스트 코드 깔끔하게 작성하기

토고미 2024. 8. 28. 19:58

go에서 테스트 코드를 작성하는 방법은 여러가지가 있다.

개인적인 취향으로는 이런 테스트 코드가 가독성도 높고, 결과를 보기도 쉬웠다.

 

먼저 main 코드다

// main.go
package main

import "fmt"

func main() {
	fmt.Println("Hello World!")
}

// 테스트할 함수의 결과 값 유형을 정의
type BodyType int 

const (
	normal BodyType = 1
	small  BodyType = 2
	tall   BodyType = 3

	none BodyType = 4
)

// 테스트할 함수의 input 구조체
type Person struct {
	Name string
	Age  int
	Body *Body
}

type Body struct {
	height int
	weight int
}

// 테스트할 함수
// 사람의 정보를 입력값으로 받아서
// 키가 큰 사람인지, 작은 사람인지 BodyType 타입으로 반환한다.
func HowTall(p *Person) BodyType {
	if p.Name == "" || p.Age == 0 || p.Body == nil {
		return none
	}

	if p.Age < 15 && p.Body.height > 170 {
		return tall
	} else if p.Age >= 15 && p.Body.height > 175 {
		return tall
	}

	return small
}

 

사람의 정보를 input 값으로 받아서 키가 큰 사람인지 작은 사람인지 판단하는

HowTall()이라는 함수를 테스트하려고 한다.

 

반환 타입이 BodyType이라는 따로 정의된 타입을 사용한다는 것에 주의하자.

 

다음은 테스트 코드다.

 

//main_test.go
package main

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestHowTall(t *testing.T) {

    // 1. 시나리오 정의
	tests := map[string]struct {
		p *Person                 // 테스트할 Input
		r BodyType                // 예상되는 결과 값
	}{
		"nil name": {             // 해당 테스트의 이름       
			p: &Person{           // 테스트 Input
				Name: "",
				Age:  5,
				Body: &Body{
					height: 100,
					weight: 15,
				},
			},
			r: none,              // 예상되는 결과 값
		},
		"nil body": {
			p: &Person{
				Name: "togomi",
				Age:  20,
			},
			r: none,
		},
		"tall": {
			p: &Person{
				Name: "togomi",
				Age:  20,
				Body: &Body{
					height: 180,
					weight: 70,
				},
			},
			r: tall,
		},
		"small": {
			p: &Person{
				Name: "togomi",
				Age:  20,
				Body: &Body{
					height: 150,
					weight: 100,
				},
			},
			r: small,
		},
	}

    // 2. 테스트 실행
	for scenario, test := range tests {
		t.Run(scenario, func(t *testing.T) {
			result := HowTall(test.p)
			assert.Equal(t, test.r, result)
		})
	}
}

 

핵심은 아래 구조체를 사용하는 것이다.

tests := map[string]struct { 

       테스트 인풋,

       테스트 결과,

}

 

이렇게 작성 후 테스트 코드를 돌려서 통과하면 아래와 같이 출력된다.

>go test ./...
ok      imsi    0.366s

 

만약 실패하면 아래와 같이 어떤 시나리오에서 실패했는지를 쉽게 알 수있다.

>go test ./...
--- FAIL: TestHowTall (0.00s)
    --- FAIL: TestHowTall/small (0.00s)  // "small" 시나리오에서 실패
        main_test.go:64:
                Error Trace:    E:/Programming/imsi/main_test.go:64
                Error:          Not equal:
                                expected: 4          // 4(none) 결과라고 예상했지만
                                actual  : 2          // 2(small) 결과가 나왔다
                Test:           TestHowTall/small
FAIL
FAIL    imsi    0.438s
FAIL