Test d'intégration avec Bot Framework et DirectLine (1)

· 4 min de lecture

Depuis que j’ai commencé à travailler dans une entreprise pendant une courte période, j’ai été chargé de travailler sur des tests d’intégration pour le Bot Framework.

Mon travail au sein du groupe consiste à rendre le bot aussi stable que possible, mais d’abord, qu’est-ce que Bot Framework ?

Créez, connectez, déployez et gérez des robots intelligents pour interagir naturellement avec vos utilisateurs sur un site Web, une application, Cortana, Microsoft Teams, Skype, Slack, Facebook Messenger, etc. Démarrez rapidement avec un environnement complet de création de robots, tout en ne payant que ce que vous utilisez.

Vous pouvez trouver plus d’informations sur Bot Framework directement ici.

** L’explication suivante ne couvrira pas toutes les informations de base sur le fonctionnement du Bot Framework. Si vous ne comprenez pas, veuillez consulter la documentation officielle. **

Pourquoi ai-je besoin d’un test d’intégration ?

Des tests d’intégration sont nécessaires car chaque fois qu’un de mes collègues propose un correctif, une nouvelle fonctionnalité ou même un nouveau bug, ces tests seront exécutés avant de pousser le code en production et si l’un des tests échoue, le code ne sera pas mis en production, ce qui signifie que l’utilisateur final n’aura pas le bug.

Test d’intégration dans les bots ?

Je crois que dans les bots, les tests d’intégration sont assez importants. Vous ne pouvez pas avoir un bot dont certains de leurs menus ne fonctionnent pas, ou certaines fonctionnalités ne renvoient rien.

Les entreprises utilisent des robots pour leurs clients parce qu’elles ne veulent pas que les gens soient occupés avec leurs problèmes. Si un robot peut aider un utilisateur, les autres travailleurs pourront utiliser leur temps pour faire quelque chose de plus important.

Aperçu de la solution.

Pour que cela fonctionne, j’ai utilisé un projet Test dans Visual Studio, qui utilisera WebClient pour l’API Rest et un fichier Json, où nous stockerons nos cas.

Fichier 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"
    }
  ]
}

Comme vous pouvez le constater, nous avons :

  • Secret Directline -> secret du bot publié
  • Point de terminaison de génération de jeton Directline -> point de terminaison pour obtenir le jeton en utilisant le secret
  • Point de terminaison de conversation Directline -> point de terminaison afin de jouer avec la conversation
  • Entrée -> le cas de test
    • Demander -> ce que nous envoyons à la conversation
    • Réponse -> ce que nous attendons d’obtenir
    • Affirmer -> qu’est-ce qu’on compare

Désérialisation

Nous avons le fichier json parfaitement formaté, nous devons maintenant le charger dans la solution, nous allons donc utiliser JSON.NET et certaines classes. Nous avons d’abord la collection d’entrées, qui contient tout, puis nous avons, pour chaque collection, une liste d’entrées.

    /// <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; }
    }

Et c’est l’objet qui porte le nom, la requête, la réponse et l’assertion pour le scénario de test.


    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; }
    }

Analyse de json en objet dans le scénario de test

Avoir les classes pour l’objet d’analyse, c’est assez simple car nous devons lire en tant qu’objet.

// Load entries from file
var path = System.IO.File.ReadAllText(@"C:\data.json");

// Deserialize to object
var data = JsonConvert.DeserializeObject<TestEntriesCollection>(path);

Désormais, avec cette collection, nous pourrons la parcourir et obtenir les informations en utilisant, par exemple, un foreach.

 foreach (TestEntry entry in data.Entries)
    {
      ....
    }

Et c’est tout pour cette partie, la partie suivante inclura l’autorisation pour DirectLine, rappelez-vous que tout le code est stocké dans mon github dans le référentiel this.