{"id":13633442,"url":"https://github.com/vitalets/alice-tester","last_synced_at":"2025-06-24T06:36:27.285Z","repository":{"id":44917875,"uuid":"172946016","full_name":"vitalets/alice-tester","owner":"vitalets","description":"Библиотека для автоматического тестирования навыков Алисы на Node.js.","archived":false,"fork":false,"pushed_at":"2024-08-23T15:43:32.000Z","size":891,"stargazers_count":16,"open_issues_count":2,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-12T05:17:46.421Z","etag":null,"topics":["alice","alice-skills","testing"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vitalets.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["vitalets"]}},"created_at":"2019-02-27T16:00:37.000Z","updated_at":"2025-04-09T10:13:56.000Z","dependencies_parsed_at":"2024-08-23T17:27:04.208Z","dependency_job_id":"51412788-2269-460d-9689-8738f9bea0ec","html_url":"https://github.com/vitalets/alice-tester","commit_stats":{"total_commits":131,"total_committers":4,"mean_commits":32.75,"dds":0.2442748091603053,"last_synced_commit":"32cbe563d89cbc6a82597ad7ae732a9a40f07871"},"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vitalets%2Falice-tester","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vitalets%2Falice-tester/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vitalets%2Falice-tester/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vitalets%2Falice-tester/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vitalets","download_url":"https://codeload.github.com/vitalets/alice-tester/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248991526,"owners_count":21194893,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alice","alice-skills","testing"],"created_at":"2024-08-01T23:00:43.329Z","updated_at":"2025-04-15T01:44:06.454Z","avatar_url":"https://github.com/vitalets.png","language":"JavaScript","funding_links":["https://github.com/sponsors/vitalets"],"categories":["Разработка"],"sub_categories":["Тестирование"],"readme":"# alice-tester\n\n[![Actions Status](https://github.com/vitalets/alice-tester/workflows/autotests/badge.svg)](https://github.com/vitalets/alice-tester/actions)\n[![Coverage Status](https://coveralls.io/repos/github/vitalets/alice-tester/badge.svg?branch=master)](https://coveralls.io/github/vitalets/alice-tester?branch=master)\n[![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)\n[![npm](https://img.shields.io/npm/v/alice-tester.svg)](https://www.npmjs.com/package/alice-tester)\n[![license](https://img.shields.io/npm/l/alice-tester.svg)](https://www.npmjs.com/package/alice-tester)\n\nБиблиотека для автоматического тестирования навыков Алисы на Node.js. \nПозволяет эмулировать сообщения пользователя в соответствии с [протоколом](https://tech.yandex.ru/dialogs/alice/doc/protocol-docpage/)\nи проверять ответы навыка.\n\n## Содержание\n\n\u003c!-- toc --\u003e\n\n- [Установка](#%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0)\n- [Использование](#%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)\n- [API](#api)\n  * [User.config](#userconfig)\n  * [new User([webhookUrl], [extraProps])](#new-userwebhookurl-extraprops)\n  * [user.enter([message], [extraProps])](#userentermessage-extraprops)\n  * [user.say(message, [extraProps])](#usersaymessage-extraprops)\n  * [user.tap(title, [extraProps])](#usertaptitle-extraprops)\n  * [user.tapImage(title, [extraProps])](#usertapimagetitle-extraprops)\n  * [user.response](#userresponse)\n  * [user.body](#userbody)\n  * [user.id](#userid)\n  * [user.sessionId](#usersessionid)\n  * [user.webhookUrl](#userwebhookurl)\n  * [user.history](#userhistory)\n- [Проверка времени ответа](#%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)\n- [Проверка размеров ответа](#%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)\n- [Проверка стоп-слов](#%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)\n- [Отладка тестов](#%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)\n- [Лицензия](#%D0%BB%D0%B8%D1%86%D0%B5%D0%BD%D0%B7%D0%B8%D1%8F)\n\n\u003c!-- tocstop --\u003e\n\n## Установка\n```bash\nnpm i alice-tester --save-dev\n```\n\n## Использование\nЕсли веб-сервер с навыком запущен локально на `http://localhost:3000`, то тест может выглядеть так:\n```js\nconst assert = require('assert');\nconst User = require('alice-tester');\n\nit('should get welcome message', async () =\u003e {\n  const user = new User('http://localhost:3000');\n  await user.enter();\n  \n  assert.equal(user.response.text, 'Добро пожаловать!');\n});\n```\n\nЗапустить тест можно через [mocha](https://mochajs.org):\n```\n$ mocha test.js\n\n  ✓ should get welcome message\n\n  1 passing (34ms)\n```\n\nДальше можно добавить тест взаимодействия с навыком.\nСпросить пользователем `\"Что ты умеешь?\"` и проверить текстово-голосовой ответ и кнопки:\n```js\nconst assert = require('assert');\nconst User = require('alice-tester');\n\nit('should show help', async () =\u003e {\n  const user = new User('http://localhost:3000');\n  await user.enter();\n  await user.say('Что ты умеешь?');\n\n  assert.equal(user.response.text, 'Я умею играть в города.');\n  assert.equal(user.response.tts, 'Я умею играть в город+а.');\n  assert.deepEqual(user.response.buttons, [{title: 'Понятно', hide: true}]);\n});\n```\n\nКогда тестов станет больше, запуск/остановку сервера удобно вынести в `before/after` хуки:\n```js\nconst assert = require('assert');\nconst User = require('alice-tester');\nconst server = require('./server');\n\nconst PORT = 3000;\n\nbefore(done =\u003e {\n  server.listen(PORT, done);\n});\n\nafter(done =\u003e {\n  server.close(done);\n});\n\nit('should get welcome message', async () =\u003e {\n  const user = new User(`http://localhost:${PORT}`);\n  await user.enter();\n\n  assert.equal(user.response.text, 'Добро пожаловать!');\n});\n\nit('should show help', async () =\u003e {\n  const user = new User(`http://localhost:${PORT}`);\n  await user.enter();\n  await user.say('Что ты умеешь?');\n\n  assert.equal(user.response.text, 'Я умею играть в города.');\n});\n```\n\nРезультат:\n```\n$ mocha test.js\n\n  ✓ should get welcome message\n  ✓ should show help\n\n  2 passing (37ms)\n```\n\nБолее подробно про разработку тестов для навыков можно почитать в [статье на Хабре](https://habr.com/ru/post/441978/). \n\n## API\n\n### User.config\nГлобальный конфиг класса `User`:\n  * **generateUserId** `{Function}` - функция генерации `userId`. По умолчанию: `` () =\u003e `${Date.now()}-${Math.random()}` ``\n  * **responseTimeout** `{Number}` - таймаут для ответа навыка (мс). По умолчанию: `1000`\n  * **webhookUrl** `{String|Function|HTTP.Server}` - дефолтный вебхук-урл. По умолчанию: `''`\n  * **stopWords** `{Array\u003cString|RegExp\u003e}` - список стоп-слов. По умолчанию: `undefined|null|NaN|true|false`\n\nПример:\n```js\nUser.config.generateUserId = () =\u003e Date.now();\nUser.config.responseTimeout = 500;\nUser.config.webhookUrl = 'http://localhost:3000';\n```\n\n### new User([webhookUrl], [extraProps])\nСоздание нового пользователя для теста.  \n**Параметры:**\n  * **webhookUrl** `{?String|Function|HTTP.Server}` - вебхук-урл навыка в виде строки или инстанса `http.Server`. Если не передан, используется дефолтный из `User.config.webhookUrl`.\n  * **extraProps** `{?Object|Function}` - объект с полями, которые будут добавлены к каждому запросу, либо функция модификации тела запроса.\n\nПримеры:\n```js\n// обычный пользователь\nconst user = new User('http://localhost');\n\n// пользователь с заданным user_id\nconst user = new User('http://localhost', {session: {user_id: 'custom-user-id'}});\n\n// пользователь без экрана\nconst user = new User('http://localhost', body =\u003e delete body.meta.interfaces.screen);\n\n// используем дефолтный вебхук-урл\nUser.config.webhookUrl = 'http://localhost:3000';\nconst user = new User();\n```\n\n### user.enter([message], [extraProps])\nВход пользователя в навык.  \n**Параметры:**\n  * **message** `{?String=''}` - фраза, с которой пользователь пришел в навык. При этом в `original_utterance` по умолчанию будет `\"запусти навык тест {message}\"`.\n  * **extraProps** `{?Object|Function}` - объект с полями, которые будут добавлены к телу запросу, либо функция модификации тела запроса.\n\n**Returns**: `Promise\u003cresponse\u003e`\n\n### user.say(message, [extraProps])\nОтправка сообщения в навык.  \n**Параметры:**\n  * **message** `{String}` - сообщение. По умолчанию одинаковое в `command` и `original_utterance`.\n  * **extraProps** `{?Object|Function}` - объект с полями, которые будут добавлены к телу запросу, либо функция модификации тела запроса.\n\n**Returns**: `Promise\u003cresponse\u003e`\n\n### user.tap(title, [extraProps])\nНажатие пользователем на кнопку с заданным текстом.\nЕсли предыдущий запрос не вернул кнопок, то будет ошибка.\nЕсли предыдущий запрос вернул кнопки с дополнительными данными (payload), то эти данные будут прикреплены к запросу.   \n**Параметры:**\n  * **title** `{String|RegExp}` - текст кнопки.\n  * **extraProps** `{?Object|Function}` - объект с полями, которые будут добавлены к телу запросу, либо функция модификации тела запроса.\n\n**Returns**: `Promise\u003cresponse\u003e`\n\n### user.tapImage(title, [extraProps])\nНажатие пользователем на изображение с заданным текстом.\nЕсли предыдущий запрос не вернул изображений-кнопок, то будет ошибка.\nЕсли предыдущий запрос вернул изображения-кнопки с дополнительными данными (payload), то эти данные будут прикреплены к запросу.   \n**Параметры:**\n  * **title** `{String|RegExp}` - текст изображения-кнопки.\n  * **extraProps** `{?Object|Function}` - объект с полями, которые будут добавлены к телу запросу, либо функция модификации тела запроса.\n\n**Returns**: `Promise\u003cresponse\u003e`\n\n### user.response\nПоле `response` из последнего [ответа](https://tech.yandex.ru/dialogs/alice/doc/protocol-docpage/#response) навыка.\n \n### user.body\nТело последнего [ответа](https://tech.yandex.ru/dialogs/alice/doc/protocol-docpage/#response) навыка.\n\n### user.id\nСгенерированный идентификатор пользователя.\n\n### user.sessionId\nСгенерированный идентификатор текущей сессии.\n\n### user.webhookUrl\nВебхук, на который шлет запросы пользователь.\n\n### user.history\nИстория всех ответов для текущего пользователя.\n\n## Проверка времени ответа\nЕсли время ответа на запрос превышает `User.config.responseTimeout`, то тест упадет с ошибкой:\n```\nResponse time (1056 ms) exceeded timeout (1000 ms)\n```\nМожно выставить любое другое значение порога, либо отключить проверку значением `0`.\n\n## Проверка размеров ответа\nНа многие поля ответа накладываются ограничения по длине. \nНапример, `response.text` не может быть больше 1024 символов.\nВ процессе прогона тестов `alice-tester` автоматически проверяет все ответы навыка на соответствие лимитам\nи кидает ошибку в случае их нарушения:\n```\nLength of response.text (1049) is greater than allowed (1024): События романа «Война и мир» происходят ... и преодолевать любые трудности.\n```\n\n## Проверка стоп-слов\nВсе ответы навыка при тестировании прогоняются через фильтр стоп-слов, которые обычно сигнализируют об ошибке в навыке.\nСписок стоп-слов по умолчанию:\n```\nundefined\nnull\nNaN\ntrue\nfalse\n```\nНапример, если в `response.text` оказалась строка `\"Привет, undefined\"`, то `alice-tester` автоматически бросит ошибку:\n```\nStop word \"undefined\" found in response.text: \"Привет, undefined\"\n```\n\n## Отладка тестов\nДля отладки тестов можно выставить переменную окружения `DEBUG=alice-tester` (см [debug](https://github.com/visionmedia/debug)).\nТогда в консоль будут выводится все отправляемые запросы и ответы:\n```bash\nDEBUG=alice-tester mocha test.js\n```\nВ консоли:\n```\nalice-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\nalice-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\n```\n\n## Лицензия\nMIT @ [Vitaliy Potapov](https://github.com/vitalets)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvitalets%2Falice-tester","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvitalets%2Falice-tester","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvitalets%2Falice-tester/lists"}