Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/vitalets/alice-tester
Библиотека для автоматического тестирования навыков Алисы на Node.js.
https://github.com/vitalets/alice-tester
alice alice-skills testing
Last synced: about 2 months ago
JSON representation
Библиотека для автоматического тестирования навыков Алисы на Node.js.
- Host: GitHub
- URL: https://github.com/vitalets/alice-tester
- Owner: vitalets
- Created: 2019-02-27T16:00:37.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2024-08-23T15:43:32.000Z (4 months ago)
- Last Synced: 2024-10-04T15:44:10.650Z (3 months ago)
- Topics: alice, alice-skills, testing
- Language: JavaScript
- Homepage:
- Size: 870 KB
- Stars: 14
- Watchers: 4
- Forks: 2
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- awesome-alice - alice-tester - Библиотека для автоматического тестирования навыков под Node.js (Разработка / Тестирование)
README
# alice-tester
[![Actions Status](https://github.com/vitalets/alice-tester/workflows/autotests/badge.svg)](https://github.com/vitalets/alice-tester/actions)
[![Coverage Status](https://coveralls.io/repos/github/vitalets/alice-tester/badge.svg?branch=master)](https://coveralls.io/github/vitalets/alice-tester?branch=master)
[![Known Vulnerabilities](https://snyk.io/test/github/vitalets/alice-tester/badge.svg?targetFile=package.json)](https://snyk.io/test/github/vitalets/alice-tester?targetFile=package.json)
[![npm](https://img.shields.io/npm/v/alice-tester.svg)](https://www.npmjs.com/package/alice-tester)
[![license](https://img.shields.io/npm/l/alice-tester.svg)](https://www.npmjs.com/package/alice-tester)Библиотека для автоматического тестирования навыков Алисы на Node.js.
Позволяет эмулировать сообщения пользователя в соответствии с [протоколом](https://tech.yandex.ru/dialogs/alice/doc/protocol-docpage/)
и проверять ответы навыка.## Содержание
- [Установка](#%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0)
- [Использование](#%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)
- [API](#api)
* [User.config](#userconfig)
* [new User([webhookUrl], [extraProps])](#new-userwebhookurl-extraprops)
* [user.enter([message], [extraProps])](#userentermessage-extraprops)
* [user.say(message, [extraProps])](#usersaymessage-extraprops)
* [user.tap(title, [extraProps])](#usertaptitle-extraprops)
* [user.tapImage(title, [extraProps])](#usertapimagetitle-extraprops)
* [user.response](#userresponse)
* [user.body](#userbody)
* [user.id](#userid)
* [user.sessionId](#usersessionid)
* [user.webhookUrl](#userwebhookurl)
* [user.history](#userhistory)
- [Проверка времени ответа](#%D0%BF%D1%80%D0%BE%D0%B2%D0%B5%D1%80%D0%BA%D0%B0-%D0%B2%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%B8-%D0%BE%D1%82%D0%B2%D0%B5%D1%82%D0%B0)
- [Проверка размеров ответа](#%D0%BF%D1%80%D0%BE%D0%B2%D0%B5%D1%80%D0%BA%D0%B0-%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%BE%D0%B2-%D0%BE%D1%82%D0%B2%D0%B5%D1%82%D0%B0)
- [Проверка стоп-слов](#%D0%BF%D1%80%D0%BE%D0%B2%D0%B5%D1%80%D0%BA%D0%B0-%D1%81%D1%82%D0%BE%D0%BF-%D1%81%D0%BB%D0%BE%D0%B2)
- [Отладка тестов](#%D0%BE%D1%82%D0%BB%D0%B0%D0%B4%D0%BA%D0%B0-%D1%82%D0%B5%D1%81%D1%82%D0%BE%D0%B2)
- [Лицензия](#%D0%BB%D0%B8%D1%86%D0%B5%D0%BD%D0%B7%D0%B8%D1%8F)## Установка
```bash
npm i alice-tester --save-dev
```## Использование
Если веб-сервер с навыком запущен локально на `http://localhost:3000`, то тест может выглядеть так:
```js
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](https://mochajs.org):
```
$ mocha test.js✓ should get welcome message
1 passing (34ms)
```Дальше можно добавить тест взаимодействия с навыком.
Спросить пользователем `"Что ты умеешь?"` и проверить текстово-голосовой ответ и кнопки:
```js
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` хуки:
```js
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 help2 passing (37ms)
```Более подробно про разработку тестов для навыков можно почитать в [статье на Хабре](https://habr.com/ru/post/441978/).
## API
### User.config
Глобальный конфиг класса `User`:
* **generateUserId** `{Function}` - функция генерации `userId`. По умолчанию: `` () => `${Date.now()}-${Math.random()}` ``
* **responseTimeout** `{Number}` - таймаут для ответа навыка (мс). По умолчанию: `1000`
* **webhookUrl** `{String|Function|HTTP.Server}` - дефолтный вебхук-урл. По умолчанию: `''`
* **stopWords** `{Array}` - список стоп-слов. По умолчанию: `undefined|null|NaN|true|false`Пример:
```js
User.config.generateUserId = () => Date.now();
User.config.responseTimeout = 500;
User.config.webhookUrl = 'http://localhost:3000';
```### new User([webhookUrl], [extraProps])
Создание нового пользователя для теста.
**Параметры:**
* **webhookUrl** `{?String|Function|HTTP.Server}` - вебхук-урл навыка в виде строки или инстанса `http.Server`. Если не передан, используется дефолтный из `User.config.webhookUrl`.
* **extraProps** `{?Object|Function}` - объект с полями, которые будут добавлены к каждому запросу, либо функция модификации тела запроса.Примеры:
```js
// обычный пользователь
const user = new User('http://localhost');// пользователь с заданным user_id
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();
```### user.enter([message], [extraProps])
Вход пользователя в навык.
**Параметры:**
* **message** `{?String=''}` - фраза, с которой пользователь пришел в навык. При этом в `original_utterance` по умолчанию будет `"запусти навык тест {message}"`.
* **extraProps** `{?Object|Function}` - объект с полями, которые будут добавлены к телу запросу, либо функция модификации тела запроса.**Returns**: `Promise`
### user.say(message, [extraProps])
Отправка сообщения в навык.
**Параметры:**
* **message** `{String}` - сообщение. По умолчанию одинаковое в `command` и `original_utterance`.
* **extraProps** `{?Object|Function}` - объект с полями, которые будут добавлены к телу запросу, либо функция модификации тела запроса.**Returns**: `Promise`
### user.tap(title, [extraProps])
Нажатие пользователем на кнопку с заданным текстом.
Если предыдущий запрос не вернул кнопок, то будет ошибка.
Если предыдущий запрос вернул кнопки с дополнительными данными (payload), то эти данные будут прикреплены к запросу.
**Параметры:**
* **title** `{String|RegExp}` - текст кнопки.
* **extraProps** `{?Object|Function}` - объект с полями, которые будут добавлены к телу запросу, либо функция модификации тела запроса.**Returns**: `Promise`
### user.tapImage(title, [extraProps])
Нажатие пользователем на изображение с заданным текстом.
Если предыдущий запрос не вернул изображений-кнопок, то будет ошибка.
Если предыдущий запрос вернул изображения-кнопки с дополнительными данными (payload), то эти данные будут прикреплены к запросу.
**Параметры:**
* **title** `{String|RegExp}` - текст изображения-кнопки.
* **extraProps** `{?Object|Function}` - объект с полями, которые будут добавлены к телу запросу, либо функция модификации тела запроса.**Returns**: `Promise`
### user.response
Поле `response` из последнего [ответа](https://tech.yandex.ru/dialogs/alice/doc/protocol-docpage/#response) навыка.
### user.body
Тело последнего [ответа](https://tech.yandex.ru/dialogs/alice/doc/protocol-docpage/#response) навыка.### 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](https://github.com/visionmedia/debug)).
Тогда в консоль будут выводится все отправляемые запросы и ответы:
```bash
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](https://github.com/vitalets)