Running Jest tests in VS Code with custom environment variables

Currently the most popular Jest test runner extension for VS Code is vscode-jest by Orta. For most common setups, this extension works without any configuration needed to VS Code. In my case, though, I needed to enable Jest's support for ECMAScript modules. The Jest documentation lists a few ways to do this, and I decided to use the the method that involves setting an environment variable.

Because I needed to set this environment variable, vscode-jest's default behavior didn't work, and I ended up needing to create a run configuration. This was not particularly complicated, but it was complicated enough that I thought I should capture the knowledge here.

Configuring the Jest command

First you need to configure the Jest command in your settings. To do this you can use the extension's "Setup Extension" command. From the command palette, run "Jest: Setup Extension" (or possibly "Jest: Setup Extension (beta)" if it's still in beta). Choose "Setup Jest Command" in the dropdown this produces.

It will ask if you can run Jest tests from the terminal; choose "yes". When it then asks for the Jest command line, enter "node_modules/.bin/jest". (Of course, if you use something else, enter that!)

This will add an entry like this to your settings.json:

"jest.jestCommandLine": "node_modules/.bin/jest"

Creating the launch configuration

You'll then return to the setup wizard's dropdown list. This time select "Setup Jest Debug Config", and then select "Generate". This will add a run configuration to your launch.json. Now you can select "Exit" from the wizard.

Now that you have the launch configuration, you need to edit it to add the environment variable. Add this to the launch configuration inside launch.json:

"env": {
    "NODE_OPTIONS": "--experimental-vm-modules"
}

You should end up with a configuration that looks something like this:

{
    "configurations": [
        {
            "type": "node",
            "name": "vscode-jest-tests",
            "request": "launch",
            "console": "integratedTerminal",
            "internalConsoleOptions": "neverOpen",
            "disableOptimisticBPs": true,
            "program": "${workspaceFolder}/node_modules/.bin/jest",
            "cwd": "${workspaceFolder}",
            "args": [
                "--runInBand",
                "--watchAll=false"
            ],
            "env": {
                "NODE_OPTIONS": "--experimental-vm-modules"
            }
        }
    ]
}

With this in place, you should be able to run and debug Jest tests from the test tool or directly from the test file.

Debugging AWS Lambda functions locally using VS Code and lambda-local

I've just started using AWS Lambda with node.js. I was able to develop these locally using the lambda-local npm package, e.g. with node.js installed (via brew) and lambda-local installed (using npm) then the following "hello, world" example is run as follows:

hellolambda.js

'use strict';

console.log('Loading function');

exports.handler = (event, context, callback) => {
    console.log('Received event:', JSON.stringify(event, null, 2));
    console.log('value1 =', event.key1);
    console.log('value2 =', event.key2);
    console.log('value3 =', event.key3);
    callback(null, event.key1);  // Echo back the first key value
    //callback('Something went wrong');

};

defaultevent.js

module.exports =
{
"key1": "hello",
"key2": "lambda",
"key3": "node"

};

/usr/local/bin/lambda-local -l hellolambda.js -e default event.js

Loading function
info: Logs
info: ------
info: START RequestId: d683128b-ac14-93c3-b2c1-5541f3bb3fda
Received event: {
  "key1": "hello",
  "key2": "lambda",
  "key3": "node"
}
value1 = hello
value2 = lambda
value3 = node
info: END
info: Message
info: ------
info: hello
info: -----

info: lambda-local successfully complete.

Rather than use bash and vi (I'm running on MacOS) I wanted to use some sort of IDE. VS Code seemed ideal as it's free and it also has builtin node.js debugging. Using it for editing is very simple, just open the folder containing the source. In this case ~/tmp/hellolambda

However, switching to the debugging section and creating the default launch configuration where VS Code will launch node with the specify file as the program doesn't do much good.



This is because when running a lambda locally using local-lambda the program that node needs to run is the local lambda environment that local-lambda creates and for it to launch the lambda function.

This can be simply configured by specifying the local-lambda script as the program (it's a node script) and then passing the lambda script and the event data as arguments using the args key (which isn't included when using the VS Code option to add a configuration). The original example above can be launched using the following configuration.

In the output window at the bottom the results of executing the lambda are shown. Breakpoints can be set and hit.

It's important that each command line argument, i.e. the option and the value are specified separately. Even though '-l' and its value are a pair they are separate command line arguments (2 in total) where "-l ${workspaceRoot}/hellolambda.js" is a single argument.

NOTE: The lambdas I'm writing are also using the AWS DynamoDB. Using a local instance of DynamoDB along with installing the AWS SDK via npm I've been able to successfully invoke local lambdas that have used the local instance of the DB.

Debugging AWS Lambda functions locally using VS Code and lambda-local

I've just started using AWS Lambda with node.js. I was able to develop these locally using the lambda-local npm package, e.g. with node.js installed (via brew) and lambda-local installed (using npm) then the following "hello, world" example is run as follows:

hellolambda.js

'use strict';

console.log('Loading function');

exports.handler = (event, context, callback) => {
    console.log('Received event:', JSON.stringify(event, null, 2));
    console.log('value1 =', event.key1);
    console.log('value2 =', event.key2);
    console.log('value3 =', event.key3);
    callback(null, event.key1);  // Echo back the first key value
    //callback('Something went wrong');

};

defaultevent.js

module.exports =
{
"key1": "hello",
"key2": "lambda",
"key3": "node"

};

/usr/local/bin/lambda-local -l hellolambda.js -e default event.js

Loading function
info: Logs
info: ------
info: START RequestId: d683128b-ac14-93c3-b2c1-5541f3bb3fda
Received event: {
  "key1": "hello",
  "key2": "lambda",
  "key3": "node"
}
value1 = hello
value2 = lambda
value3 = node
info: END
info: Message
info: ------
info: hello
info: -----

info: lambda-local successfully complete.

Rather than use bash and vi (I'm running on MacOS) I wanted to use some sort of IDE. VS Code seemed ideal as it's free and it also has builtin node.js debugging. Using it for editing is very simple, just open the folder containing the source. In this case ~/tmp/hellolambda

However, switching to the debugging section and creating the default launch configuration where VS Code will launch node with the specify file as the program doesn't do much good.



This is because when running a lambda locally using local-lambda the program that node needs to run is the local lambda environment that local-lambda creates and for it to launch the lambda function.

This can be simply configured by specifying the local-lambda script as the program (it's a node script) and then passing the lambda script and the event data as arguments using the args key (which isn't included when using the VS Code option to add a configuration). The original example above can be launched using the following configuration.

In the output window at the bottom the results of executing the lambda are shown. Breakpoints can be set and hit.

It's important that each command line argument, i.e. the option and the value are specified separately. Even though '-l' and its value are a pair they are separate command line arguments (2 in total) where "-l ${workspaceRoot}/hellolambda.js" is a single argument.

NOTE: The lambdas I'm writing are also using the AWS DynamoDB. Using a local instance of DynamoDB along with installing the AWS SDK via npm I've been able to successfully invoke local lambdas that have used the local instance of the DB.