اختبار التكامل باستخدام Bot Framework وDirectLine (3)
هذا هو الجزء الأحدث من الدليل، في هذا الجزء، سنقوم بتقييم النص من التأكيد في ملف json.
الآن بعد أن استخدمنا request وأرسلنا كـ activity إلى الروبوت، حصلنا على response وعلينا مقارنة ما assert في json (الاستجابة التي قمنا بتخزينها في json، هذه هي الاستجابة المتوقعة) مع الاستجابة التي حصلنا عليها من الروبوت.
لن يغطي الشرح التالي جميع المعلومات الأساسية حول كيفية عمل Bot Framework، إذا لم تكن تفهم ذلك، فيرجى الانتقال والتحقق من الوثائق الرسمية.
إضافة Microsoft.CodeAnalogy إلى الحل
أولاً، يتعين علينا تضمين CodeAnalogy كحزمة NuGet.
بعد التثبيت، تذكر إضافة الحزمة إلى ملف .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;
}
رسم بياني
فيما يلي رسم تخطيطي لكل التدفق الذي اتبعناه للوصول إلى هذه النقطة، ونأمل أن يوضح الأمر إذا لم تفهم شيئًا ما.
وهذا كل شيء، ويتم ذلك للحالات الفردية حيث تكون الحالة من 1 إلى 1، ويرسل المستخدم activity ويعيد الروبوت أغنية واحدة أخرى activity.
أتمنى أن تنال إعجابك، التالي سيكون حالات تدفق الاختبار مع أكثر من استجابة.
!https://gyazo.com/d964cfac395ed438a5282e60614863e7](https://gyazo.com/d964cfac395ed438a5282e60614863e7)
تذكر أنه تم تخزين كافة التعليمات البرمجية في جيثب الخاص بي في مستودع هذا.

