اختبار التكامل باستخدام Bot Framework وDirectLine (3)

· 4 دقيقة قراءة

هذا هو الجزء الأحدث من الدليل، في هذا الجزء، سنقوم بتقييم النص من التأكيد في ملف json.

الآن بعد أن استخدمنا request وأرسلنا كـ activity إلى الروبوت، حصلنا على response وعلينا مقارنة ما assert في json (الاستجابة التي قمنا بتخزينها في json، هذه هي الاستجابة المتوقعة) مع الاستجابة التي حصلنا عليها من الروبوت.

لن يغطي الشرح التالي جميع المعلومات الأساسية حول كيفية عمل Bot Framework، إذا لم تكن تفهم ذلك، فيرجى الانتقال والتحقق من الوثائق الرسمية.

إضافة Microsoft.CodeAnalogy إلى الحل

أولاً، يتعين علينا تضمين CodeAnalogy كحزمة NuGet.

https://gyazo.com/ce97a60ecab998f162f6ac7a2ab2c9a7

بعد التثبيت، تذكر إضافة الحزمة إلى ملف .cs.

using Microsoft.CodeAnalysis.CSharp.Scripting;

إنشاء كائن Globals

من أجل التقييم، علينا تمرير المعلمات إلى المقيم. يحتاج هذا المقيم إلى ملف التكوين.

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

هذا الجزء مهم جدًا، في ملف التكوين هذا، سنقوم بتضمين الكائنات التي سنقارنها، لذلك بالنسبة لنا، نحتاج إلى تمرير الاستجابة المتوقعة و الاستجابة المستلمة.

باستخدام هذه المعلومات، سيتم استخدام assert في ملف json وسيقوم بتقييم ما يقال.

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

** يقوم EvaluateAsync<T> بتقييم وإرجاع T، في حالتنا نمرر string للتقييم وglobals، الذي يحتوي على البيانات التي سيتم تقييمها.**

سأحاول شرح ذلك بمثال، باستخدام إدخال (يحتوي على اسم وطلب واستجابة وتأكيد).

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

دعنا نحصل على الأشياء المهمة من هذا الإدخال، أولاً التأكيد "assert": "Request.Text == Response.Text"، وهذا يعني أنه سيقارن Request.Text مع Response.Text، ويعيد القيمة كقيمة منطقية.

لكن عندما نستدعي الدالة await CSharpScript.EvaluateAsync<bool>(entry.Assert, globals: globals) فإننا نمرر معلمتين:

  • string السلسلة المطلوب تقييمها -> "Request.Text == Response.Text"
  • globals بيانات للمقيم -> في هذه الحالة يتعين علينا تقديم Request وResponse، الطلب هو ردنا المتوقع والرد هو الرد المستلم.

بما أننا نقوم بملء البيانات في المقيم، يمكننا الآن استخدام السلسلة وتقييمها، لذلك ستُرجع true أو false.

تم

لقد انتهينا، هنا يمكنك رؤية 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;
}

رسم بياني

فيما يلي رسم تخطيطي لكل التدفق الذي اتبعناه للوصول إلى هذه النقطة، ونأمل أن يوضح الأمر إذا لم تفهم شيئًا ما.

https://gyazo.com/1e3b7c9c2286844062878b4b8ca02d2d

وهذا كل شيء، ويتم ذلك للحالات الفردية حيث تكون الحالة من 1 إلى 1، ويرسل المستخدم activity ويعيد الروبوت أغنية واحدة أخرى activity.

أتمنى أن تنال إعجابك، التالي سيكون حالات تدفق الاختبار مع أكثر من استجابة.

!https://gyazo.com/d964cfac395ed438a5282e60614863e7](https://gyazo.com/d964cfac395ed438a5282e60614863e7)

تذكر أنه تم تخزين كافة التعليمات البرمجية في جيثب الخاص بي في مستودع هذا.