alice-tester
Библиотека для автоматического тестирования навыков Алисы на Node.js.
Позволяет эмулировать сообщения пользователя в соответствии с протоколом
и проверять ответы навыка.
Содержание
Установка
npm i alice-tester --save-dev
Использование
Если веб-сервер с навыком запущен локально на http://localhost:3000
, то тест может выглядеть так:
const assert = require('assert');
const User = require('alice-tester');
it('should get welcome message', async () => {
const user = new User('http://localhost:3000');
await user.enter();
assert.equal(user.response.text, 'Добро пожаловать!');
});
Запустить тест можно через mocha:
$ mocha test.js
✓ should get welcome message
1 passing (34ms)
Дальше можно добавить тест взаимодействия с навыком.
Спросить пользователем "Что ты умеешь?"
и проверить текстово-голосовой ответ и кнопки:
const assert = require('assert');
const User = require('alice-tester');
it('should show help', async () => {
const user = new User('http://localhost:3000');
await user.enter();
await user.say('Что ты умеешь?');
assert.equal(user.response.text, 'Я умею играть в города.');
assert.equal(user.response.tts, 'Я умею играть в город+а.');
assert.deepEqual(user.response.buttons, [{title: 'Понятно', hide: true}]);
});
Когда тестов станет больше, запуск/остановку сервера удобно вынести в before/after
хуки:
const assert = require('assert');
const User = require('alice-tester');
const server = require('./server');
const PORT = 3000;
before(done => {
server.listen(PORT, done);
});
after(done => {
server.close(done);
});
it('should get welcome message', async () => {
const user = new User(`http://localhost:${PORT}`);
await user.enter();
assert.equal(user.response.text, 'Добро пожаловать!');
});
it('should show help', async () => {
const user = new User(`http://localhost:${PORT}`);
await user.enter();
await user.say('Что ты умеешь?');
assert.equal(user.response.text, 'Я умею играть в города.');
});
Результат:
$ mocha test.js
✓ should get welcome message
✓ should show help
2 passing (37ms)
Более подробно про разработку тестов для навыков можно почитать в статье на Хабре.
API
User.config
Глобальный конфиг класса User
:
- generateUserId
{Function}
- функция генерации userId
. По умолчанию: () => `${Date.now()}-${Math.random()}`
- responseTimeout
{Number}
- таймаут для ответа навыка (мс). По умолчанию: 1000
- webhookUrl
{String|Function|HTTP.Server}
- дефолтный вебхук-урл. По умолчанию: ''
- stopWords
{Array<String|RegExp>}
- список стоп-слов. По умолчанию: undefined|null|NaN|true|false
Пример:
User.config.generateUserId = () => Date.now();
User.config.responseTimeout = 500;
User.config.webhookUrl = 'http://localhost:3000';
Создание нового пользователя для теста.
Параметры:
- webhookUrl
{?String|Function|HTTP.Server}
- вебхук-урл навыка в виде строки или инстанса http.Server
. Если не передан, используется дефолтный из User.config.webhookUrl
. - extraProps
{?Object|Function}
- объект с полями, которые будут добавлены к каждому запросу, либо функция модификации тела запроса.
Примеры:
const user = new User('http://localhost');
const user = new User('http://localhost', {session: {user_id: 'custom-user-id'}});
const user = new User('http://localhost', body => delete body.meta.interfaces.screen);
User.config.webhookUrl = 'http://localhost:3000';
const user = new User();
Вход пользователя в навык.
Параметры:
- message
{?String=''}
- фраза, с которой пользователь пришел в навык. При этом в original_utterance
по умолчанию будет "запусти навык тест {message}"
. - extraProps
{?Object|Function}
- объект с полями, которые будут добавлены к телу запросу, либо функция модификации тела запроса.
Returns: Promise<response>
Отправка сообщения в навык.
Параметры:
- message
{String}
- сообщение. По умолчанию одинаковое в command
и original_utterance
. - extraProps
{?Object|Function}
- объект с полями, которые будут добавлены к телу запросу, либо функция модификации тела запроса.
Returns: Promise<response>
Нажатие пользователем на кнопку с заданным текстом.
Если предыдущий запрос не вернул кнопок, то будет ошибка.
Если предыдущий запрос вернул кнопки с дополнительными данными (payload), то эти данные будут прикреплены к запросу.
Параметры:
- title
{String|RegExp}
- текст кнопки. - extraProps
{?Object|Function}
- объект с полями, которые будут добавлены к телу запросу, либо функция модификации тела запроса.
Returns: Promise<response>
Нажатие пользователем на изображение с заданным текстом.
Если предыдущий запрос не вернул изображений-кнопок, то будет ошибка.
Если предыдущий запрос вернул изображения-кнопки с дополнительными данными (payload), то эти данные будут прикреплены к запросу.
Параметры:
- title
{String|RegExp}
- текст изображения-кнопки. - extraProps
{?Object|Function}
- объект с полями, которые будут добавлены к телу запросу, либо функция модификации тела запроса.
Returns: Promise<response>
user.response
Поле response
из последнего ответа навыка.
user.body
Тело последнего ответа навыка.
user.id
Сгенерированный идентификатор пользователя.
user.sessionId
Сгенерированный идентификатор текущей сессии.
user.webhookUrl
Вебхук, на который шлет запросы пользователь.
user.history
История всех ответов для текущего пользователя.
Проверка времени ответа
Если время ответа на запрос превышает User.config.responseTimeout
, то тест упадет с ошибкой:
Response time (1056 ms) exceeded timeout (1000 ms)
Можно выставить любое другое значение порога, либо отключить проверку значением 0
.
Проверка размеров ответа
На многие поля ответа накладываются ограничения по длине.
Например, response.text
не может быть больше 1024 символов.
В процессе прогона тестов alice-tester
автоматически проверяет все ответы навыка на соответствие лимитам
и кидает ошибку в случае их нарушения:
Length of response.text (1049) is greater than allowed (1024): События романа «Война и мир» происходят ... и преодолевать любые трудности.
Проверка стоп-слов
Все ответы навыка при тестировании прогоняются через фильтр стоп-слов, которые обычно сигнализируют об ошибке в навыке.
Список стоп-слов по умолчанию:
undefined
null
NaN
true
false
Например, если в response.text
оказалась строка "Привет, undefined"
, то alice-tester
автоматически бросит ошибку:
Stop word "undefined" found in response.text: "Привет, undefined"
Отладка тестов
Для отладки тестов можно выставить переменную окружения DEBUG=alice-tester
(см debug).
Тогда в консоль будут выводится все отправляемые запросы и ответы:
DEBUG=alice-tester mocha test.js
В консоли:
alice-tester REQUEST: {"request":{"command":"","original_utterance":"","type":"SimpleUtterance"},"session":{"new":true,"user_id":"user-1","session_id":"session-1","message_id":1,"skill_id":"test-skill"},"meta":{"locale":"ru-RU","timezone":"Europe/Moscow","client_id":"ru.yandex.searchplugin/5.80 (Samsung Galaxy; Android 4.4)","interfaces":{"screen":{}}},"version":"1.0"} +0ms
alice-tester RESPONSE: {"version":"1.0","session":{"new":true,"user_id":"user-1","session_id":"session-1","message_id":1,"skill_id":"test-skill"},"response":{"text":"Это приватный навык и недоступен для публичного использования.","tts":"Это приватный навык и недоступен для публичного использования.","end_session":true}} +15ms
Лицензия
MIT @ Vitaliy Potapov