This is part one of the Big Nerd Ranch series. Read about our free developer training for Alexa Skills Kit here.

If you want to build Alexa Skills, where should you start? You could begin with building one of the sample skills like the color picker or the trivia game. But when you’ve already tackled “Hello, World,” you’re ready to dive in.

Not quite yet. First, let’s set up a local development environment. Why should you use a local development environment over testing on a live server? There are many benefits. Chief among them are the fact that you gain access to the debugger and the stack trace, and you can quickly test changes without uploading files to a remote server, cutting down your iteration time.

In addition to time considerations, there are other concerns: what if the network is running slowly, you’re on a plane, or the Wi-Fi isn’t working? With a local dev environment, you can still get work done.

That’s where this post comes in: it will guide you through setting up a local development environment so that you can work more efficiently, enabling you to rapidly test your skills as you develop them. We will first set up a working environment with Node.js, and then we will build a model for our Alexa Skill. This skill—Airport Info—will track airport flight delays and weather conditions, and will give us a chance to try developing a more complex Alexa Skill locally.

Building the Skill Model

We will begin by building a model for the Airport Info skill. For this blog post, we're going to use Node.JS and Amazon's AWS Lambda compute service. You have the flexibility to use other languages with Lambda or even any HTTPS endpoint, but we chose Node.js here because it’s easy to get started with and is widely used in the Alexa Skill development community.

The source code for this project is available on GitHub. Let’s set up our environment.

First Steps: Using nvm

Before we can begin developing on our Node.js-backed Alexa skill locally, we will of course need to install Node.js. To get started, I’d suggest pulling down Node Version Manager (nvm) to easily keep track of different versions of Node.

Let’s begin by installing nvm. Note that NVM does not exist for a Windows environment. There is an alternative available, with a slightly different set of commands (nvm list vs nvm ls, for example).

Your home directory may appear differently based on your operating system. We will use "local ✗" as a generic home command prompt.

While today this means we’ll be working with ES5, in a future article we’ll explore enabling ES6 support.

Install Node v0.10.36 using the following command:

nvm install v0.10.36

After this completes, set the default version of Node so we won’t have to fiddle with it in the future:

➜ localhost ✗ nvm alias default v0.10.36
default -> v0.10.36

npm config

Included with Node.js is the node package manager (npm), which we’ll use to add the dependencies our skill needs. Create a new directory for the project called faa-info. This is where our skill service code will live.

Open a terminal window and go to this directory. Next, we will initialize a new package.json file to hold a list of dependencies our project will use:

npm init

Run through the dialogs, accepting the defaults for each dialog, and when you’re prompted to enter a test command, type:

mocha

We will use Chai and Mocha, two JavaScript assertion and test libraries, to build our tests, so we're adding them while we set up npm.

Now that we've configured npm as our test runner, we will add all of the dependencies the project will use. Add the required dependencies to our package.json:

Foundation

Let’s consider the feature our skill offers: in response to an IATA airport code provided by the user, our skill will give information relevant for that particular airport.

The service we’ll use is the FAA’s public airport status service. The endpoint accepts an IATA airport code and a format, like http://services.faa.gov/airport/status/SFO?format=application/json to get information about the San Francisco airport. If you visit that URL, you will see the information we would like our skill to ultimately read back to the user: delay status, weather conditions and temperature info. The FAA payload contains all of this:

To proceed, we’ll first address the problem of requesting the data, then tackle formatting it so that Alexa can use it as a response.

Making the Request

Let’s start with some unit tests to ensure that the model works as we expect. Create a directory called test within faa-info and add a file called test_faa_data_helper.js. As I mentioned earlier, we will use Chai and Mocha to build our tests. They should already be installed, since we added them earlier via npm.

Our test will describe the behavior of the FAADataHelper class. The test doesn’t yet make any assertions, but it does require a helper class. It should fail, because we don’t have a helper class created yet.

We can now run our test with mocha test/test_faa_data_helper.js from the terminal in the root of our project.

It looks like our test file ran, but couldn’t find the module because we haven’t created it. Let’s create a new file called faa_data_helper.js in the root directory (../faa-info) and start a module called FAADataHelper.

We need to make some assertions in our test. Our first test should check a made-up method called requestAirportStatus(airportCode) on FAADataHelper, which will eventually make the actual request to the Airport Info service, then return the JSON we saw earlier.

This test asserts that a Promise-based network request returns a value we expect. (Our project will use request-promise.)

Notice the eventually portion of the matcher in use above? This is a special part of the chai-as-promised matcher we added, which allows us to make assertions about the data a Promise returns without requiring the use of callbacks, "sleeps" or other less-than-ideal approaches to waiting for the request to complete. For more in-depth coverage, Jani Hartikainen has written a great article on testing Promises.

Making our Tests Pass

Now let’s go ahead and implement the request. We’ll use the request-promise library to build a request to the FAA service mentioned earlier. Add the following to faa_data_helper.js that you created in the project's root directory:'

Let’s also add a test for the eventuality that an IATA airport code isn’t one the FAA service knows about or is responding with a non-200 status code. If the server is given a faulty IATA code, it appears to return a 404 status code. Our request library interprets this as an error.

Add the following test to within the describe('#getAirportStatus', function() { part of the test_faa_data_helper.js file. We will assert that an invalid IATA airport code returns an error:

A Hypothetical Response from Alexa

Now that we’ve proven our request works as expected, let’s consider the response Alexa should give to a user with this data. The data we receive indicates if there’s a flight delay—or not—so let’s have our helper give Alexa either, depending on the response from the FAA’s server:

"There is currently no delay at Hartsfield-Jackson Atlanta International. The current weather conditions are Light Snow, 36.0 F (2.2 C) and wind Northeast at 9.2mph."

or

"There is currently a delay for Hartsfield-Jackson Atlanta International. The average delay time is 57 minutes. Delay is because of the following: AIRLINE REQUESTED DUE TO DE-ICING AT AIRPORT / DAL AND DAL SUBS ONLY. The current weather conditions are Light Snow, 36.0 F (2.2 C) and wind Northeast at 9.2mph."

Note: Alexa will read glyphs, so you'll need to test the output in the voice simulator to make sure that everything is working as it should.

Let’s write a test for a helper method to build these strings. We’ll have two tests, one for a case where there isn’t a delay, and one where there is. I grabbed the following JSON for our test harness from the service, but feel free to get your own.

Add this to test/test_faa_data_helper.js within the describe('FAADataHelper', function():

Keep in mind that we are bouncing between adding to FAADataHelper and its test as we go—we’re TDDing it. For the sake of this article, we’re skipping ahead several “ping-pongs” between test file and implementation.

Crafting our Response

To make these tests pass, we’ll implement a formatAirportStatus(status) method that accepts the response from the FAA server and turns it into a sentence matching the expected above.

Let’s use the _.template() feature available in lodash to simplify the task of generating the strings Alexa will respond with. Add the following method to your FAADataHelper class:

Now our FAADataHelper is ready to be hooked up to a skill, which we will build in the next post. We’ll also go over how we can host the skill locally and mock the requests from Amazon Echo, enabling rapid feedback on any bugs.

Been reading along without setting up your environment? Check out the source code and get started!