Quick Flow
go test -cover ./...
go test -coverprofile=coverage.out ./...
go test -coverpkg=./... -coverprofile=coverage.out ./...
go tool cover -func=coverage.out
go tool cover -html=coverage.outcoverage는 "테스트가 어떤 statement를 실행했는가"를 보여 주는 신호이지, 동작이 모두 맞다는 증명은 아닙니다. 기본 coverage는 각 test가 자기 package만 분석하므로 service test에서 repository까지 함께 분석해야 하면 -coverpkg 범위를 명시합니다.
coverage 해석
-cover는 statement 실행 비율을 보여 준다
go test -cover는 테스트 실행 중 어떤 statement가 실행됐는지 계측하고 coverage 비율을 출력합니다. 이 수치는 빠른 신호로 유용하지만, 테스트 품질을 직접 증명하지는 않습니다. 의미 없는 assert 없이 코드를 실행하기만 해도 coverage는 올라갈 수 있고, statement coverage가 높아도 조건의 양쪽 결과나 오류 반환을 모두 검증했다는 뜻은 아닙니다.
coverprofile은 누락 위치를 찾는 데 쓴다
숫자만 보면 어떤 분기와 함수가 빠졌는지 알기 어렵습니다. -coverprofile=coverage.out으로 profile을 만들고 go tool cover -func 또는 -html로 보면 함수별 누락과 source 위치를 확인할 수 있습니다. 특히 -html은 실행된 코드와 실행되지 않은 코드를 시각적으로 보여 주기 때문에 테스트 보강 위치를 찾기 좋습니다.
go test -coverprofile=coverage.out ./...
go tool cover -func=coverage.outCI에서는 HTML보다 -func 결과나 전체 coverage threshold를 먼저 보고, 로컬에서는 HTML로 실제 누락 줄을 확인하는 흐름이 실용적입니다. package 경계를 넘어 하나의 profile을 만들려면 다음처럼 분석 범위를 넓힙니다.
go test -coverpkg=./... -coverprofile=coverage.out ./...
go tool cover -func=coverage.out-coverpkg는 import path pattern에 맞는 package를 계측합니다. 넓힌 범위가 실행되지 않으면 profile에는 여전히 누락으로 남으므로, 숫자만 합쳐 모든 package를 검증했다고 해석하지 않습니다.
covermode는 병렬 코드에서 의미가 달라진다
Go coverage에는 set, count, atomic 같은 모드가 있습니다. 기본 set은 statement가 실행됐는지만 봅니다. count는 몇 번 실행됐는지 세고, atomic은 병렬 test에서도 정확한 count를 내지만 비용이 큽니다. -race를 켜면 기본 mode도 atomic이 됩니다. 일반적인 coverage 확인에는 기본값으로 충분한 경우가 많고, 병렬 알고리즘 계측처럼 정확한 count가 필요할 때만 비용을 감수하고 atomic을 검토합니다.
어디에 쓸까
| 상황 | 명령 |
|---|---|
| 빠른 coverage 확인 | go test -cover ./... |
| profile 파일 생성 | go test -coverprofile=coverage.out ./... |
| 함수별 coverage 확인 | go tool cover -func=coverage.out |
| HTML로 누락 줄 확인 | go tool cover -html=coverage.out |
| 병렬 count 정확도 필요 | -covermode=atomic 검토 |
| 다른 package까지 함께 계측 | -coverpkg=./... |
| CI threshold 확인 | package별 기준을 따로 설정 |
주의할 점
coverage 수치를 목표로 삼으면 테스트가 실행만 하고 검증하지 않는 방향으로 흐를 수 있습니다. -coverpkg는 분석 범위를 넓힐 뿐 integration test를 대신하지 않습니다. coverage는 누락된 경로를 찾는 도구로 쓰고, 실제 품질 판단은 assert, 경계값, 실패 케이스를 함께 봐야 합니다.
실패 예시
- coverage 90%만 맞추고 에러 경로 assert를 비워 둠
- 결과: 수치는 높지만 실패 처리 회귀를 잡지 못함
- 대응: coverage로 누락 경로를 찾고, 각 경로의 기대 결과를 테스트로 고정한다참고 링크
2 sources