Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misleading documentation: variables in .env and .env.test are not being loaded in test environment #17903

Closed
tremby opened this issue Oct 15, 2020 · 23 comments
Assignees
Labels
please verify canary The issue should be verified against next@canary. It will be closed after 30 days of inactivity

Comments

@tremby
Copy link
Contributor

tremby commented Oct 15, 2020

Bug report

Describe the bug

According to these docs:

Next.js allows you to set defaults in .env (all environments)

Further down on the same page:

Apart from development and production environments, there is a 3rd option available: test. In the same way you can set defaults for development or production environments, you can do the same with .env.test file for testing environment

But variables in .env and .env.test are not being loaded when running tests.

To Reproduce

Basic setup and .env:

  1. create-next-app -e with-jest and enter a name
  2. cd <name>
  3. echo MY_VAR=my_value >.env
  4. cat >__tests__/env.js <<EOF
    describe("environment variables", () => {
      it("loads variables from .env in the test environment", () => {
        expect(process.env.MY_VAR).toBe("my_value");
      });
    });
    EOF
    
  5. npm run test:ci -- env

The test fails: process.env.MY_VAR is undefined.

.env.test:

  1. mv .env .env.test
  2. npm run test:ci -- env

The test fails: process.env.MY_VAR is undefined.

Expected behavior

The test should pass in both situations (with the file named either .env or .env.test). At least, if I'm understanding the docs correctly and I'm not doing anything silly.

System information

  • OS: Ubuntu
  • Version of Next.js: 9.5.5
  • Version of Node.js: 12.18.1
@erkde
Copy link

erkde commented Oct 15, 2020

As of v9.5.5, you can just do

import { loadEnvConfig } from '@next/env'

export default async () => {
  loadEnvConfig(process.env.PWD)
}

if you add that your jest setup (e.g. globalSetup), should be good to go

@tremby
Copy link
Contributor Author

tremby commented Oct 15, 2020

So the docs are out of date?

@erkde
Copy link

erkde commented Oct 15, 2020

So the docs are out of date?

maybe, 9.5.5 is only out a few days

@tremby
Copy link
Contributor Author

tremby commented Oct 15, 2020

Well the problem also exists on 9.5.4. It's either an application bug or a documentation bug regardless, unless I have something wrong.

@timneutkens
Copy link
Member

Next.js does not set up your test environment currently so it can't load environment variables for you. You can boot up the Next.js server though which loads the environment variables:

const next = require('next')
// `.env` / `.env.test` is loaded during initialization.
const app = next()

@howieweiner
Copy link

I too have just noticed this. NODE_ENV is set to to test, but when running Jest unit tests the .env.test file is not loaded. The docs do indicate that they should.

As per @erkde comment, I have fixed this with by loading the env files in jest.config.js

const { loadEnvConfig } = require('@next/env')
loadEnvConfig(process.env.PWD)

@tremby
Copy link
Contributor Author

tremby commented Oct 15, 2020

A documentation bug then.

Regarding booting Next, do you suggest doing that globally (such as in jest config) or per test file which needs it?

@tremby tremby changed the title Variables in .env and .env.test are not being loaded in test environment Misleading documentation: variables in .env and .env.test are not being loaded in test environment Oct 15, 2020
@howieweiner
Copy link

For my purposes, it made sense to make the change globally as I had an env var that disables auth checks during tests.

The loading if .env.test does work for my Cypress tests as documented

@tremby
Copy link
Contributor Author

tremby commented Oct 15, 2020

But only after booting Next, right? That ought to be documented.

@howieweiner
Copy link

Sorry, what do you mean by 'booting Next'?

@tremby
Copy link
Contributor Author

tremby commented Oct 15, 2020

As above in @timneutkens's comment:

You can boot up the Next.js server though which loads the environment variables:

const next = require('next')

@howieweiner
Copy link

Ah. Sorry, I didn't seem to need this step. Programmatically setting the env vars using loadEnvConfig was enough

@tremby
Copy link
Contributor Author

tremby commented Oct 15, 2020

Right, so it sounds like either loadEnvConfig or require('next') get the vars loaded up. Just saying that the docs should mention this when it talks about env vars for tests.

@warpskew
Copy link

warpskew commented Oct 28, 2020

My temporary workaround has been to add a global setup file in my Jest configuration:

/**
 * @file jest.config.js
 */

module.exports = {
  globalSetup: '<rootDir>/test/setup.ts',
};

and to load a particular environment configuration with dotenv:

/**
 * @file test/setup.ts
 */

import dotenv from 'dotenv';

dotenv.config({ path: '.env.test' });

I know it doesn't solve the problem, but hopefully it can be helpful in the meantime.

Also, you may be able to run dotenv.config(...) with multiple paths to load in a few configs (please note I have not tested this):

dotenv.config({ path: '.env' });
dotenv.config({ path: '.env.test' });

@tremby
Copy link
Contributor Author

tremby commented Oct 28, 2020 via email

@howieweiner
Copy link

howieweiner commented Oct 28, 2020

I needed the .env.test file loaded for both Jest and out Cypress integration tests. My workaround was to use https://www.npmjs.com/package/dotenv-load which behaves as expected.

@tremby
Copy link
Contributor Author

tremby commented Nov 25, 2020

I just came back to this.

I don't want to install dotenv, since that doesn't necessarily work in exactly the same way as next would load the vars.

Putting import "next"; in my test/setup.ts file or putting require("next") in my jest.config.js file is not causing env vars in .env.test to load.

I tried the suggestion in this comment.
I'm getting some weird behaviour with that.
I can get it working by putting this in my test/setup.ts file:

import { loadEnvConfig } from "@next/env";
import { resolve } from "path";
loadEnvConfig(resolve(__dirname, ".."));

but then the test console output is littered with log lines from the env files being loaded -- console.info is getting run again and again. I looked at the implementation of loadEnvConfig and its third parameter is a console object. I tried passing one:

loadEnvConfig(resolve(__dirname, ".."), undefined, { info: jest.fn(), error: console.error });

but console.info is still getting called. I can't figure out why.

My workaround for now is heavy-handed:

const mockInfo = jest.spyOn(console, "info").mockImplementation();
loadEnvConfig(resolve(__dirname, ".."));
mockInfo.mockRestore();

@erkde
Copy link

erkde commented Nov 25, 2020

@tremby see: https://jestjs.io/docs/en/configuration#globalsetup-string e.g.

jest.config.js

module.exports = {
  ...
  globalSetup: '<rootDir>/test/setupEnv.ts',
}

test/setupEnv.ts

import { loadEnvConfig } from '@next/env'

export default async () => {
  loadEnvConfig(process.env.PWD)
}

@tremby
Copy link
Contributor Author

tremby commented Nov 26, 2020

Ok, now it only runs once, which is better. Thanks.

Not that it matters any more, but that function still doesn't seem to pay any attention to its third parameter.

The point of this ticket remains that the docs are misleading, which is still an issue.

kodiakhq bot pushed a commit that referenced this issue Mar 12, 2021
This adds a note to the environment variables documentation to mention how the env files can be loaded using the `@next/env` package as this has been brought up a few times. 

x-ref: #22936 (comment)
x-ref: #17903
@syntactic-salt
Copy link

Is there any plan to fix this?

@jankaifer jankaifer self-assigned this Dec 1, 2022
@jankaifer jankaifer added the please verify canary The issue should be verified against next@canary. It will be closed after 30 days of inactivity label Dec 1, 2022
@github-actions
Copy link
Contributor

github-actions bot commented Dec 1, 2022

Please verify that your issue can be recreated with next@canary.

Why was this issue marked with the please verify canary label?

We noticed the provided reproduction was using an older version of Next.js, instead of canary.

The canary version of Next.js ships daily and includes all features and fixes that have not been released to the stable version yet. You can think of canary as a public beta. Some issues may already be fixed in the canary version, so please verify that your issue reproduces by running npm install next@canary and test it in your project, using your reproduction steps.

If the issue does not reproduce with the canary version, then it has already been fixed and this issue can be closed.

How can I quickly verify if my issue has been fixed in canary?

The safest way is to install next@canary in your project and test it, but you can also search through closed Next.js issues for duplicates or check the Next.js releases.

My issue has been open for a long time, why do I need to verify canary now?

Next.js does not backport bug fixes to older versions of Next.js. Instead, we are trying to introduce only a minimal amount of breaking changes between major releases.

What happens if I don't verify against the canary version of Next.js?

An issue with the please verify canary that receives no meaningful activity (e.g. new comments that acknowledge verification against canary) will be automatically closed and locked after 30 days.

If your issue has not been resolved in that time and it has been closed/locked, please open a new issue, with the required reproduction, using next@canary.

I did not open this issue, but it is relevant to me, what can I do to help?

Anyone experiencing the same issue is welcome to provide a minimal reproduction following the above steps. Furthermore, you can upvote the issue using the 👍 reaction on the topmost comment (please do not comment "I have the same issue" without repro steps). Then, we can sort issues by votes to prioritize.

I think my reproduction is good enough, why aren't you looking into it quicker?

We look into every Next.js issue and constantly monitor open issues for new comments.

However, sometimes we might miss one or two due to the popularity/high traffic of the repository. We apologize, and kindly ask you to refrain from tagging core maintainers, as that will usually not result in increased priority.

Upvoting issues to show your interest will help us prioritize and address them as quickly as possible. That said, every issue is important to us, and if an issue gets closed by accident, we encourage you to open a new one linking to the old issue and we will look into it.

Useful Resources

@balazsorban44
Copy link
Member

This issue has been automatically closed because it wasn't verified against next@canary. If you think it was closed by accident, please leave a comment. If you are running into a similar issue, please open a new issue with a reproduction. Thank you.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 3, 2023

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 3, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
please verify canary The issue should be verified against next@canary. It will be closed after 30 days of inactivity
Projects
None yet
Development

No branches or pull requests

8 participants