GO Test code - 1일차 golang에서 테스트 코드 작성, coverage 확인 방법

0

GO Test

목록 보기
1/1

Simple Testing

1. basic golang test

golang에서의 test code는 test할 대상 코드이름이 xxx.go라면 xxx_test.go라는 파일로 만든다. 가령 main.go 파일을 test하기위해서 만든 test code는 main_test.go가 된다.

재밌는 것은 다른 프로그래밍 언어는 test code만 있는 폴더가 따로 있는 반면에 go에서는 test할 코드 바로 옆에 둔다. 가령 다음과 같이 두면 된다.

└── lecture1
    ├── main.go
    └── main_test.go

test할 파일인 main.go와 test code인 main_test.go 파일, 이들을 한 곳에 묶에 두는 것이 재밌는 특징이다.

다음과 같이 main.go안에 IsPrime함수가 있다고 하자. 이를 test하고 싶다면 어떻게 만들어야할까?

  • main.go
func IsPrime(n int) (bool, string) {
	if n <= 0 || n == 1 {
		return false, "negative value and 0 ,1 is not a prime number\n"
	}
	for i := 2; i <= n/2; i++ {
		if n%i == 0 {
			return false, fmt.Sprintf("%d that is not a prime number\n", n)
		}
	}
	return true, fmt.Sprintf("%d that is a prime number\n", n)
}

main_test.go안에 test code를 쓸 때는 다음과 같이 쓴다.

  • main_test.go
package main

// or Test_isPrime
func TestIsPrime(t *testing.T) {

}

package는 테스트할 코드가 있는 package명과 같거나 _test접미사로 붙여준다. 가령 test할 package이름이 main이라면 test code의 package이름도 main이거나 main_test로 하는 것이다. 또한, test 함수 이름에는 반드시 대문자로 시작하는 Test 접두사를 붙여야한다. 그리고 그 다음에 나오는 이름은 반드시 대문자가 처음에 나오거나, _로 시작해야한다. 따라서 테스트 함수의 이름 형식은 다음과 같다. TestXxx, Test_xxx 그렇지 않으면 에러가 발생할 것이다.

또한 파라미터로 testing.T를 받아야하고 리턴값은 없어야 한다. 이것이 기본적인 테스트 함수 모양이다. testing.T 함수를 통해 test에 필요한 기능들을 제공받을 수 있다.

이제 test code를 만들어보자

package main

import "testing"

func TestIsPrime(t *testing.T) {
	testValue := 0
	result, msg := IsPrime(testValue)
	if result {
		t.Errorf("with %d as test parameter, got true, but expected false[%s]", testValue, msg)
	}

	testValue = 7
	result, msg = IsPrime(testValue)
	if !result {
		t.Errorf("with %d as test parameter, got true, but expected false[%s]", testValue, msg)
	}
}

실행하려면 test code가 있는 곳에 다음의 명령어를 쳐준다.

go test -v

다음과 같이 t.Errorf를 사용하면 테스트가 실패한 경우에 로그를 보여준다. 0의 경우 IsPrimefalse이므로 if result문을 넘어간다. 7의 경우 IsPrimetrue이므로 if !result문을 넘어간다. 실험으로 if result 문의 !를 바꿔주면 다음과 같은 로그가 발생한다.,

=== RUN   TestIsPrime
    main_test.go:9: with 0 as test parameter, got true, but expected false
--- FAIL: TestIsPrime (0.00s)
FAIL
exit status 1
FAIL    test-practice   0.001s

기대했던 결과와 실제 값이 달라 에러가 발생하는 것을 확인할 수 있다.

golang test code의 기본에 대해서 정리하자면 다음과 같다.

  • test할 go파일과 같은 위치에 둘 것
  • naming convention은 test할 go파일을 접두사로 xxx_test.go 형식으로 만들 것
  • xxx_test.go파일의 package는 test할 go파일과 같은 package이름이거나 xxx_test로 지을 것
  • test function은 대문자로 Test접두사를 가질 것
  • Test접두사 뒤에는 test할 function 이름을 뒤에 붙일 것, 단 맨 앞 글자는 대문자일 것 ex) ``TextXxx
  • test function은 파라미터로 *testing.T를 가지고 리턴값은 없을 것

2. go coverage

golang에서는 기본적으로 test coverage를 알려준다.

go test -cover

결과로 다음과 같다.

PASS
coverage: 83.3% of statements
ok      test-practice   0.001s

더 명확하게 어디가 테스팅이 안되었는 지 확인하고 싶다면 test profile을 만들면 된다.

go test -coverprofile=coverage.out

다음의 명령어로 coverage에 관한 정보를 담은 coverage.out파일을 만들 수 있다.

  • coverage.out
mode: set
test-practice/main.go:3.14,5.2 0 0
test-practice/main.go:7.26,8.22 1 1
test-practice/main.go:11.2,11.27 1 1
test-practice/main.go:16.2,16.13 1 1
test-practice/main.go:8.22,10.3 1 1
test-practice/main.go:11.27,12.15 1 1
test-practice/main.go:12.15,14.4 1 0

그러나 이렇게 보기엔 어렵다. 그래서 html파일로 보기좋게 만들도록 하자.

go tool cover -html=coverage.out

html파일이 열리고 어디에 test에 안되었는 지 확인할 수 있다.

html을 파일로 남기고 싶다면 -o옵션을 같이하면 된다.

go tool cover -html=coverage.out -o cover.html

함수 coverage를 확인하고 싶다면 다음의 명령어를 치면 된다.

go tool cover -func=coverage.out

다음과 같이 각 function에 대한 coverage가 나온다.

test-practice/main.go:3:        main            0.0%
test-practice/main.go:7:        IsPrime         83.3%
total:                          (statements)    83.3%

0개의 댓글