
왜 변수와 상수를 테스트해야 할까요?
어느 날 갑자기 서비스의 결제 로직이 멈췄다는 알람을 받았다고 상상해 보세요. 원인을 찾아보니 결제 수수료를 정의해둔 상수가 실수로 변경되었거나, 변수의 타입이 의도치 않게 바뀌어 있었던 상황이에요. 이런 문제는 단순한 오타처럼 보이지만, 실제 서비스에서는 엄청난 금전적 손실을 불러올 수 있어요.
많은 입문 개발자가 함수나 구조체의 복잡한 로직을 테스트하는 데만 집중하곤 해요. 하지만 Go 변수 테스트는 그 기초가 되는 데이터의 무결성을 지키는 아주 중요한 작업이에요. 변수가 의도한 범위 내에서 값을 유지하는지, 상수가 정말로 변하지 않는 값으로 안전하게 보호되고 있는지 확인하는 과정이 반드시 필요해요.
이 가이드를 끝까지 읽고 나면, 단순히 코드를 짜는 수준을 넘어 프로덕션 환경에서도 믿고 쓸 수 있는 안정적인 코드를 작성하는 능력을 갖추게 될 거예요. 기초부터 탄탄하게 다져나가는 즐거움을 느껴보세요.
이 글에서 함께 배울 내용들
- Go에서 변수와 상수의 핵심 차이점 이해하기
- 테스트를 위한 최적의 개발 환경 설정하기
- Golang의 꽃, 테이블 기반 테스트(Table-driven tests) 구현하기
- 실전에서 바로 써먹는 변수 검증 전략
테스트 시작 전 꼭 알아야 할 준비물
무턱대고 테스트 코드를 작성하기 시작하면 금방 한계에 부딪혀요. 어떤 도구가 필요한지, 그리고 우리가 테스트하려는 대상이 무엇인지 명확히 정의하는 과정이 선행되어야 해요. 준비 단계가 탄탄해야 테스트 코드도 간결해져요.
먼저 컴퓨터에 Go 언어가 설치되어 있어야 해요. 터미널에서 go version 명령어를 입력했을 때 버전 정보가 제대로 나온다면 준비는 끝난 셈이에요. 그리고 코드를 편하게 작성하고 테스트 결과를 바로 확인할 수 있는 VS Code나 GoLand 같은 에디터가 있으면 훨씬 수월해요.
변수와 상수의 결정적 차이 비교
테스트를 설계하기 전에 우리가 무엇을 검증할지 알아야 해요. 아래 표를 통해 두 개념의 차이를 명확히 정리해 드릴게요.
| 구분 항목 | 변수(Variable) | 상수(Constant) |
|---|---|---|
| 값의 변경 가능성 | 프로그램 실행 중 언제든 변경 가능 | 한 번 정하면 절대 변경 불가 |
| 선언 키워드 | var 또는 := |
const |
| 주요 용도 | 계산 결과, 사용자 입력값 등 동적 데이터 | 설정값, 수학적 상수, 고정된 기준값 |
| 테스트 핵심 포인트 | 값의 변화 과정과 타입의 적절성 확인 | 의도한 값이 유지되는지 확인 |
Go에서 상수는 컴파일 시점에 결정되어야 해요. 즉, 함수의 실행 결과값을 상수에 할당할 수는 없다는 점을 꼭 기억하세요!
단계별 실전 테스트 구현하기
이제 본격적으로 코드를 작성하고 테스트해 볼 시간이에요. 단순히 코드를 복사하는 게 아니라, 왜 이런 구조로 작성하는지 그 흐름을 따라와 주세요. 실전 감각을 익히는 데 집중해 보세요.
STEP 1. 프로젝트 환경 구성하기
테스트를 하려면 먼저 독립적인 작업 공간이 필요해요. 터미널을 열고 프로젝트를 담을 폴더를 만든 뒤, Go 모듈 시스템을 초기화해야 해요. 이 과정이 없으면 패키지 간의 참조가 꼬여서 테스트가 제대로 동작하지 않을 수 있어요.
먼저 폴더를 만들고 이동한 뒤, 다음과 같이 명령어를 입력해 주세요. go mod init my-test-project를 실행하면 go.mod 파일이 생성되면서 우리 프로젝트만의 관리 체계가 잡혀요. 이렇게 하면 나중에 외부 라이브러리를 가져올 때도 아주 편리해요.
STEP 2. 변수와 상수 모델링하기
테스트할 대상을 만들어야겠죠? 간단한 설정 정보를 담고 있는 config.go 파일을 만들어 볼게요. 여기에는 서비스 운영에 필요한 상수와 상태를 나타내는 변수를 함께 담을 거예요.
파일에는 서비스의 최대 재시도 횟수를 나타내는 상수 MaxRetries와 현재 시스템의 상태를 나타내는 변수 CurrentStatus를 정의할 거예요. 상수는 시스템의 규칙을, 변수는 시스템의 흐름을 담당한다고 이해하면 쉬워요. 이 파일을 작성할 때는 반드시 패키지 이름을 명시해야 한다는 점 잊지 마세요.
STEP 3. 테스트 파일 생성과 기본 구조
Go 언어에는 아주 강력한 테스트 도구가 내장되어 있어요. 테스트를 하려면 반드시 파일 이름 끝에 _test.go를 붙여야 해요. 예를 들어 config.go를 테스트한다면 파일 이름은 config_test.go가 되어야 하죠. 이렇게 이름을 지어야 Go의 테스트 실행 도구가 이 파일을 테스트용으로 인식하고 자동으로 찾아내거든요.
테스트 함수를 만들 때는 이름 앞에 반드시 Test라는 단어를 붙여야 해요. 그리고 함수의 첫 번째 인자는 항상 t *testing.T 형태를 가져야 해요. 이 t라는 인자가 바로 테스트의 성공과 실패를 판정하는 마법의 도구예요. 이 도구를 사용해서 우리가 원하는 조건이 맞는지 확인하게 돼요.
STEP 4. 테이블 기반 테스트(Table-driven Tests) 적용하기
Go 개발자들이 가장 사랑하는 패턴이 바로 테이블 기반 테스트예요. 이 방식은 테스트할 데이터들을 표(Table)처럼 구조체 슬라이스에 담아두고, 반복문을 돌리면서 하나씩 검증하는 아주 깔끔한 방법이에요. 코드가 중복되지 않고 새로운 테스트 케이스를 추가하기가 정말 쉬워요.
예를 들어, 변수의 값이 특정 범위 안에 있는지 확인하는 테스트를 한다고 가정해 볼게요. struct를 활용해서 name, input, expected 같은 필드를 만들어요. 그 다음 range 문을 사용해서 각 데이터를 하나씩 꺼내어 t.Run()으로 실행하면, 각 케이스가 독립적으로 어떤 결과를 냈는지 명확하게 확인할 수 있어요.
STEP 5. 실전 시나리오와 검증 코드 작성
이제 완성된 시나리오를 바탕으로 코드를 돌려볼까요? 우리가 만든 상수가 정말로 유지되는지, 그리고 변수가 특정 조건에서 올바르게 변하는지 검증하는 코드를 작성해야 해요. 만약 값이 예상과 다르다면 t.Errorf()를 호출해서 어떤 케이스에서 무엇이 잘못되었는지 상세하게 알려주도록 구성하세요.
테스트를 실행할 때는 터미널에
go test -v를 입력하세요. -v 옵션을 붙여주면 각 테스트 케이스가 성공했는지 실패했는지 아주 자세하게 보여준답니다.실제로 테스트를 돌려보면, 우리가 미처 생각하지 못했던 경계값 문제나 초기화 오류를 발견할 수도 있어요. 그게 바로 테스트를 하는 진짜 이유예요. 오류가 발견되면 당황하지 말고 코드를 수정하면서 다시 실행해 보세요. 이 반복 과정이 여러분을 진정한 개발자로 만들어 줄 거예요.
자주 하는 실수와 해결법
테스트를 작성하다 보면 의외로 사소한 부분에서 막힐 때가 많아요. 초보 단계에서 가장 많이 겪는 문제들을 모아봤으니, 여러분의 상황과 비교해 보세요.
- ❌ 패키지 외부의 비공개 변수를 테스트하려 함
왜 발생하나요? Go에서 소문자로 시작하는 변수나 상수는 같은 패키지 안에서만 접근할 수 있어요.
✅ 해결법: 테스트 파일을 같은 패키지 폴더에 두거나, 필요한 경우 공개된(대문자로 시작하는) 함수를 통해 간접적으로 검증하세요. - ❌ 상수 값을 테스트 함수 안에서 변경하려고 시도함
왜 발생하나요? 상수는 문법적으로 불변(Immutable)이기 때문에 변경 시도 자체가 컴파일 에러를 일으켜요.
✅ 해결법: 상수의 값을 바꾸려 하지 말고, 상수가 로직에 어떻게 올바르게 적용되는지를 테스트하세요. - ❌ 테스트 파일 이름을 잘못 지정함
왜 발생하나요?_test.go접미사가 없으면 Go 도구는 이를 일반 소스 파일로 인식하고 테스트를 건너뛰어요.
✅ 해결법: 파일명이 정확히[파일명]_test.go인지 다시 한번 확인해 보세요. - ❌ 테스트 케이스의 실패를 무시함
왜 발생하나요?t.Fail()만 쓰고 구체적인 에러 메시지를 남기지 않으면 무엇이 틀렸는지 알 수 없어요.
✅ 해결법:t.Errorf()를 사용하여 기대값과 실제값이 무엇인지 상세히 출력하세요. - ❌ 테스트 실행 시 환경 변수 설정을 놓침
왜 발생하나요? 특정 변수가 환경 변수에 의존하는 경우, 테스트 환경에서는 그 값이 없을 수 있어요.
✅ 해결법: 테스트 코드 내에서os.Setenv()를 사용해 테스트용 환경을 구축하세요.
자주 묻는 질문
Q. 상수는 값이 변하지 않는데 왜 테스트가 필요한가요?
상수 값 자체가 바뀌는지를 보는 게 아니라, 그 상수를 사용하는 로직이 올바른지 확인하기 위해서예요. 예를 들어, 최대 접속자 수를 상수로 정해뒀다면, 그 상수를 기준으로 동작하는 로직이 경계값에서 오류를 일으키지 않는지 검증하는 것이 핵심이에요.
Q. 테이블 기반 테스트를 사용하면 코드가 너무 길어지지 않나요?
처음에는 그렇게 느껴질 수 있지만, 테스트 케이스가 늘어날수록 훨씬 효율적이에요. 새로운 조건을 추가할 때 기존 로직을 건드리지 않고 데이터만 한 줄 추가하면 되기 때문에 유지보수 면에서 압도적으로 유리하답니다.
Q. Go 변수 테스트에서 가장 권장되는 도구는 무엇인가요?
별도의 외부 도구 없이 Go에 내장된 testing 패키지만으로도 충분해요. 오히려 표준 패키지를 사용하는 것이 Go의 철학에 가장 잘 맞고, 다른 개발자들이 코드를 이해하기에도 훨씬 좋아요.
Q. go test ./... 명령어는 무엇을 의미하나요?
현재 디렉터리뿐만 아니라 하위 폴더에 있는 모든 패키지의 테스트를 한꺼번에 실행하라는 아주 유용한 명령어예요. 프로젝트 규모가 커지면 이 명령어를 습관적으로 사용하게 될 거예요.
정리하며: 더 나은 개발자로 가는 길
오늘 우리는 Go 프로그래밍의 기초인 변수와 상수를 어떻게 안전하게 테스트하는지 깊이 있게 살펴보았어요. 처음에는 테스트 코드를 짜는 게 번거롭고 시간 낭비처럼 느껴질 수도 있지만, 이는 나중에 닥칠 수 있는 거대한 버그를 막아주는 가장 저렴한 보험과도 같아요.
- 변수는 동적 데이터를, 상수는 고정된 규칙을 담당해요.
- 테스트 파일은 반드시
_test.go로 끝나야 해요. - 테이블 기반 테스트를 통해 중복 없이 다양한 케이스를 검증하세요.
- 상수는 값을 바꾸는 게 아니라, 그 값이 로직에 미치는 영향을 테스트해요.
t.Errorf()로 실패 원인을 상세히 남기는 습관을 가지세요.
이제 이론은 충분히 배웠어요. 백문이 불여일견이라는 말처럼, 직접 코드를 쳐보는 것이 가장 빠른 학습 방법이에요. 지금 바로 제가 설명해 드린 구조를 바탕으로 여러분만의 테스트 코드를 작성해 보세요.
오늘 바로 실행해 볼 액션 플랜
- 오늘 할 일: Go 환경이 제대로 설정되었는지 확인하고
go mod init으로 프로젝트 만들기 - 이번 주 할 일: 작은 프로젝트를 만들어 변수와 상수를 정의하고 테이블 기반 테스트 작성해 보기
- 실행 직전 할 일:
go test -v명령어로 모든 테스트가 통과하는지 확인하기
지금 바로 예제 코드를 클론해 직접 실행해 보세요. 코드를 직접 만져보며 얻는 경험이 여러분의 실력을 가장 빠르게 키워줄 거예요.
함께 읽으면 좋은 글: Go 변수와 상수 완벽 가이드