coverprofile
플래그로 어느 코드를 테스트 코드가 커버하는지 시각적으로 볼 수 있음단위 테스트를 작성할 때, 외부에 드러나는 부분에 집중하는 것이 좋음
그래야 구현 코드가 변경되더라도 테스트는 변경할 필요 없음
고 언어는 폴더에 든 모든 파일이 동일한 패키지에 속하지만, 테스트 파일은 _test 패키지에 속한다는 예외가 있음
func TestCustomer1(t *testing.T) {
customer, err := createCustomer1("foo") // 구조체를 생성하고 그 과정에서 에러 발생했는지 확인
if err != nil {
t.Fatal(err)
}
// ...
_ = customer
}
func createCustomer1(someArg string) (Customer, error) {
// Customer 구조체를 생성함
customer, err := customerFactory(someArg)
if err != nil {
return Customer{}, err
}
return customer, nil
}
func TestCustomer2(t *testing.T) {
customer := createCustomer2(t, "foo") // 유티리티 함수를 호출할 때 t를 전달
// ...
_ = customer
}
func createCustomer2(t *testing.T, someArg string) Customer {
customer, err := customerFactory(someArg)
if err != nil {
t.Fatal(err) // Customer 구조체를 생성할 수 없으면 곧바로 테스트를 실패로 만든다
}
return customer
}
테스팅 함수 문맥에서 *testing.T
변수를 유틸리티 함수(createCustomer
)로 전달하면 에러 처리 과정을 훨씬 간결하게 만들 수 있음
테스팅 환경을 마련해야 할 경우도 있음
예를들어, 통테 과정에서 특정한 컨테이너를 구동했다가 멈춰야 할 때는 테스트 패키지마다 설정, 해제(teardown) 함수를 호출할 수 있음
테스트 단위로 호출하려면 사전 동작으로 설정함수를 호출하고 defer로 해제 함수를 호출함
func TestMySQLIntegration(t *testing.T) {
setupMySQL()
defer teardownMySQL()
// ...
}