
Quase um ano se passou desde que surgiu a oportunidade de criar suas habilidades para Alice, a assistente de voz da Yandex. Novas habilidades chegam diariamente no catálogo e seu número total é de várias centenas. Infelizmente, a comunicação com algumas habilidades para dizer o mínimo "não se soma". A habilidade faz um loop sobre a mesma frase ou geralmente é interrompida e não responde.
Neste artigo, considerarei escrever testes funcionais automatizados para uma habilidade no Node.js. A presença de tais testes permite que você crie melhores habilidades e confie em seu desempenho.
Ferramentas de teste existentes
O Skill for Alice é um servidor web que pode responder a solicitações POST em um formato específico. No momento, existem várias ferramentas nas quais você pode transferir o URL da habilidade e verificar seu funcionamento:
- O console oficial do desenvolvedor , onde você pode testar suas habilidades com texto e assistir a solicitações / respostas
- Simulador de Estação Aimylogic, suporta voz
- Projeto de código aberto dialogs.popstas.ru para teste local de habilidades
A peculiaridade dessas ferramentas é que elas oferecem alguma interface do usuário para testes de habilidades manuais. Eu quero as melhores tradições de integração contínua
execute o comando no console, verifique automaticamente todos os scripts e faça o upload da nova versão.
Ao mesmo tempo, não quero me aprofundar nos testes de unidade de módulos de habilidades individuais. O protocolo de solicitação / resposta é registrado na documentação e é nesse nível que é melhor testar. Então, mesmo tendo reescrito completamente a arquitetura interna, não há necessidade de alterar os testes. Ou seja, em essência, esses são testes funcionais .
Não encontrei uma biblioteca concluída para o Node.js para essa tarefa, portanto, escreveremos nossa própria :)
Habilidade de teste
Veja o exemplo de habilidade oficial do repositório Yandex no GitHub. Esta é a habilidade "Parrot", que simplesmente repete tudo o que o usuário disse. Construído com base na micro estrutura e contém apenas algumas linhas de código:
Na primeira chamada, a habilidade receberá uma mensagem em branco do usuário (original_utterance) e responderá "Hello!"
. Em outros casos, ele simplesmente copia a mensagem do usuário no campo response.text
.
Embrulhei o código de exemplo original do GitHub na função micro()
para que a exportação retorne um servidor http, que usaremos nos testes.
Plano de teste
Portanto, para cobrir essa habilidade com testes, você precisa do seguinte:
- Crie um servidor com habilidade na porta local
- Verifique dois casos:
- O usuário digita a habilidade, a habilidade deve responder "Olá!"
- O usuário envia uma mensagem para a habilidade, a habilidade deve responder com a mesma mensagem
- Pare o servidor com habilidade e mostre o relatório
Ao automatizar essas verificações, você pode executá-las antes de cada confirmação e garantir que nada esteja quebrado.
Escreveremos o código de teste de acordo com o plano, usando a sintaxe do mocha . Suponha que já tenhamos alguma classe de User
que possa fazer tudo o que precisamos:
Resta escrever a classe User
e será possível executar o teste.
Usuário virtual
A principal coisa que um usuário de teste deve poder fazer é enviar solicitações POST para o URL da habilidade com dados no formato desejado. O formato da solicitação é descrito na documentação . Agora, como não precisamos de todos os campos, deixei apenas o necessário para não aumentar o código de exemplo. Classe de User
com comentários:
Lançamento
Para começar, resta importar as classes de usuário e servidor para o arquivo de teste e também definir o valor da porta na qual o servidor aumentará:
Instale todas as dependências necessárias:
npm install micro node-fetch mocha
E execute o teste:
$ mocha test.js ✓ should get hello on enter 1 passing (34ms)
Está tudo bem, o teste passou!
Mas antes de prosseguir, você precisa garantir que o teste realmente funcione. Para fazer isso, substitua a habilidade de resposta "Olá!" para "olá!" e execute-o novamente:
$ mocha test.js 0 passing (487ms) 1 failing 1) should get hello on enter: AssertionError [ERR_ASSERTION]: '!' == 'Hello!' + expected - actual -! +Hello!
O teste mostrou um erro - como deveria ser.
Agora, com certeza, consideramos o primeiro caso a ser coberto.
Ensinamos o usuário a se comunicar
O segundo caso permanece quando o usuário envia uma mensagem para a habilidade e deve receber a mesma mensagem de volta. Para que o usuário possa "se comunicar", adicionei o método say(message)
à classe User
. Também refatorei um pouco: fiz o envio de solicitações http para um método separado e o usei dentro de enter()
e say(message)
:
O código de teste para o segundo caso é assim:
it('should reply the same message', async () => {
Começamos novamente e vemos que os dois testes passaram:
$ mocha test.js ✓ should get hello on enter ✓ should reply the same message 2 passing (37ms)
Passos adicionais
Da mesma forma, você pode adicionar scripts mais complexos à habilidade, cobrindo-os com testes. Isso garantirá que novas alterações não sejam antigas.
A infraestrutura de teste criada também pode ser aprimorada:
- modifique a classe
User
para que os campos restantes na solicitação possam ser alterados (por exemplo, marque a caixa que o usuário não possui uma tela) - conectar cobertura de código (por exemplo, nyc )
- pendure todas as verificações nos ganchos pré-confirmação / pré-envio (por exemplo, usando husky )
Eu tenho várias habilidades, então coloquei a classe de usuário de teste em um pacote alice-tester separado, talvez alguém seja útil.
Também publiquei o código de trabalho completo do exemplo no artigo no GitHub . Você pode clonar o repositório e experimentar.
Obrigado pela atenção!