使用Bot Framework和DirectLine集成测试(3)

· 3 分钟阅读

这是指南的最新部分,在这部分中,我们将评估 json 中断言中的文本。

现在我们使用了 request 并作为 activity 发送给机器人,我们得到了 response,我们必须将 json 中的 assert(我们存储在 json 中的响应,这是预期响应)与我们从机器人获得的响应进行比较。

以下解释不会涵盖Bot Framework如何工作的所有基本信息,如果您不明白,请去查看官方文档。

将 Microsoft.CodeAnalysis 添加到解决方案中

首先,我们必须将 CodeAnalysis 作为 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;
}

这部分非常重要,在该配置文件中,我们将包含要比较的对象,因此对于我们来说,我们需要向其传递 预期响应收到的响应

有了这些信息,它将使用 json 文件中的 assert 并评估其中的内容。

/// 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.TextResponse.Text,并以布尔值形式返回值。

但是当我们调用函数 await CSharpScript.EvaluateAsync<bool>(entry.Assert, globals: globals) 时,我们传递 2 个参数:

  • string 要评估的字符串 -> "Request.Text == Response.Text"
  • 评估者的 globals 数据 -> 在这种情况下,我们必须给出 RequestResponse,请求是我们的 预期响应,响应是 收到的响应

当我们在求值器中填充数据时,现在我们可以使用字符串并求值,因此它将返回 truefalse

完成

我们完成了,在这里你可以看到完成的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

请记住,所有代码都存储在我的 github 中的 this 存储库中。