Testing and Debugging

Testing Your Skill

At the top of the page, click the Build tab to get back to the Skill dashboard. Ensure that all items (except for In-Skill Products) under the Skill builder checklist are marked with green checkmarks, otherwise you won't be able to test your skill.

Back at the top of the page, click the Test tab and enable testing to view the Test Lab.

On the left, there's an Alexa Simulator where you can interact with Alexa however you want, and on the right, there's a Skill I/O section that isn't enabled yet. Let's activiate it. Type or speak into the Alexa Simulator:

Open Echomon

This will trigger the Skill I/O section and show a JSON Input and JSON Output. Alexa will speak the welcome response we configured earlier. Now let's try this one out:

Ask Echomon who is 25?

At this point, your test will fail! Don't panic! This is normal!

Debugging With Lambda

Right now, in your JSON Output, you should be seeing

null

Well, that's not very informative. Let's figure out why this is happening.

Let's go back to our AWS Console. At the very top, next to the Save button, there's a Test button and a dropdown menu. Select the dropdown menu, and select Configure Test Events. We'll select Create new test event, and under Event Template, search for Amazon Alexa Start Session. We can call this event launchRequest. Click Create at the bottom, and now click the Test button.

Now, you should be seeing a failed execution. Let's click Details, and you'll get an error that looks like the following:

{
  "errorMessage": "name 'should_end_session' is not defined",
  "errorType": "NameError",
  "stackTrace": [...]
}

It looks like we're missing a variable called should_end_session. Looking at the stack trace, it'll point you to a line number inside the get_welcome_response function. Looks like we forgot to include it here!

The should_end_session variable determines whether we should end the session or not. For example, if there's an error and you want Alexa to prompt the user to try again, you would set should_end_session = False, whereas if Alexa has completed the task, you'll set should_end_session = True. In this case, after the user has been welcomed to the Echomon skill, you'll want to set it to False because we want to give the user time to try out the skill.

def get_welcome_response():
    
    ...

    #TODO: Give a welcome response.
    reprompt_text = "Please try asking for a pokemon's name by, "
    should_end_session = False
    return build_response(session_attributes, build_speechlet_response(
        card_title, speech_output, reprompt_text, should_end_session))

Click Save again, then Test again, and the execution result should succeed!

Another way to debug is by checking CloudWatch Logs. Next to your Execution result, you should see a link to view your logs. Let's click that to see where it takes us.

Now, these CloudWatch logs are a little tricky to understand. Let's click the first one at the top of the list. This is the most recent test that we ran. We'll see that there's nothing here to note. However, when we click the second one, you'll see that there's a lot more information here, including a log that has the error message we had above.

name 'should_end_session' is not defined: Name Error

If we expand that option, you'll see a stacktrace that tells you where this error occurred. This can be useful when we're testing in our skill and it gives us strange errors.

Speaking of testing our skill, let's head back to our developer console. We'll try our command again. This time, you should get a Lambda response in JSON. If you scroll to the bottom of the JSON Input, you should see request.type is a LaunchRequest, and in the JSON Output under response.outputSpeech.text, it should print what you've told her to say.

Debugging With CloudWatch

Great! Now that our welcome response works, let's try one of our utterances. Type in or speak:

What is the name of Pokemon 25?

Again, the JSON Output we're seeing is

null

What do you think we should do?

If you scroll to the bottom of the JSON Input, you'll see a failed request:

"request": {
  "type": "SessionEndedRequest",
  "requestId": "amzn1.echo-api.request.d7863dae-ead9-412b-a663-d58da5584f70",
  "timestamp": "2019-06-03T19:19:51Z",
  "locale": "en-US",
  "reason": "ERROR",
  "error": {
    "type": "INVALID_RESPONSE",
    "message": "An exception occurred while dispatching the request to the skill."
  }
}

This isn't very useful in itself, but we can head back to our CloudWatch Logs and refresh the page. (If you closed that window already, you can find it again by running our launchRequest test from your AWS Console again, and clicking the logs button.)

Click the most recent log at the top of the logs table, and you'll see that the most recent log, once again, is showing an error:

name 'should_end_session' is not defined: Name Error

When we nail down the line it's erroring at, you'll see that this time, we're missing should_end_session in get_pokemon_name. Let's go ahead and add that boolean to the end of each condition.

if POKEMON_SLOT_NAME in intent['slots']:
    pokemon_number = intent['slots'][POKEMON_SLOT_NAME]['value']
    pokemon_name = get_pokemon(pokemon_number)
    speech_output = "Pokedex entry " + pokemon_number + " is named " + pokemon_name + "."
    should_end_session = True
else:
    speech_output = "I'm not sure what you mean by that. " \
                    "Please try again."
    should_end_session = False

Now click Save, and go back to your Developer Console. Try entering your utterance again.

Ask echomon what is the name of Pokemon 25?

Now Alexa should respond with Pikachu!

You'll also notice that in your JSON Input at the very bottom, you'll see our request:

"request": {
  "type": "IntentRequest",
  "requestId": "amzn1.echo-api.request.434b53a7-7c3c-4a27-8f59-5457e130ece5",
  "timestamp": "2019-06-02T04:24:09Z",
  "locale": "en-US",
  "intent": {
    "name": "GetPokemonIntent",
    "confirmationStatus": "NONE",
    "slots": {
      "PokedexNumber": {
        "name": "PokedexNumber",
        "value": "25",
        "confirmationStatus": "NONE",
        "source": "USER"
      }
    }
  }
}

This looks great! Just as we expect it to. Another way to debug is to copy the whole of your JSON Input and create a new test case in your AWS Console and run it there. You'll see that your execution succeeds, and the result of that looks just like the body of the JSON Output.

Edge Cases

Don't forget that it's always good practice to test your edge cases. Remember that the list we've provided consists of first generation Pokemon. This means that only asking for Pokemon #1 through #151 are valid. If you ask Alexa "Who is 200", the Lambda response will be invalid.

Since this isn't an Alexa specific debugging issue, see if you can debug this yourself! Remember that the value stored inside of our request object is a string, not an integer. To convert from string to integer, you can use int(string).

← Previous
Next →