Alexaスキルのテストを自動化するASTD (リファレンス編)

テストデータの定義

TestTurnの定義

TestTurnの型定義を擬似コードで下記に示します。

type TestTurn = {
    skipValidation?: boolean,
    preProcessor?: function,
    postProcessor?: function,
    input: {
        speak: string,
        mode?: string
    },
    output: {
        type?: 'Standard' | 'Directive',
        outputSpeech: object,
        card?: object,
        reprompt?: object,
        shouldEndSession?: boolean
    }
};

※ TypeScriptの形式ですが、型は擬似的にJavaScriptのものを使っています。

outputでオプション (‘?’) になっているものは、スキルからは返されない可能性のあるものです。

ベースの定義

項目内容
skipValidation?outputの検証を行うかどうかのフラグです。
trueに設定されるとoutputの項目を検証しません。SMAPIの呼び出しが成功すれば、このテストターンは成功したと見なします。
省略可能で、省略値はfalseです。
preProcessor?このターンの前処理を行う関数を定義します。
function preprocessor() {
// do something …
}

引数も戻り値もありません。
Chai等のAssertionライブラリを使ってassertionが書けます。Assertされると、テストターンは実行されません。
テストターンの実行前に事前条件を設定する場合に使用します。例えばS3データストアにスキルのデータをロードするような場合です。
個別のテストターンではなく、テストケースの実行前に事前条件の設定をする場合は、テストケースのpreProcessorを指定します。
postProcessor?テストターンの実行後に実行すべき処理の関数を指定します。
function postprocesor(simulationResult) {
// do something …
}
simulationResultは、SMAPIから戻されたレスポンスです。
Chai等のAssertionライブラリを使ってassertionが書けます。
postProcessorは、テストターンの実行後に実行結果を検証する場合に使用します。例えばS3データストアに出力されたデータを検証します。
個別のテストターンではなく、テストケースの実行後に実行結果を検証する場合は、TestCaseのpostProcessorを指定します。

inputの定義

項目内容
speakスキルへの入力となる発話を定義します。
mode?‘FORCE_NEW_SESSION’ – 新しいセッションとして対話を開始します。
‘DEFAULT’ – 直前のセッションの状態に依存します。セッション中の場合は、セッションを継続します。セッション終了後であれば、新しいセッションを開始します。
省略値は’DEFAULT’です。

output.outputSpeechの定義

スキルからの発話テキストを定義します。発話テキストには下記の2種類の型があります。

  • SSML
  • Plain Text
SSML

SSML (Speech Synthesis Markup Language) 形式の発話テキストです。

{
    type: 'SSML',
    playBehavior?: string,
    ssml: string
}
項目内容
type‘SSML’を指定します。
playBehavior?下記の何れかを指定します。
‘ENQUEUE’ | ‘REPLACE_ALL’ | ‘REPLACE_ENQUEUED’
ssml発話テキストを定義します。
スキルからのレスポンスは、<speak></speak>のタグで囲まれていますが、テストデータには必要ありません。ASTDが検証前にタグを補います。
Plain Text

単純テキスト形式の発話テキストです。

{
    type: 'PlainText',
    playBehavior?: string,
    text: string,
}
項目内容
type‘PlainText’を指定します。
playBehavior?下記の何れかを指定します。
‘ENQUEUE’ | ‘REPLACE_ALL’ | ‘REPLACE_ENQUEUED’
text発話テキストを定義します。

output.cardの定義

スキルからのカード出力を定義します。カード出力には下記の4種類があります。

  • Simple Card
  • Standard Card
  • Link Account Card
  • Ask For Permissions Consent Card
Simple Card

タイトルと本文が表示されるカードです。

{
    type: 'Simple',
    title?: string,
    content?: string
}
項目内容
type‘Simple’を指定します。
title?カードのタイトルを定義します。
content?カードの本文を定義します。
Standard Card

タイトル、本文に加えて、イメージが表示されるカードです。

{
    type: 'Standard',
    title?: string,
    text?: string,
    image?: {
        smallImageUrl?: string,
        largeImageUrl?: string
    }
}
項目内容
type‘Standard’を指定します。
title?カードのタイトルを定義します。
text?カードの本文を定義します。
image?カードに表示するアイコンへのURLを定義します。
Ask For Permissions Consent Card

デバイス所有者の連絡先など、アクセス許可が必要なときに表示されるカードです。

{
    type: 'AskForPermissionsConsent',
    permissions: string[]
}
項目内容
type‘AskForPermissionsConsent’を指定します。
permissions要求されるアクセス許可の種類を定義します。
Link Account Card
{
    type: 'LinkAccount'
}
項目内容
type‘LinkAccount’を指定します。

output.repromptの定義

ユーザーに再度問いかけるための発話テキストです。

内容は、output.outputSpeechと同じ書式です。

output.shouldEndSessionの定義

セッションを継続するかどうかのフラグです。true, falseで設定します。

TestCaseの定義

TestCaseの型定義を擬似コードで下記に示します。

type TestCase = {
    title: string,
    turns: TestTurn[],
    preProcessor?: function,
    postProcessor?: function,
    before?: function,
    after?: function
};
項目内容
titleテストレポートに出力されるテストケースのタイトルを定義します。
turnsテストケースに含まれる一連の対話を表すテストターンを定義します。
preProcessor?テストケースの実行前に実行すべき処理の関数を指定します。
function preProcessor() {
    // do something …
}

引数も戻り値もありません。
Chai等のAssertionライブラリを使ってassertionが書けます。Assertされると、テストケースの実行は打ち切られます。
preProcessorは、テストケースの実行前に事前条件を設定する場合に使用します。例えばS3データストアにテストデータをロードするような場合です。
postProcessor?テストケースの実行後に実行すべき処理の関数を指定します。
function postProcessor() {
    // do something …
}
引数も戻り値もありません。
Chai等のAssertionライブラリを使ってassertionが書けます。Assertされると、テストケースの実行は打ち切られます。
postProcessorは、テストケースの実行後に実行結果を検証する場合に使用します。例えばS3データストアに出力されたデータを検証します。
before?MochaのHOOKであるbeforeとして実行されます。各テストケースはMochaのdescribeの中で実行されます。ここで設定されたbeforeは、そのdescribeにバインドされます。
after?beforeと同じく、describeにバインドされます。

TestDataの定義

TestDataの型定義を擬似コードで下記に示します。

type TestData = {
    title: string,
    testCases: TestCase[],
    locale: string
};
項目内容
titleテストレポートに出力されるテストのタイトルを定義します。
testCasesこのテストで実行されるテストケースを定義します。
locale対話に使われるロケール (言語) を指定します。日本語の場合は、’ja-JP’となります。

テンプレート

TypeScript版

import * as Astd from 'alexa-skill-test-driver';
import * as config from './config.json'

const testData: Astd.TestData = {
    // テストデータ
};

Astd.executeTestData(testData, config);

JavaScript版

const Astd = require('alexa-skill-test-driver');
const config = require('./config.json');

const testData = {
    // テストデータ
};

Astd.executeTestGroup(testData, config);

ASTDの実行

良く使われるMochaのオプション

オプション 説明
bailテストエラーが起きると、そこでテストを打ち切ります。
デフォルトでは、ターンの途中でテストエラーが発生すると、残りのターンをスキップして、次のテストケースに移ります。起動オプションでbailを指定すると、次のテストケースに移ることなく実行を打ち切ります。
slow <ms>Mochaはテストの実行時間を出力します。スレッショルドに対するマージンで、緑、黄色、赤で状況を表します。デフォルト値は75msです。そのままではASTDのテスト結果は全て赤 (Slow) になるため、適当なスレッショルドを設定する必要があります。
筆者は3秒ルールを考慮して3,000msを設定しています。 50% (1,500ms) 以下で緑、50% (1,500ms) を超えると黄、100% (3,000ms) を超えると赤で表示されます。
timeout <ms>テスト実行時のタイムアウトを指定します。これは各ターンの実行時間に相当します。
デフォルトは2,000ms (2秒) です。
スキルとの対話には、3-4秒かかることが多いこと、リトライ (最大3回) が発生する場合があることから、15,000ms (15秒) 程度は必要です。

ASTDの実行オプション

各テストデータは、テストデータの最後に記述された下記の関数により実行されます。

Astd.executeTest(
  testData, 
  config, 
  acceptUnexpectedDelegation, 
  dumpResponse, 
  skipUndefinedToBe, 
  skipUndefinedActual);
引数説明
testDataTestDataとして定義されたテストデータの本体です。
configSMAPIにアクセスするための構成情報です。テンプレートでは、./config.jsonファイルから読み込まれます。
acceptUnexpectedDelegation?オプショナル (省略値はfalse)
trueに設定すると、予期しないDelegation要求を受け付けます。

SMAPIから予期しないDelegation要求が返される場合があり、trueが設定されている場合は、エラーとせずに受け付けます。その場合は、outputSpeechに定義された発話テキストのみを、Delegation要求と一緒に返された発話テキストと比較します。またoutputSpeech以外の項目については検証を行いません。
構成ファイル (config.json) に定義することもできます。
dumpResponse?オプショナル (省略値はfalse)
trueに設定すると、SMAPIから返されたレスポンスを表示します。
構成ファイル (config.json) に定義することもできます。
skipUndefinedToBe?オプショナル (省略値はfalse)
trueに設定すると、テストデータに定義されていないoutputの項目の検証をスキップします。
skipUndefinedActual?オプショナル (省略値はfalse)
trueに設定すると、スキルからのレスポンスに定義されていないoutputの項目の検証をスキップします。

ASTDの構成ファイル

テンプレートでは、同じディレクトリにあるconfig.jsonファイルを読み込んでいます。

項目説明
skill_idアクセスするスキルのIDです。
開発者コンソールのスキルリストから取得できます。
client_id (*1*2)LWAから取得するクライアントID
client_secret (*1*2)LWAから取得するクライアントシークレット
refresh_token (*1*2)ASK CLIで取得するアクセストークン
acceptUnexpectedDelegation? (*3)オプショナル (省略値はfalse)
trueに設定すると、スキルから予期しないDialog.Delegateが返されても、エラーとして扱いません。
dumpResponse? (*3)オプショナル (省略値はfalse)
trueに設定すると、スキルから返されたレスポンスの内容を出力します。
skipUpdefinedToBe? (*3)オプショナル (省略値はfalse)
trueに設定すると、テストデータに定義されていないoutputの項目の検証をスキップします。
skipUndefinedActual? (*3)オプショナル (省略値はfalse)
trueに設定すると、スキルからのレスポンスに定義されていないoutputの項目の検証をスキップします。

*1 「SMAPIで使用するアクセストークンの取得」を参照
*2 「構成ファイルの用意」を参照
*3 「ASTDの実行オプション」を参照

参考

変更履歴

日付内容
2021/06/19記述内容の補足と改良
2021/06/10初版リリース
Alexa-Skill
スポンサーリンク