kun432's blog

Alexaなどスマートスピーカーの話題中心に、Voiceflowの日本語情報を発信してます。たまにAWSやkubernetesなど。

〜スマートスピーカーやVoiceflowの記事は右メニューのカテゴリからどうぞ。〜

AlexaスキルのテストをBotiumでやってみた①

f:id:kun432:20210131175240p:plain

Alexaスキルのテスト、どうしてますか?色々やり方はあると思います。

今回はVoiceflowのcommunity forumで知った「Botium」を使ってみたいと思います。

目次

Botiumとは?

Botiumはチャットボットのテスト自動化プラットフォームです。

無料プランはありますが、E2Eや音声テストなどは有償プランじゃないと使えません。有償プランの価格は載ってないですけど、ちょっと調べてみた感じ、そこそこかかるみたいですね・・・・

ただし、ツールライブラリだけを使うなら無料かつOSSになっているので、今回はそちらでやってみましょう。

Botiumのツール

Botiumのツールは以下のようになっています。

  • Botium Core
    • Botiumのコアライブラリ
  • Botium CLI
    • Botium Coreを使ったCLI。テストもできます。
  • Botium Bindings
    • Botium Coreとテストランナーをつなげるもの。テストランナーにはMocha/Jasmin/Jestなどが使える。Botium CLIを使わずに、自前でテストランナーをつかいた場合はこちらを選ぶようです。
  • Botium Box
    • BotiumのCLIやライブラリを制御するためのGUIプラットフォーム。有償。

あと、上記には書いてないですが、以下もあります。

  • Botium Connector
    • チャットボットやフレームワーク、プラットフォームなどとつなげるためのもの。Alexaの場合はbotium-connector-alexa-smapiを使ってつなげる。

今回使うのは以下のみです。

  • botium-cli(botium core含む)
  • botium-connector

Botiumのインストールと基本的な使い方

botium-cliをインストールします。

$ npm install -g botium-cli

テストプロジェクトを初期化します。ディレクトリを作成してそこで行うのが良いでしょう。

$ mkdir alexa-test-sample && cd alexa-test-sample

$ botium-cli init
Botium Configuration File written to "./botium.json".
Botium Convo File written to "/path-to-somewhere/alexa-test-sample/give_me_a_picture.convo.txt".
Botium initialization ready. You should now run "botium-cli run --verbose --convos ." to verify.

botium-cli initを実行するとテストの雛形が作成されます。

$ tree
.
├── botium.json
└── give_me_a_picture.convo.txt

botium.jsonにテストプロジェクトの設定を記載します。デフォルトで用意されているテスト(botium-connector-echo)の設定が行われているようです。

{
  "botium": {
    "Capabilities": {
      "PROJECTNAME": "My Botium Project",
      "CONTAINERMODE": "echo"
    },
    "Sources": {},
    "Envs": {}
  }
}

.convo.txtがテストシナリオを記載するファイルになります。botium-cliは実行時に現在のディレクトリから*.convo.txtを探してテストを行うようになっているようですね。こちらもデフォルトで用意されているテスト用のシナリオが記載されているようですが、見て分かる通り、mochaやjestなどと違って、非常に簡易かつわかりやすい感じの記述になっていますね。

give me picture

#me
Hello, Bot!

#bot
You said: Hello, Bot!

#me
give me a picture

#bot
Here is a picture
MEDIA logo.png

では早速実行してみましょう。

$ botium-cli run --verbose --convos
  botium-cli Using Botium configuration file ./botium.json +0ms
  botium-cli-run command options: {
  botium-cli-run   _: [ 'run' ],
  botium-cli-run   verbose: true,
  botium-cli-run   v: true,
  botium-cli-run   convos: [ '.' ],
  botium-cli-run   C: [ '.' ],
  botium-cli-run   config: './botium.json',
  botium-cli-run   c: './botium.json',
  botium-cli-run   output: 'spec',
  botium-cli-run   testsuitename: 'Botium Test-Suite',
  botium-cli-run   n: 'Botium Test-Suite',
  botium-cli-run   expandutterances: false,
  botium-cli-run   expandscriptingmemory: false,
  botium-cli-run   timeout: 60,
  botium-cli-run   '$0': '../../.volta/tools/image/packages/botium-cli/bin/botium-cli'
  botium-cli-run } +0ms
  botium-cli-run Mocha Reporter "spec", options: undefined +0ms
  botium-core-BotDriver Loaded Botium configuration files /path-in-somewhere/alexa-test/botium.json +0ms
  botium-core-ScriptingProvider ReadConvosFromDirectory(.) found filenames: botium.json,give_me_a_picture.convo.txt +0ms
  botium-core-ScriptingProvider ReadConvosFromDirectory(.) found convos:
  botium-core-ScriptingProvider  1 give me picture ({ convoDir: '.', filename: 'give_me_a_picture.convo.txt' }): Line 3: #me - Hello, Bot! | Line 6: #bot - You said: Hello, Bot! | Line 9: #me - give me a picture | Line 12: #bot - Here is a picture MEDIA(logo.png) +4ms
  botium-core-ScriptingProvider ReadConvosFromDirectory(.) found utterances:
  botium-core-ScriptingProvider  none +1ms
  botium-core-ScriptingProvider ReadConvosFromDirectory(.) found partial convos:
  botium-core-ScriptingProvider  none +0ms
  botium-core-ScriptingProvider ReadConvosFromDirectory(.) scripting memories:
  botium-core-ScriptingProvider  none +0ms
  botium-cli-run ready reading convos (1), expanding convos ... +238ms
  botium-core-ScriptingProvider ExpandConvos - Using utterances expansion mode: all +0ms
  botium-cli-run ready expanding convos and utterances, number of test cases: (1). +23ms
  botium-cli-run adding test case give me picture (from: { convoDir: '.', filename: 'give_me_a_picture.convo.txt' }) +2ms


  Botium Test-Suite
  botium-core-BotDriver Build - Botium Core Version: 1.11.15 +280ms
  botium-core-BotDriver Build - Capabilites: {
  botium-core-BotDriver   PROJECTNAME: 'My Botium Project',
  botium-core-BotDriver   TESTSESSIONNAME: 'Botium Test Session',
  botium-core-BotDriver   TESTCASENAME: 'Botium Test Case',
  botium-core-BotDriver   TEMPDIR: 'botiumwork',
  botium-core-BotDriver   CLEANUPTEMPDIR: true,
  botium-core-BotDriver   WAITFORBOTTIMEOUT: 10000,
  botium-core-BotDriver   SIMULATE_WRITING_SPEED: false,
  botium-core-BotDriver   SIMPLEREST_PING_RETRIES: 6,
  botium-core-BotDriver   SIMPLEREST_PING_TIMEOUT: 10000,
  botium-core-BotDriver   SIMPLEREST_PING_VERB: 'GET',
  botium-core-BotDriver   SIMPLEREST_PING_UPDATE_CONTEXT: true,
  botium-core-BotDriver   SIMPLEREST_PING_PROCESS_RESPONSE: false,
  botium-core-BotDriver   SIMPLEREST_INIT_PROCESS_RESPONSE: false,
  botium-core-BotDriver   SIMPLEREST_STOP_RETRIES: 6,
  botium-core-BotDriver   SIMPLEREST_STOP_TIMEOUT: 10000,
  botium-core-BotDriver   SIMPLEREST_STOP_VERB: 'GET',
  botium-core-BotDriver   SIMPLEREST_START_RETRIES: 6,
  botium-core-BotDriver   SIMPLEREST_START_TIMEOUT: 10000,
  botium-core-BotDriver   SIMPLEREST_START_UPDATE_CONTEXT: true,
  botium-core-BotDriver   SIMPLEREST_START_PROCESS_RESPONSE: true,
  botium-core-BotDriver   SIMPLEREST_START_VERB: 'GET',
  botium-core-BotDriver   SIMPLEREST_POLL_VERB: 'GET',
  botium-core-BotDriver   SIMPLEREST_POLL_INTERVAL: 1000,
  botium-core-BotDriver   SIMPLEREST_POLL_UPDATE_CONTEXT: true,
  botium-core-BotDriver   SIMPLEREST_METHOD: 'GET',
  botium-core-BotDriver   SIMPLEREST_IGNORE_EMPTY: true,
  botium-core-BotDriver   SIMPLEREST_TIMEOUT: 10000,
  botium-core-BotDriver   SIMPLEREST_EXTRA_OPTIONS: {},
  botium-core-BotDriver   SIMPLEREST_STRICT_SSL: true,
  botium-core-BotDriver   SIMPLEREST_INBOUND_UPDATE_CONTEXT: true,
  botium-core-BotDriver   SIMPLEREST_CONTEXT_MERGE_OR_REPLACE: 'MERGE',
  botium-core-BotDriver   SCRIPTING_TXT_EOL: '\n',
  botium-core-BotDriver   SCRIPTING_XLSX_EOL_WRITE: '\r\n',
  botium-core-BotDriver   SCRIPTING_XLSX_HASHEADERS: true,
  botium-core-BotDriver   SCRIPTING_CSV_SKIP_HEADER: true,
  botium-core-BotDriver   SCRIPTING_CSV_QUOTE: '"',
  botium-core-BotDriver   SCRIPTING_CSV_ESCAPE: '"',
  botium-core-BotDriver   SCRIPTING_NORMALIZE_TEXT: true,
  botium-core-BotDriver   SCRIPTING_ENABLE_MEMORY: false,
  botium-core-BotDriver   SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS: false,
  botium-core-BotDriver   SCRIPTING_MATCHING_MODE: 'wildcardIgnoreCase',
  botium-core-BotDriver   SCRIPTING_UTTEXPANSION_MODE: 'all',
  botium-core-BotDriver   SCRIPTING_UTTEXPANSION_RANDOM_COUNT: 1,
  botium-core-BotDriver   SCRIPTING_UTTEXPANSION_NAMING_MODE: 'justLineTag',
  botium-core-BotDriver   SCRIPTING_UTTEXPANSION_NAMING_UTTERANCE_MAX: '16',
  botium-core-BotDriver   SCRIPTING_MEMORYEXPANSION_KEEP_ORIG: false,
  botium-core-BotDriver   SCRIPTING_FORCE_BOT_CONSUMED: false,
  botium-core-BotDriver   ASSERTERS: [],
  botium-core-BotDriver   LOGIC_HOOKS: [],
  botium-core-BotDriver   USER_INPUTS: [],
  botium-core-BotDriver   SECURITY_ALLOW_UNSAFE: true,
  botium-core-BotDriver   CONTAINERMODE: 'echo',
  botium-core-BotDriver   CONFIG: './botium.json'
  botium-core-BotDriver } +0ms
  botium-core-BotDriver Build - Sources : { LOCALPATH: '.', GITPATH: 'git', GITBRANCH: 'master', GITDIR: '.' } +1ms
  botium-core-BotDriver Build - Envs : { IS_BOTIUM_CONTAINER: true } +0ms
  botium-connector-PluginConnectorContainer-helper Botium plugin botium-connector-echo loaded. Plugin version is 0.0.16 +0ms
  botium-cli-run running testcase give me picture +56ms
  botium-core-Convo give me picture/Line 3: user says (cleaned by binary and base64 data and sourceData) {
  botium-core-Convo   "sender": "me",
  botium-core-Convo   "channel": null,
  botium-core-Convo   "not": false,
  botium-core-Convo   "optional": false,
  botium-core-Convo   "messageText": "Hello, Bot!",
  botium-core-Convo   "media": null,
  botium-core-Convo   "buttons": null,
  botium-core-Convo   "cards": null,
  botium-core-Convo   "forms": null,
  botium-core-Convo   "attachments": null,
  botium-core-Convo   "asserters": [],
  botium-core-Convo   "userInputs": [],
  botium-core-Convo   "logicHooks": []
  botium-core-Convo } +0ms
  botium-connector-echo UserSays called, echo back +0ms
  botium-core-Convo give me picture wait for bot  +1ms
  botium-core-Convo give me picture: bot says (cleaned by binary and base64 data and sourceData) {
  botium-core-Convo   "sender": "bot",
  botium-core-Convo   "messageText": "You said: Hello, Bot!",
  botium-core-Convo   "channel": "default"
  botium-core-Convo } +1ms
  botium-core-ScriptingMemory fill start: {} +0ms
  botium-core-ScriptingProvider assertBotResponse give me picture/Line 6 (Line 3: #me - Hello, Bot!) BOT: You said: Hello, Bot! = You said: Hello, Bot! ... +86ms
  botium-core-Convo give me picture/Line 9: user says (cleaned by binary and base64 data and sourceData) {
  botium-core-Convo   "sender": "me",
  botium-core-Convo   "channel": null,
  botium-core-Convo   "not": false,
  botium-core-Convo   "optional": false,
  botium-core-Convo   "messageText": "give me a picture",
  botium-core-Convo   "media": null,
  botium-core-Convo   "buttons": null,
  botium-core-Convo   "cards": null,
  botium-core-Convo   "forms": null,
  botium-core-Convo   "attachments": null,
  botium-core-Convo   "asserters": [],
  botium-core-Convo   "userInputs": [],
  botium-core-Convo   "logicHooks": []
  botium-core-Convo } +2ms
  botium-connector-echo UserSays called, echo back +3ms
  botium-core-Convo give me picture wait for bot  +0ms
  botium-core-Convo give me picture: bot says (cleaned by binary and base64 data and sourceData) {
  botium-core-Convo   "sender": "bot",
  botium-core-Convo   "messageText": "Here is a picture",
  botium-core-Convo   "media": [
  botium-core-Convo     {
  botium-core-Convo       "altText": "Botium Logo",
  botium-core-Convo       "mediaUri": "https://www.botium.ai/wp-content/uploads/2020/03/logo.png"
  botium-core-Convo     }
  botium-core-Convo   ],
  botium-core-Convo   "nlp": {
  botium-core-Convo     "intent": {
  botium-core-Convo       "name": "picture",
  botium-core-Convo       "confidence": 0.8
  botium-core-Convo     }
  botium-core-Convo   },
  botium-core-Convo   "channel": "default"
  botium-core-Convo } +1ms
  botium-core-ScriptingMemory fill start: {} +3ms
  botium-core-ScriptingProvider assertBotResponse give me picture/Line 12 (Line 9: #me - give me a picture) BOT: Here is a picture = Here is a picture ... +3ms
  botium-cli-run give me picture ready, calling done function. +10ms
    ✔ give me picture
  botium-connector-BaseContainer Cleanup rimrafing temp dir /Users/kun432/repository/alexa-test/botiumwork/My Botium Project 20220321 223340 fLHQW +0ms


  1 passing (54ms)

いろいろ出力されますが、最後に1 passingと表示されれば、convo.txtのシナリオ通りにボットとの会話が行われたということになります。

これでサンプルのテスト雛形は不要なのですべて削除してください。

$ rm -rf *

Alexaスキル向けテストプロジェクトの作成

Alexa用のbotium connectorをインストールします。

$ npm install -g botium-connector-alexa-smapi

Alexaスキル向けテストプロジェクトの初期化を行います。

$ botium-connector-alexa-smapi-cli init

ここから対話形式で設定を行います。画面の説明に従って設定を行えばOKです。順に行きましょう。

This wizard will guide you through the Botium Connector setup. Please follow the instructions.
It involves Copy&Paste from a web browser to this terminal window.



######## Step 1/3 - Create Amazon Security Profile ########
 1. Go to this url: https://developer.amazon.com/home.html
 2. Open "Settings" / "Security Profiles" and create a new profile or select an existing one
 3. Add this url to the "Allowed Return URLs": https://s3.amazonaws.com/ask-cli/response_parser.html


Copy & Paste the "Client-ID" here:

ターミナルを一旦このままにしておいて、https://developer.amazon.com/home.htmlにアクセス、ログインして、「設定」→「セキュリティプロファイル」と進み、既存のセキュリティプロファイルを選択するか、セキュリティプロファイルを新規作成します。ここでは新規に作成してみましょう。

f:id:kun432:20220321225052p:plain

f:id:kun432:20220321225100p:plain

f:id:kun432:20220321225109p:plain

セキュリティプロファイル名と説明を適当に記載して、保存します。

f:id:kun432:20220321225336p:plain

セキュリティプロファイルが作成されたら、「ウェブ設定」のタブをクリックします。

f:id:kun432:20220321225831p:plain

右下の編集をクリックします。

f:id:kun432:20220321225959p:plain

「許可された返信URL 」に先ほどターミナルに表示されていたURL(https://s3.amazonaws.com/ask-cli/response_parser.html)を入力して、保存します。

f:id:kun432:20220321230045p:plain

次に、セキュリティプロファイルのウェブ設定で表示されている「クライアントID」をコピーして、

f:id:kun432:20220321230443p:plain

ターミナルに貼り付けてENTER。

Copy & Paste the "Client-ID" here: amzn1.application-oa2-client.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

次にクライアントシークレットについて聞かれます。

Copy & Paste the "Client-Secret" here:

「シークレットを表示」をクリック

f:id:kun432:20220321231139p:plain

表示された「クライアントシークレット」をコピーして、

f:id:kun432:20220321231001p:plain

ターミナルに貼り付けてENTER。

Copy & Paste the "Client-Secret" here: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

次に表示されているURLにアクセスします。

######## Step 2/3 - Get Amazon Authorization Code ########
 1. Paste the following url to your browser and follow the instructions:
    https://www.amazon.com/ap/oa?response_type=code&client_id=amzn1.application-oa2-client.(...snip...)

Copy&Paste the Authorization Code you received:

Alexa開発者アカウント(amazon.co.jpアカウント)でログインします。

f:id:kun432:20220321231900p:plain

権限を聞かれるので許可します。

f:id:kun432:20220321232021p:plain

認証コードが生成されますので、これをコピーして、

f:id:kun432:20220321232030p:plain

ターミナルに貼り付けてENTER。

Copy&Paste the Authorization Code you received: XXXXXXXXXXXXXXXXX

Alexa開発者コンソール上で作成しているスキルが一覧表示されますので、テストを行うスキルの番号を入力します。今回はテスト用に用意したスキルを選択しました。

######## Step 3/3 - Selecting vendor id and skill ########


Using vendor id "XXXXXXXXXXXXXX" (hoge) for your account


Found 50 skills for your account
 1: "テストスキル1" (amzn1.ask.skill.XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX1)
 2: "テストスキル2" (amzn1.ask.skill.XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX2)
...snip...
 19: "トリップアドバイザー" (amzn1.ask.skill.XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX3)
...snip...
Enter Number of skill to use: 19

以下のように表示されればOKです。入力した情報をもとにbotium.jsonが生成されます。

######## Ready - Creating botium.json ########
Done.

中身を少し見てみましょう。

{
  "botium": {
    "Capabilities": {
      "CONTAINERMODE": "alexa-smapi",
      "ALEXA_SMAPI_REFRESHTOKEN": "XXX(...snip...)XXX",
      "ALEXA_SMAPI_CLIENTID": "amzn1.application-oa2-client.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
      "ALEXA_SMAPI_CLIENTSECRET": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
      "ALEXA_SMAPI_VENDORID": "XXXXXXXXXXXXXX",
      "ALEXA_SMAPI_SKILLID": "amzn1.ask.skill.XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX3"
    }
  }
}

CONTAINERMODEalexa-smapiになっていて、対話形式で入力したものが設定されているのがわかると思います。少しだけ追加します。

{
  "botium": {
    "Capabilities": {
      "PROJECTNAME": "トリップアドバイザー",      // 追加
      "ALEXA_SMAPI_LOCALE": "ja-JP",     // 追加
      "CONTAINERMODE": "alexa-smapi",
      "ALEXA_SMAPI_REFRESHTOKEN": "XXX(...snip...)XXX",
      "ALEXA_SMAPI_CLIENTID": "amzn1.application-oa2-client.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
      "ALEXA_SMAPI_CLIENTSECRET": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
      "ALEXA_SMAPI_VENDORID": "XXXXXXXXXXXXXX",
      "ALEXA_SMAPI_SKILLID": "amzn1.ask.skill.XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX3"
    }
  }
}

PROJECTNAMEはテストプロジェクトの名前です。これはあってもなくてもいいです。ALEXA_SMAPI_LOCALEはスキルのロケールです。これが定義されていない場合、どうやらen-USでテストが行われ、en-US向けにスキルが作成されていない場合は失敗します。日本語の場合はja-JPを設定しておきます。なお、説明のためにコメントを入れていますが、JSONではコメントが使えないので実際に設定する際には入れないようにしてください。

Botiumを使ったAlexaスキルのテスト

ではテストシナリオを作りましょう。その前にサンプルのスキルの会話フローをご紹介します。今回のサンプルはVoiceflowで作成しています。

f:id:kun432:20220321234411p:plain

行きたい都市名を言うと、おすすめの観光地を教えてくれるというものです。実際に作る場合はもっと複雑になると思いますが、テストのためのサンプルなので。ハッピーパスはこういう感じになります。

f:id:kun432:20220321234806p:plain

ではテストシナリオです。tripadvisor_happypath01.convo.txtという名前でシナリオを作りました。*.convo.txtであればなんでもよいです。

トリップアドバイザーのテスト:Happy Path #1

#me
トリップアドバイザーを開いて

#bot
はじめまして、トリップアドバイザースキルをご利用いただきありがとうございます。このスキルでは行きたい日本の都市名をいうとおすすめの観光名所を提案します。例えば「京都に行きたい」と言ってみてください。

#me
京都 かな

#bot
京都 ですね。京都 は清水寺がおすすめです。

注意する点としては、スロットおよび変数の前後には半角スペースが必要になります。これはVoiceflowの仕様によるかもしれません(Voiceflowでは必ず必要になる。通常のAlexaスキルだと不要かも)

ではテストを実行してみましょう。

$ botium-cli run


  Botium Test-Suite
    ✔ トリップアドバイザーのテスト:Happy Path #1 (10767ms)


  1 passing (12s)

はい、問題なくテスト成功していますね。

失敗の場合も見てみましょう。シナリオファイルを少し修正します。

#bot
京都 ですね。京都 は東大寺がおすすめです。

実際にはシナリオ側が間違っているのですが、エラーの確認のため、ということで。実行してみましょう。

$ botium-cli run


  Botium Test-Suite
    1) トリップアドバイザーのテスト:Happy Path #1


  0 passing (12s)
  1 failing

  1) Botium Test-Suite
       トリップアドバイザーのテスト:Happy Path #1:
     Error: トリップアドバイザーのテスト:Happy Path #1/Line 12: Bot response (on Line 9: #me - 京都 かな) "京都 ですね。京都 は清水寺がおすすめです。" expected to match "京都 ですね。京都 は東大寺がおすすめです。"
########################################
ASSERTION FAILED in TextMatchAsserter - Expected: ["京都 ですね。京都 は東大寺がおすすめです。"]  - Actual: "京都 ですね。京都 は清水寺がおすすめです。"
INPUT: 京都 かな
------------ TRANSCRIPT ----------------------------
#me: トリップアドバイザーを開いて
#bot: <speak>はじめまして、トリップアドバイザースキルをご利用いただきありがとうございます。このスキルでは行きたい日本の都市名をいうとおすすめの観光名所を提案します。例えば「京都に行きたい」と言ってみてください。</speak>
#me: 京都 かな
#bot: <speak>京都 ですね。京都 は清水寺がおすすめです。</speak>
      at wrapBotiumError (/path-in-somewhere/botium-cli/lib/node_modules/botium-cli/src/run/index.js:76:12)
      at finish (/path-in-somewhere/botium-cli/lib/node_modules/botium-cli/src/run/index.js:205:24)
      at /path-in-somewhere/botium-cli/lib/node_modules/botium-cli/src/run/index.js:218:11

はい、想定とテスト結果が異なっていることがわかりますね。このようにしてテストを行えばよいわけです。

また、テストファイルは複数用意することができます。同じパスに以下のファイルを追加します。

tripadvisor_happypath02.convo.txt

トリップアドバイザーのテスト:Happy Path #2

#me
トリップアドバイザーを開いて

#bot
はじめまして、トリップアドバイザースキルをご利用いただきありがとうございます。このスキルでは行きたい日本の都市名をいうとおすすめの観光名所を提案します。例えば「京都に行きたい」と言ってみてください。

#me
奈良 に行きたい

#bot
奈良 ですね。奈良 は東大寺がおすすめです。

tripadvisor_nomatch_city.convo.txt

トリップアドバイザーのテスト:都市名該当なし

#me
トリップアドバイザーを開いて

#bot
はじめまして、トリップアドバイザースキルをご利用いただきありがとうございます。このスキルでは行きたい日本の都市名をいうとおすすめの観光名所を提案します。例えば「京都に行きたい」と言ってみてください。

#me
神戸

#bot
ごめんなさい、神戸 はまだ対応していません。

では実行してみましょう。

$ botium-cli run


  Botium Test-Suite
    ✔ トリップアドバイザーのテスト:Happy Path #1 (10344ms)
    ✔ トリップアドバイザーのテスト:Happy Path #2 (10557ms)
    ✔ トリップアドバイザーのテスト:都市名該当なし (7728ms)


  3 passing (29s)

こんな感じでまとめてテストを実行してくれます。

まとめ

Botiumのシナリオはとても簡易でわかりやすいですね。mocha/jestなどは多少なりともコードの書き方を覚えておく必要がありますが、Botiumなら開発者じゃなくてもテスト用のシナリオをかけそうです。

とはいえ、これだけだと複雑なテストを書くには足りないですね。ということで、次回はシナリオの書き方についていろいろ見ていきたいと思います。