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

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

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

عملي في المجموعة هو جعل الروبوت مستقرًا قدر الإمكان، ولكن أولاً، ما هو إطار عمل الروبوت؟

قم ببناء الروبوتات الذكية وتوصيلها ونشرها وإدارتها للتفاعل بشكل طبيعي مع المستخدمين لديك على موقع ويب وتطبيق وCortana وMicrosoft Teams وSkype وSlack وFacebook Messenger والمزيد. ابدأ بسرعة مع بيئة بناء الروبوتات الكاملة، كل ذلك مع الدفع مقابل ما تستخدمه فقط.

يمكنك العثور على مزيد من المعلومات حول Bot Framework مباشرة هنا.

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

لماذا أحتاج إلى اختبار التكامل؟

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

اختبار التكامل في الروبوتات؟

أعتقد أن اختبار التكامل مهم جدًا في الروبوتات. لا يمكن أن يكون لديك روبوت حيث لا تعمل بعض قوائمه، أو لا تقوم بعض الميزات بإرجاع أي شيء.

تستخدم الشركات الروبوتات لعملائها لأنها لا تريد أن ينشغل الناس بمشاكلهم، فإذا كان الروبوت قادرًا على مساعدة المستخدم، فسيتمكن العمال الآخرون من استخدام وقتهم للقيام بشيء أكثر أهمية.

نظرة عامة على الحل.

من أجل إنجاز هذا العمل، استخدمت مشروع اختبار في Visual Studio، والذي سيستخدم WebClient لـ API Rest وملف 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"
    }
  ]
}

كما ترون لدينا:

  • سر الخط المباشر -> سر من الروبوت المنشور
  • نقطة نهاية إنشاء الرمز المميز للخط المباشر -> نقطة النهاية للحصول على الرمز المميز باستخدام السر
  • نقطة نهاية محادثة الخط المباشر -> نقطة النهاية للعب بالمحادثة
  • الدخول -> حالة الاختبار
    • طلب -> ما نرسله إلى المحادثة
    • الاستجابة -> ما نتوقع الحصول عليه
    • أكد -> ما الذي نقارنه

إلغاء التسلسل

لدينا ملف json منسق بشكل مثالي، وعلينا الآن تحميله في الحل، لذلك سنستخدم JSON.NET وبعض الفئات. أولاً لدينا مجموعة الإدخالات، التي تحتوي على كل شيء، وبعد ذلك لدينا قائمة إدخالات لكل مجموعة.

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

وهذا هو الكائن الذي يحتوي على الاسم والطلب والاستجابة والتأكيد لحالة الاختبار.


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

التحليل من json إلى الكائن في حالة الاختبار

إن الحصول على فئات لكائن التحليل أمر سهل للغاية لأننا نحتاج إلى قراءته ككائن.

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

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

الآن مع هذه المجموعة، سنكون قادرين على تكرارها والحصول على المعلومات باستخدام، على سبيل المثال، foreach.

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

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