Práticas recomendadas de teste

O desenvolvimento de uma Ação para a plataforma Actions on Google geralmente envolve a implementação do Dialogflow para o processamento de linguagem natural (PLN) e o fulfillment do Dialogflow, que processa a lógica da Ação. Ter testes na sua base de código ajuda a garantir que a ação tenha o desempenho esperado na produção.

Ao implementar testes de unidade, integração ou completos para a ação, considere o agente do Dialogflow e o fulfillment como componentes separados.

Um fluxograma prossegue de uma consulta do usuário para o Actions on Google, o Dialogflow
e um webhook de fulfillment e, por fim, retorna ao usuário.

Figura 1. Fluxograma descrevendo os sistemas a serem considerados para testes

Como testar um agente do Dialogflow

O agente e o fulfillment do Dialogflow são testados como componentes separados. As subseções a seguir descrevem como conceituar e testar o agente do Dialogflow para sua ação.

Dialogflow como um sistema de entrada e saída de consultas

Seu agente do Dialogflow é responsável por receber a consulta de um usuário, fazer a correspondência com uma intent e extrair as entidades predefinidas da consulta. O agente interage com o fulfillment transmitindo uma mensagem que contém a intent correspondente, os parâmetros e os metadados do Actions on Google.

Como desenvolvedor, você controla a configuração do agente do Dialogflow, como a estrutura de intents e entidades. Os metadados do Actions on Google vêm do Actions on Google e podem conter os dados corretos para o teste.

Durante os testes, concentre-se em permitir que o agente extraia corretamente os parâmetros de intent e faça a correspondência entre as consultas e as intents. Essa abordagem fornece uma métrica quantificável para avaliar o desempenho do agente. É possível calcular essa métrica preparando e usando casos de teste individuais ou um conjunto de validação.

É possível representar um agente do Dialogflow com uma consulta de texto como entrada e uma intent, além de parâmetros de intent extraídos como saída.

Figura 2. Representação do Dialogflow como sistema de consulta de entrada e saída

Testes de unidade

No agente do Dialogflow, é possível escrever testes em que cada caso espera uma consulta de texto como entrada e produz metadados de intent como saída. Esses metadados precisam conter (no mínimo) o nome da intent correspondente e uma lista de parâmetros correspondentes.

O endpoint detectIntent da API Dialogflow usa a consulta de texto como uma entrada e produz uma saída estruturada que contém o nome da intent resolvida e dos parâmetros extraídos. Ela é útil para avaliar o desempenho da correspondência com a intent do agente. Para uma referência completa de outros campos úteis, consulte a referência do QueryResult.

Este é um exemplo de teste:

it('choose_fact', async function() {
  // The `dialogflow` variable is an abstraction around the API that creates
  // and sends payloads to Dialogflow.
  const resJson = await dialogflow.detectIntent(
    'Tell me about the history of Google');
  expect(resJson.queryResult).to.include.deep.keys('parameters');
  // Check that Dialogflow extracted required entities from the query.
  expect(resJson.queryResult.parameters).to.deep.equal({
    'category': 'history',
    // Put any other parameters you wish were extracted
  });
  expect(resJson.queryResult.intent.displayName).to.equal('choose_fact');
});

Este snippet usa Mocha e Chai. Veja o exemplo completo funcional do teste de unidade do Dialogflow escrito em Node.js para Fatos sobre o Google.

Os arquivos de teste podem ser executados em paralelo porque a API Dialogflow aceita um sessionId como argumento. Assim, é possível ter um sandbox separado para cada conversa enquanto usa um único cliente da API Dialogflow.

Como você está fazendo solicitações na API Dialogflow, uma cobrança poderá ser realizada se sua cota de chamadas sem custo financeiro for atingida. Consulte cotas e limites para mais informações.

Testes de integração

O endpoint detectIntent da API Dialogflow também aciona o fulfillment de terceiros. Assim, é possível escrever casos de teste que cubram a integração entre o agente e o fulfillment do Dialogflow.

A principal diferença entre escrever testes de integração e de unidade para o Dialogflow é que, nesse teste, é possível declarar respostas provenientes do webhook, além da extração de entidade e intent do Dialogflow.

Veja o exemplo completo de trabalho de um teste de integração escrito em Node.js no repositório Fatos sobre o Google.

Como testar um webhook de fulfillment do Dialogflow

O agente e o fulfillment do Dialogflow são testados como componentes separados. As subseções a seguir descrevem como conceituar e testar o fulfillment da ação.

Fulfillment como um sistema JSON-in e JSON-out

Seu código de fulfillment do Dialogflow espera solicitações e produz respostas no formato JSON. Como resultado, é possível testar o código de fulfillment pensando nele como um sistema JSON-in e JSON-out. A solicitação contém metadados do Dialogflow e do Actions on Google, portanto, tem tudo o que é necessário para acionar um gerenciador de intent específico no fulfillment.

Para testar o acionamento de um gerenciador de intents, envie uma solicitação JSON (entrada) para a ação. Essa solicitação é transmitida para o fulfillment, que pode ser acessado na Internet. O fulfillment produz uma resposta JSON (saída), que pode ser avaliada para validação.

Um fulfillment pode ser representado com a entrada de solicitação JSON e a saída de resposta JSON do webhook.

Figura 3. Representação de um fulfillment como sistema JSON-in e JSON-out

Testes de unidade

Pense no código do webhook de fulfillment como um sistema que aceita uma entrada JSON e produz uma saída JSON. O processo de teste de uma ação é simplificado para fornecer uma solicitação ao fulfillment e verificar o JSON de saída resultante.

Isso dá a liberdade de hospedar o fulfillment localmente e enviar solicitações HTTP localmente para testes. Se você estiver usando a biblioteca de cliente Node.js para Actions on Google, também será possível enviar solicitações JSON diretamente para a camada de middleware da biblioteca de cliente.

Se você testar o código do webhook com entradas JSON e receber as saídas JSON esperadas, poderá dizer com confiança razoável que as partes que você controla funcionam corretamente. Suponha que o Dialogflow e o Actions on Google estejam funcionando corretamente porque geram os payloads JSON corretos. Esse isolamento fornece um modelo de programação simplificado para escrever testes.

Aqui está uma descrição geral do processo de teste:

  1. Use o simulador no Console do Actions para receber as solicitações JSON para cada etapa em um caso de uso. Salve-os como arquivos JSON. Também é possível criar essas solicitações usando as informações da documentação de referência do webhook.
  2. Crie testes para invocar o webhook com esses payloads.
  3. Para cada teste, verifique se o JSON de resposta contém os itens esperados.

Além disso, esse modelo permite testar o fulfillment do Dialogflow em uma configuração de integração contínua, já que o endpoint de fulfillment pode ser executado localmente, e a API Dialogflow tem um conceito integrado de sessões.

Um teste de exemplo vai ficar assim:

it('yes-history', function() {
  expect(jsonRes.payload).to.have.deep.keys('google');
  expect(jsonRes.payload.google.expectUserResponse).to.be.true;
  expect(jsonRes.payload.google.richResponse.items).to.have.lengthOf(3);
  expect(jsonRes.payload.google.richResponse.suggestions).to.have
    .deep.members([
      {'title': 'Sure'}, {'title': 'No thanks'},
    ]);
});

O snippet acima usa Mocha e Chai. Confira o exemplo completo escrito em Node.js no repositório Fatos sobre o Google.

Como projetar um fulfillment com teste de unidade

O código do webhook geralmente contém uma lógica de negócios personalizada que seu aplicativo usa para atender às necessidades dele. Além disso, o código do webhook também pode conter gerenciadores de intent.

Para melhorar a granularidade dos testes de unidade para o código de fulfillment, é recomendável organizar o código de modo que a lógica de negócios seja dissociada das rotinas de processamento de intents. Isso significa ter gerenciadores de intent e lógica de negócios em módulos separados, para que cada parte possa ser testada de forma independente.

Consulte nosso exemplo de ação de shiritori no GitHub (link em inglês). Nesse exemplo, functions/index.js e functions/shiritori/*.js contêm separadamente os gerenciadores de intent e a lógica de negócios, permitindo pacotes de testes mais robustos.

Testes de integração

Para escrever casos de teste que abrangem a integração entre o Dialogflow e o código do webhook de fulfillment, leia a seção de teste de integração do Dialogflow acima.

Testes de carga

Antes de implantar a ação na produção, também recomendamos testar a carga do fulfillment do webhook para detectar problemas de desempenho que causam degradação ou interrupção do serviço de fulfillment.

Veja alguns exemplos de problemas de desempenho que podem ser encontrados no teste de carga:

  • Computação e memória limitadas
  • Restrições de cota dos seus provedores
  • Leituras e gravações de dados lentas
  • Problemas de simultaneidade no código

Os cenários de teste de carga dependem do padrão de uso esperado ou histórico da ação. No entanto, os cenários comuns a serem testados são aumentos repentinos de carga (pico) e cargas sustentadas (absorção).

Identifique cenários em que seu webhook é chamado e executa operações que consomem muitos recursos. Operações típicas com uso intensivo de recursos incluem consultar um banco de dados, chamar outra API, executar operações de computação e com uso intensivo de memória, como a renderização de um arquivo de som.

Nesses cenários, é possível capturar solicitações enviadas pelos servidores do Actions on Google para o webhook dos registros do webhook ou do Stackdriver. Também é possível capturar solicitações do simulador do Console do Actions.

Quando tiver as solicitações, você poderá usar uma ferramenta de teste de carga para descobrir como o webhook responde em diferentes cenários de teste de carga. As subseções a seguir fornecem alguns exemplos de testes de pico e de imersão usando o ApacheBench (link em inglês).

Teste de pico

O teste de pico exige que você envie um número constante de solicitações para o webhook por algum tempo e aumente de repente a carga. Por exemplo, configure um teste que envia uma carga de 10 consultas por segundo (QPS) com alguns picos de 60 QPS.

É possível executar o seguinte comando do ApacheBench para enviar 60 solicitações simultâneas ao webhook:

ab -n 60 -c 60 -p ActionRequest.json -T 'application/json' https://example.com/webhookFunctionName

Suponha que o arquivo ActionRequest.json contenha o payload de solicitação capturado enviado para seu webhook.

Teste de imersão

O teste de imersão exige que você envie um número constante de solicitações para o webhook e observe a resposta. Por exemplo, você pode configurar um teste que envia uma carga constante de 10 a 20 QPS por vários minutos para ver se os tempos de resposta aumentam.

É possível executar o seguinte comando ApacheBench para enviar 1.200 solicitações, com 10 simultâneas a cada segundo:

ab -t 120 -n 1200 -p ActionRequest.json -T 'application/json' https://example.com/webhookFunctionName

Suponha que o arquivo ActionRequest.json contenha o payload de solicitação capturado enviado para seu webhook.

Analisar os resultados do teste de carga

Depois de executar testes de carga, analise os resultados dos tempos de resposta do webhook. Os indicadores de problemas na implementação do webhook geralmente são tendências como um tempo de resposta médio que aumenta a cada execução de teste ou um tempo de resposta do pior caso que seja inaceitável para a ação.

Testes de ponta a ponta

Faça testes completos antes de enviar a ação para aprovação usando o simulador do Console do Actions. Veja as etapas para testes completos usando o simulador do Console do Actions na documentação do Simulador do Actions. A execução desses testes ajuda a remover possíveis incertezas do componente de infraestrutura do Actions on Google.