godotenv: Can't use godotenv when running tests
I’ve added godotenv to my project and it works fine when running the compiled binary, but it fails when running my tests:
$ go test ./...
2017/10/13 16:22:37 Error loading .env fileopen .env: no such file or directory
This is happening because the tests are being run in the following temp dir location:
/var/folders/yh/7x8fqv696sb1673313nk8_m80000gn/T/go-build041463486/github.com/myrepo/identity/server/_test
and it can’t find the .env file. Can anyone tell me how to fix this issue? Do I need to specify the absolute path to the .env file? I’m using the following code to load the .env file without specifying a path:
err = godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file", err)
}
About this issue
- Original URL
- State: open
- Created 7 years ago
- Reactions: 52
- Comments: 28 (3 by maintainers)
This problem gets even more tricky with Go Modules as your code can (and IMO should) live outside of
$GOPATH. Therefore the$GOPATHrelative tricks above do not work.My
.envis in the root of my repo, below is a simple util file that finds your repo dir fromcwdand loads the.envexplicitly.FWIW I run my tests like:
go test ./internal/... -covertestutils.go:
I just do a simple call from my test setup call:
Hope this helps someone else
Thanks for the response @joho. I’m not actually trying to vary the
.envbased on dev/test (yet), I’m just trying to getgodotdenvworking in both my compiled app as well as in test mode.It seems to be failing because during test mode, the tests are not looking for
.envin the root of the project, but instead they’re looking for the file relative to where the test is being run. The.envfile is in currently in$GOPATH/src/github.com/adamcohen/godotenv-test/.env, but the test is looking for the file in$GOPATH/src/github.com/adamcohen/godotenv-test/loader/.envwhich doesn’t exist.So it seems that there are (at least) two ways to solve this:
.envfile, as in:.envfile (or a symlink to it) in all subdirsHave I understood this correctly? If this is indeed the situation, it might be worth making note of this in the readme file to explain that if you want to write tests for an application which is using
godotenv, you’ll need one of the above approaches. I can make a PR for this addition if you’d like.Relative path args also work for
godotenv.Load().Why not use the godotenv command like
An extra benefit is that you can specify a test .env file.
Or even better you can just overwrite some env variables by using multiple files
Thanks @DanielOchoa I didn’t know relative path args existed!
Here’s the small snippet, to support different environments file dynamically. Based on the @adamcohen comment.(option 1)
Create a config struct, to hold your environment values and to initiate the struct create a method similar to the one below.(In
config.go)In your go files, you can access the env values as below
When you run without setting any
ENVIRONMENT, it will load the .env file.If you want to run the tests with values in
.env.test, you can run using the below command from any subFolder(by appending theENVIRONMENT=testbefore in your test command)Example:
$ ENVIRONMENT=test go test -run TestI’m using it like below:
I’ve created a new empty project, and the tests are no longer run in a temporary dir, so that part has been sorted out, however, I was still unable to get godotenv to work. I’ve put the project here, and this is what I get when I run
go test ./...:So it seems that
godotenvis failing because the call togodotenv.Load()happens while in thegodotenv-test/loader/dir, yet the.envfile is in the root atgodotenv-test. Is this expected behaviour?Right. Apparently this is documented behaviour (see https://go-review.googlesource.com/c/go/+/17949) but I was never aware of it. I’ll have a think of the best way to document (and/or a recommended work around) and get something into the readme.
This solution on SO https://stackoverflow.com/a/38644571 worked for me and seems quite straightforward
It gives you the directory of the current file, and from there you can navigate to the .env file you want. I had this directory structure
and in the end my version of their solution looked like this
That one definitely is the expected behaviour, the dotenv file should be found at the execution root.
If you’re hoping to vary .env based on dev/test, you’ll need to manually specify the file you want to load (relative to where you’re executing). In the rails world (where the original library this duplicates comes from) you would have
.env.developmentand.env.testwhich are automatically loaded based on theRAILS_ENVenv var, but unfortunately there’s no equivalent to hook off within go.Iam new into golang, this fixed my issue. Thanks
Copy your .env file which is in root directory, and Paste it in your test directory. It worked for me.
I place my env files at the same dir as my go.mod. As every Go project must have a go.mod, I could implement like this. The
envFileexpects something like “.env” or “.env.test”, etc.I ended up with using an env for it… I found providing config path explicitly is better, of course there should be default value.