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

· 4 min de lecture

Ceci est la dernière partie du guide, dans cette partie, nous évaluerons le texte de l’assertion dans le json.

Maintenant que nous avons utilisé le request et envoyé comme activity au bot, nous avons obtenu le response et nous devons comparer ce que le assert dans le json (la réponse que nous avons stockée dans le json, c’est la réponse attendue) avec la réponse que nous avons obtenue du bot.

** 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. **

Ajout de Microsoft.CodeAnalysis à la solution

Tout d’abord, nous devons inclure CodeAnalysis en tant que package NuGet.

https://gyazo.com/ce97a60ecab998f162f6ac7a2ab2c9a7

Après l’installation, n’oubliez pas d’ajouter le pacakge au fichier .cs.

using Microsoft.CodeAnalysis.CSharp.Scripting;

Création d’un objet Globals

Afin d’évaluer, nous devons transmettre les paramètres à l’évaluateur. Cet évaluateur a besoin d’un fichier de configuration.

 /// <summary>
/// Object to pass parameters to Roslyn compiler
/// </summary>
public class Globals
{
    /// <summary>
    /// ExpectedResponse
    /// </summary>
    public Activity Request;
    /// <summary>
    /// ReceivedResponse
    /// </summary>
    public Activity Response;
}

Cette partie est très importante, dans ce fichier de configuration, nous inclurons les objets que nous comparerons, donc pour nous, nous devons lui transmettre la réponse attendue et la réponse reçue.

Avec ces informations, il utilisera le assert dans le fichier json et évaluera ce qui est dit.

/// Arrange with new values
var globals = new Objects.Globals { Request = entry.Response, Response = latestResponse };

/// Assert
Assert.IsTrue(await CSharpScript.EvaluateAsync<bool>(entry.Assert, globals: globals));

Le EvaluateAsync<T> évalue et renvoie T, dans notre cas, nous transmettons le string à évaluer et globals, qui contient les données où il sera évalué.

Je vais essayer d’expliquer cela avec un exemple, en utilisant une entrée (qui a un nom, une requête, une réponse et une assertion).

{
      "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"
    }

Obtenons les éléments importants de cette entrée, d’abord l’assertion "assert": "Request.Text == Response.Text", cela signifie qu’il comparera le Request.Text avec le Response.Text, et renverra la valeur sous forme booléenne.

Mais lorsque nous appelons la fonction await CSharpScript.EvaluateAsync<bool>(entry.Assert, globals: globals) nous passons 2 paramètres :

  • string chaîne à évaluer -> "Request.Text == Response.Text"
  • globals données pour l’évaluateur -> dans ce cas, nous devons donner un Request et un Response, la demande est notre réponse attendue et la réponse est la réponse reçue.

Pendant que nous remplissons les données dans l’évaluateur, nous pouvons maintenant utiliser la chaîne et évaluer, elle renverra donc true ou false.

Terminé

Nous avons terminé, vous pouvez voir ici le TestMethod terminé

[TestMethod]
public async Task ShouldTestSingleCases()
{
    // Load entries from file
    var path = System.IO.File.ReadAllText(@"C:\data.json");

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

    /// Flow: Arrange -> Act -> arrange -> assert

    foreach (TestEntry entry in data.Entries)
    {
        /// Arrange with current requested values
        string token, newToken, conversationId;

        if (entry.Request.Type == ActivityTypes.Message)
        {
            /// Act

            /// 1 - Get token using secret from DirectLine in BotFramework panel
            token = Utils.uploadString<DirectLineAuth>(data.Secret, data.DirectLineGenerateTokenEndpoint, "").token;

            /// 2 -Create a new conversation
            var createdConversation = Utils.uploadString<DirectLineAuth>(token, data.DirectLineConversationEndpoint, "");

            // This returns a new token and a conversationId
            newToken = createdConversation.token;
            conversationId = createdConversation.conversationId;

            /// 3 - Send an activity to the conversation with new token and conversationId
            string directlineConversationActivitiesEndpoint = data.DirectLineConversationEndpoint + conversationId + "/activities";
            Utils.uploadString<DirectLineAuth>(newToken, directlineConversationActivitiesEndpoint, JsonConvert.SerializeObject(entry.Request));

            /// 4 - Get all activities, we get a List<activity> and a watermark
            var getLastActivity = Utils.downloadString<ActivityResponse>(newToken, directlineConversationActivitiesEndpoint);

            /// 5 - Get the latest activity which is the response we should be expecting
            var latestResponse = getLastActivity.activities[Int32.Parse(getLastActivity.watermark)];

            /// Arrange with new values
            var globals = new Objects.Globals { Request = entry.Response, Response = latestResponse };

            /// Assert
            Assert.IsTrue(await CSharpScript.EvaluateAsync<bool>(entry.Assert, globals: globals));
        }
    }
    await Task.CompletedTask;
}

Diagramme

Voici un diagramme de tout le flux que nous avons suivi pour arriver à ce point, j’espère que si vous n’avez pas compris quelque chose, cela clarifie les choses.

https://gyazo.com/1e3b7c9c2286844062878b4b8ca02d2d

Et c’est tout, cela est fait pour des cas uniques où le cas est 1 pour 1, l’utilisateur envoie un activity et le bot renvoie un autre simple activity.

J’espère que vous l’avez aimé, le prochain sera les cas de flux de tests avec plus d’une réponse.

https://gyazo.com/d964cfac395ed438a5282e60614863e7

N’oubliez pas que tout le code est stocké dans mon github dans le référentiel this.