본문 바로가기

Go

Golang TDD (테스트 주도 개발) 유닛테스트 루트 절대경로 설정

Golang TDD를 도입하려는 도중 이슈가 발생해 적어봤습니다.

TDD의 기본은 유닛 테스트입니다.말 그대로 함수 하나를 테스트를 한다는 말인데요.

TDD의 설명은 많은 분들이 적어놓으셨기 때문에 생략하겠습니다.

제가 궁금했던 문제는 이겁니다.
유닛테스트 즉, 함수 하나를 테스트하는데 환경변수는 어떤 식으로 초기화해서 써야 할까?

 

TDD 를 도입하기 이전에는 디비접근,센트리URL,JWT TOKEN,PASSWORD 등등을 루트 디렉터리의. env로 긁어와서
초기화한 후 실행하면 끝이었습니다.
TDD 도입을 하면서도 별 생각이 없었습니다. 테스트 코드를 만들고 기존에 있는 환경변수 초기화 함수를 테스트 코드 안에 넣고 ( 필자는 .env 사용 )

go test ./...  를 하면?

panic: open .env: no such file or directory

읭?

아.. 유닛 테스트를 진행하는 함수의 디렉토리 위치가 달라서 .env 파일을 찾을 수 없구나!

라고 생각을 했는데 아니었습니다.


Viper ( golang 에서 환경변수 path 설정 및 .env , yaml , 등등을 읽고 쓸 수 있는 패키지 )를 
유닛 테스트 안에 경로를 바꾸어서 설정을 해도 여전히 .env 파일을 읽을 수 없었습니다.

읭? 

솔직히 말하면 왜 .env 파일을 읽을 수 없었는지 아직 모릅니다..

왜냐하면 동일한 코드를 test 모드에서 하면 에러가 나고 run 하면 에러가 안 났습니다.

( ../ , ../../ 등 무수히 많은 코드를 타고 내려가 봐도 결과는 동일했습니다..)

( 혹시 이 이유를 아시는 분은 댓글 남겨주세용.. )

제가 해결한 방법루트 디렉토리에 있는 .env 파일만 강제로 읽게 만드는 LoadEnv() 함수를 하나 만들었습니다.

아래 코드를 그대로 복사하셔서 사용하셔도 됩니다. projectDirName을 현재 사용하고 계시는 프로젝트로만 변경해주시면 됩니다.
참고 (https://github.com/joho/godotenv/issues/43)

go get github.com/joho/godotenv

go get github.com/sirupsen/logrus

package testutils

import (
   "github.com/joho/godotenv"
   log "github.com/sirupsen/logrus"
   "os"
   "regexp"
)

const projectDirName = "your-project-name"

func LoadEnv() {
   re := regexp.MustCompile(`^(.*` + projectDirName + `)`)
   cwd, _ := os.Getwd()
   rootPath := re.Find([]byte(cwd))
   err := godotenv.Load(string(rootPath) + `/.env`)
   if err != nil {
      log.WithFields(log.Fields{
         "cause": err,
         "cwd":   cwd,
      }).Fatal("Problem loading .env file")

      os.Exit(-1)
   }
}

LoadEnv() 함수로 현재 루트 프로젝트를 가져와서 godotenv 모듈을 사용해 절대 경로로 설정해서 사용했습니다.

func Test_getEnv(t *testing.T) {

   testutils.LoadEnv()

   type args struct {
      SomethingImportantKey string
   }

   tests := []struct {
      name string
      args args
   }{
      {"test get .env", args{SomethingImportantKey: os.Getenv("Important_KEY")}},
   }

   for _, tt := range tests {
      t.Run(tt.name, func(t *testing.T) {
         //...
      })
   }

}

이후에 Test 코드를 돌려보니 .env 파일을 잘 읽어서 가져오게 됐습니다.

 

마치면서..

 

해결을 했습니다만 Test 모드에는 기존 path 설정과는 다르다는 건 알겠는데 이 부분에 대해서는 좀 더 고도화가 필요해 보입니다.
글 쓰는 솜씨가 시즌2 롤 처음 시작했을 때 했던 트린다미어가 생각나네요 그럼 이만