Integrationstest mit Bot Framework und DirectLine (3)

· 4 Min. Lesezeit

Dies ist der neueste Teil des Leitfadens. In diesem Teil werden wir den Text aus der Behauptung im JSON auswerten.

Nachdem wir nun den request verwendet und als activity an den Bot gesendet haben, haben wir den response erhalten und müssen den assert im JSON (die Antwort, die wir im JSON gespeichert haben, dies ist die erwartete Antwort) mit der Antwort vergleichen, die wir vom Bot erhalten haben.

Die folgende Erklärung deckt nicht alle grundlegenden Informationen zur Funktionsweise des Bot Frameworks ab. Wenn Sie es nicht verstehen, schauen Sie sich bitte die offizielle Dokumentation an.

Hinzufügen von Microsoft.CodeAnalysis zur Lösung

Zunächst müssen wir CodeAnalysis als NuGet-Paket einbinden.

https://gyazo.com/ce97a60ecab998f162f6ac7a2ab2c9a7

Denken Sie nach der Installation daran, das Paket zur Datei .cs hinzuzufügen.

using Microsoft.CodeAnalysis.CSharp.Scripting;

Erstellen eines Globals-Objekts

Zur Auswertung müssen wir die Parameter an den Auswerter übergeben. Dieser Evaluator benötigt eine Konfigurationsdatei.

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

Dieser Teil ist sehr wichtig. In dieser Konfigurationsdatei werden wir angeben, welche Objekte wir vergleichen werden. Daher müssen wir ihm die erwartete Antwort und die erhaltene Antwort übergeben.

Mit diesen Informationen wird das assert in der JSON-Datei verwendet und ausgewertet, was gesagt wird.

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

Das EvaluateAsync<T> wertet T aus und gibt es zurück. In unserem Fall übergeben wir das auszuwertende string und das globals, das die Daten enthält, in denen es ausgewertet wird.

Ich werde versuchen, dies anhand eines Beispiels zu erklären, indem ich einen Eintrag verwende (der einen Namen, eine Anfrage, eine Antwort und eine Behauptung enthält).

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

Lassen Sie uns die wichtigen Dinge aus diesem Eintrag herausholen, zuerst die Behauptung "assert": "Request.Text == Response.Text", das bedeutet, dass sie den Request.Text mit dem Response.Text vergleicht und den Wert als booleschen Wert zurückgibt.

Aber wenn wir die Funktion await CSharpScript.EvaluateAsync<bool>(entry.Assert, globals: globals) aufrufen, übergeben wir zwei Parameter:

  • string auszuwertende Zeichenfolge -> "Request.Text == Response.Text"
  • globals Daten für den Bewerter -> in diesem Fall müssen wir einen Request und einen Response angeben, die Anfrage ist unsere erwartete Antwort und die Antwort ist die erhaltene Antwort.

Während wir die Daten in den Evaluator füllen, können wir jetzt die Zeichenfolge verwenden und auswerten, sodass true oder false zurückgegeben wird.

Fertig

Wir sind fertig, hier sehen Sie das fertige TestMethod

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

Diagramm

Hier ist ein Diagramm des gesamten Ablaufs, dem wir gefolgt sind, um an diesen Punkt zu gelangen. Wenn Sie etwas nicht verstanden haben, wird es hoffentlich geklärt.

https://gyazo.com/1e3b7c9c2286844062878b4b8ca02d2d

Und das ist alles, dies wird für einzelne Fälle durchgeführt, bei denen der Fall 1-zu-1 ist, der Benutzer einen activity sendet und der Bot einen weiteren einzelnen activity zurückgibt.

Ich hoffe, es hat Ihnen gefallen. Als nächstes werden die Testablauffälle mit mehr als einer Antwort behandelt.

https://gyazo.com/d964cfac395ed438a5282e60614863e7

Denken Sie daran, dass der gesamte Code in meinem Github in diesem-Repository gespeichert ist.