Интеграционный тест с использованием Bot Framework и DirectLine (3)
Это последняя часть руководства, в этой части мы будем оценивать текст из утверждения в json.
Теперь, когда мы использовали request и отправили боту как activity, мы получили response и нам нужно сравнить то, что assert в json (ответ, который мы сохранили в json, это ожидаемый ответ) с ответом, который мы получили от бота.
Следующее объяснение не охватывает всю основную информацию о том, как работает Bot Framework. Если вы не понимаете, пожалуйста, просмотрите официальную документацию.
Добавление Microsoft.CodeAnaанализ в решение
Прежде всего, нам нужно включить CodeAnalysis как пакет NuGet.
[
После установки не забудьте добавить пакет в файл .cs.
[[[ТОК_7]]]
Создание объекта Globals
Чтобы оценить, мы должны передать параметры оценщику. Этому оценщику нужен файл конфигурации.
[[[ТОК_9]]]
Эта часть очень важна: в этот файл конфигурации мы будем включать объекты, которые будем сравнивать, поэтому нам нужно передать ему ожидаемый ответ и полученный ответ.
Имея эту информацию, он будет использовать assert в файле json и оценивать то, что он говорит.
[[[ТОК_11]]]
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) мы передаем 2 параметра:
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.
Надеюсь, вам понравилось. следующим будут сценарии тестирования с более чем одним ответом.
Помните, что весь код хранится у меня на github в репозитории this.

