1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

LocalStackを使って、Alexaスキルのテストをする方法

Last updated at Posted at 2020-11-07

はじめに

Alexaスキル開発では、S3にデータを保存することがよくあります。
S3を使うためには、AWSのCredentialが必要になるのですが、わざわざテストのために管理するのはめんどくさいです。

LocalStackask-sdk-test を使って、いい感じにテストが出来る方法をやってみました。

やってみた

TypeScript, Serverless Frameworkを利用していますが、細かい部分は省略しています。
JavaScriptを利用する場合は、適宜読み替えていただければと思います。

LocalStack

LocalStackを使ってS3をローカルで動かします。
docker-composeを利用します。

docker-compose.yml
version: '2.1'

services:
  localstack:
    container_name: "localstack_main"
    image: localstack/localstack
    ports:
      - "4566:4566"
    environment:
      - SERVICES=s3

最近、利用ポートが一つにまとまったようです。


ダミーのProfileを設定します。

~/.aws/config
[default]
output =  json
region = ap-northeast-1

[profile localstack]
output = json
region = ap-northeast-1
~/.aws/credentials
[default]
aws_access_key_id = dummy
aws_secret_access_key = dummy

[localstack]
aws_access_key_id = dummy
aws_secret_access_key = dummy

LocalStackを起動して、Alexaで使うS3のデータを作っておきます。

$ docker-compose up -d
$ aws --endpoint-url http://localhost:4566 --profile localstack s3 mb s3://sample-skill-test
$ echo '{"hello": "world"}' | aws --endpoint-url http://localhost:4566 --profile localstack s3 cp - s3://sample-skill-test/amzn1.ask.account.VOID

Alexaスキル

一部の抜粋になりますが、ask-sdk-testが動くようにします。
(もしかしたら他にも必要なパッケージがあるかも... :pray:

package.json
{
...
  "scripts": {
    "test": "npx mocha -r ts-node/register -r tsconfig-paths/register test/index.spec.ts",
  },
  "devDependencies": {
    "@types/mocha": "8.0.3",
    "ask-sdk-test": "^2.5.0",
    "mocha": "8.2.1",
...
  },
...
}


ハローワールドのスキルを修正して、S3からデータを引っ張ってきます。

handler.ts
import AWS from "aws-sdk";

// s3ForcePathStyle を設定しないとhostの解決で失敗する
AWS.config.update({ region: "ap-northeast-1", s3ForcePathStyle: true });

// s3の設定
// testの時はLocalStackを使う
const s3PersistenceAdapter = new Adapter.S3PersistenceAdapter({
  bucketName: "sample-skill-test",
  s3Client: process.env.ENV == "test" ?
    new AWS.S3({endpoint: "http://localhost:4566"}) :
    new AWS.S3()
});

// handler
const LaunchRequestHandler = {
  canHandle(handlerInput: Ask.HandlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === "LaunchRequest";
  },
  async handle(handlerInput: Ask.HandlerInput) {
    const { hello } = await handlerInput.attributesManager.getPersistentAttributes();
    return handlerInput.responseBuilder
      .speak(hello)
      .withShouldEndSession(true)
      .getResponse();
  }
};

// Alexaの設定
export const alexa = Ask.SkillBuilders.custom()
  .addRequestHandlers(LaunchRequestHandler)
  .withApiClient(new Ask.DefaultApiClient())
  .withPersistenceAdapter(s3PersistenceAdapter)
  .lambda();

world というS3のデータが帰ってくるかを確認するテストです。

test/index.spec.ts
import { describe } from "mocha";
import {
  AlexaTest,
  LaunchRequestBuilder,
  SkillSettings
} from "ask-sdk-test";

process.env.ENV = "test";

import { alexa as skillHandler } from "../handler.ts";

// initialize the testing framework
const skillSettings: SkillSettings = {
  appId: "amzn1.ask.skill.00000000-0000-0000-0000-000000000000",
  userId: "amzn1.ask.account.VOID",
  deviceId: "amzn1.ask.device.VOID",
  locale: "en-US"
};

const alexaTest = new AlexaTest(skillHandler, skillSettings);

describe("LaunchRequest", () => {
  alexaTest.test([
    {
      request: new LaunchRequestBuilder(skillSettings).build(),
      says: "world",
      repromptsNothing: true,
      shouldEndSession: true
    }
  ]);
});


テストを実行します。

$ npm run test
> npx mocha -r ts-node/register -r tsconfig-paths/register test/index.spec.ts
...

  LaunchRequest
    ✓ returns the correct responses (52ms)


  1 passing (60ms)

まとめ

  • LocalStackを使って、Alexaスキルのテストをローカル環境で動かしました。
  • Github Actionsに組み込んでCIを作れたり、AWS費用がかからないのもよいです。
  • LocalStackは、S3だけでなくDynamoDBなど他のAWSサービスにも対応しているので、いろいろ応用出来るかと思います。

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?