Prueba de integración usando Bot Framework y DirectLine (1)
Desde que comencé a trabajar en una empresa por un corto período de tiempo, me asignaron trabajar en pruebas de integración para Bot Framework.
Mi trabajo en el grupo es hacer que el bot sea lo más estable posible, pero primero, ¿qué es Bot Framework?
Cree, conecte, implemente y administre bots inteligentes para interactuar naturalmente con sus usuarios en un sitio web, aplicación, Cortana, Microsoft Teams, Skype, Slack, Facebook Messenger y más. Comience rápidamente con un entorno completo de creación de bots, mientras paga solo por lo que usa.
Puede encontrar más información sobre Bot Framework directamente aquí.
La siguiente explicación no cubrirá toda la información básica sobre cómo funciona Bot Framework. Si no lo comprende, consulte la documentación oficial.
¿Por qué necesito una prueba de integración?
Las pruebas de integración son necesarias porque cada vez que uno de mis compañeros de trabajo implementa una solución, una nueva característica o incluso un nuevo error, estas pruebas se ejecutarán antes de enviar el código a producción y, si alguna de las pruebas falla, el código no pasará a producción, lo que significa que el usuario final no tendrá el error.
¿Prueba de integración en bots?
Creo que en los bots las pruebas de integración son bastante importantes. No puede tener un bot donde algunos de sus menús no funcionan o algunas de las funciones no devuelven nada.
Las empresas están utilizando bots para sus clientes porque no quieren que la gente esté ocupada con sus problemas; si un bot puede ayudar a un usuario, los demás trabajadores podrán utilizar su tiempo para hacer algo más importante.
Descripción general de la solución.
Para que esto funcione, utilicé un proyecto de prueba en Visual Studio, que utilizará WebClient para API Rest y un archivo Json, donde almacenaremos nuestros casos.
archivo JSON
{
"secret": "direct-line-secret",
"directlineGenerateTokenEndpoint": "https://directline.botframework.com/v3/directline/tokens/generate",
"directlineConversationEndpoint": "https://directline.botframework.com/v3/directline/conversations/",
"entries": [
{
"name": "DecirHola",
"request": {
"type": "message",
"text": "Hola",
"from": {
"id": "default-user",
"name": "User"
},
"locale": "es",
"textFormat": "plain",
"timestamp": "2018-04-09T08:04:37.195Z",
"channelData": {
"clientActivityId": "1523261059363.6264723268323733.0"
},
"entities": [
{
"type": "ClientCapabilities",
"requiresBotState": true,
"supportsTts": true,
"supportsListening": true
}
],
"id": "61hacck8j6jg"
},
"response": {
"type": "message",
"timestamp": "2018-04-09T08:04:37.901Z",
"localTimestamp": "2018-04-09T09:04:37+01:00",
"serviceUrl": "http://localhost:50629",
"channelId": "emulator",
"from": {
"id": "j98bbdf097a",
"name": "Bot"
},
"conversation": {
"id": "eabcie4be8ak"
},
"recipient": {
"id": "default-user"
},
"locale": "es",
"text": "No tengo respuesta para eso.",
"attachments": [],
"entities": [],
"replyToId": "61hacck8j6jg",
"id": "47me557ikbf7"
},
"assert": "Request.Text == Response.Text"
}
]
}
Como puedes ver tenemos:
- Secreto de línea directa -> secreto del bot publicado
- Punto final de generación de token de Directline -> punto final para obtener el token usando el secreto
- Punto final de conversación de línea directa -> punto final para jugar con la conversación
- Entrada -> el caso de prueba
- Solicitar -> qué enviamos a la conversación
- Respuesta -> qué esperamos obtener
- Afirmar -> qué estamos comparando
Deserialización
Tenemos el archivo json perfectamente formateado, ahora tenemos que cargarlo en la solución, por lo que usaremos JSON.NET y algunas clases. Primero tenemos la colección de entradas, que lo tiene todo, y luego tenemos, para cada colección, una lista de entradas.
/// <summary>
/// Object to parse from the file
/// </summary>
public class TestEntriesCollection
{
/// <summary>
/// DirectLine Secret
/// </summary>
[JsonProperty("secret")]
public string Secret { get; set; }
/// <summary>
/// Endpoint to get the token using the secret for DirectLine
/// </summary>
[JsonProperty("directlineGenerateTokenEndpoint")]
public string DirectLineGenerateTokenEndpoint { get; set; }
/// <summary>
/// Endpoint for a conversation in DirectLine
/// </summary>
[JsonProperty("directlineConversationEndpoint")]
public string DirectLineConversationEndpoint { get; set; }
/// <summary>
/// Entries list
/// </summary>
[JsonProperty("entries")]
public List<TestEntry> Entries { get; set; }
}
Y este es el objeto que tiene el nombre, solicitud, respuesta y afirmación para el caso de prueba.
public class TestEntry
{
/// <summary>
/// Entry name
/// </summary>
[JsonProperty("name")]
public string Name { get; set; }
/// <summary>
/// Activity requested by the entry
/// </summary>
[JsonProperty("request")]
public Activity Request { get; set; }
/// <summary>
/// Activity response expected by the entry
/// </summary>
[JsonProperty("response")]
public Activity Response { get; set; }
/// <summary>
/// Assert value in string
/// </summary>
[JsonProperty("assert")]
public string Assert { get; set; }
}
Análisis de json a objeto en el caso de prueba
Tener las clases para el objeto de análisis es bastante fácil ya que necesitamos leer como objeto.
// Load entries from file
var path = System.IO.File.ReadAllText(@"C:\data.json");
// Deserialize to object
var data = JsonConvert.DeserializeObject<TestEntriesCollection>(path);
Ahora, con esta colección, podremos recorrerla y obtener la información usando, por ejemplo, un foreach.
foreach (TestEntry entry in data.Entries)
{
....
}
Y eso es todo por esta parte, la siguiente parte incluirá la autorización para DirectLine, recuerde que todo el código está almacenado en mi github en este repositorio.