예전에는 테스트가 멈추면 fmt.Println을 여기저기 넣고 다시 돌렸어요. 요즘은 다르게 해요. 타임아웃을 짧게 걸어 두면, 시간이 다 됐을 때 testing 패키지가 패닉을 내면서 모든 고루틴의 스택을 찍어 줘요.
package hang
import "testing"
func TestHandoff(t *testing.T) {
results := make(chan int)
go func() {
results <- 42 // nobody reads this
}()
done := make(chan struct{})
<-done
}
go test -timeout 3s를 돌리면 panic: test timed out after 3s, 실행 중인 테스트 목록, 그리고 고루틴이 하나씩 나와요. 고루틴마다 대괄호 안에 대기 이유가 있고, 지금 서 있는 줄이 나와요. 여기서는 중요한 두 개가 쉽게 보여요. 하나는 <-done 줄에서 [chan receive], 다른 하나는 results <- 42에서 [chan send]이고, 그 아래 created by 줄이 누가 띄웠는지 알려 줘요. 고루틴마다 얼마나 기다렸는지도 찍혀서 오래된 누수와 방금 생긴 걸 쉽게 구분할 수 있어요.
왜 그렇게 오래 print로 버텼는지 모르겠어요. 아마 기본 타임아웃이 10분이라 덤프를 볼 만큼 기다린 사람이 없어서였겠죠.