Chat Bot(聊天机器人)自动化测试脚本来解决人工测试的问题

问题描述:有一个Oliver Cafe Shop聊天机器人,如何实现自动化脚本自动测试这个聊天机器人的功能。

实现效果:通过代码来实现客户端发送请求来代替Bot Framework Emulator输入Tea,然后客户端监听和接收服务器端(Bot)发来的回复(图片中选择drinksubtype的卡片),最后根据服务器端(Bot)的回复再次发送请求(红茶)或者进行别的操作。

Chat Bot(聊天机器人)自动化测试脚本来解决人工测试的问题_第1张图片

1.首先建立一个工程TestWebRequest,作为代替模拟器发送请求,具体实现函数代码如下,其中WriteLog在以前的博客中:这里

//Post请求的json格式的content的路径
public List orderDrinkAllJsonPathList = new List { "../../../Json/Order.json" };
public void OrderDrink()
        {
            WriteLog("Order Drink Begin.");
            try
            {
                foreach (string jsonPath in orderDrinkAllJsonPathList)
                {
                    string content = File.ReadAllText(jsonPath);
                    string jsonPathName = jsonPath.Substring(jsonPath.LastIndexOf("/") + 1);
                    HttpResponseMessage response = OrderDrinkOneStep(content, jsonPathName).Result;
                    //HttpResponseMessage response = GetActivity(content, jsonPathName).Result;                    
                    if (response != null && response.IsSuccessStatusCode)
                    {
                        string responseContent = response.Content.ReadAsStringAsync().Result ?? "Empty";
                        WriteLog("Order Drink " + jsonPathName + " successful:" + responseContent);
                        //System.Threading.Thread.Sleep(3000 * timeCount * 3);
                        Console.WriteLine("Order Drink " + jsonPathName + " successful:" + responseContent);
                    }
                    else if (response != null)
                    {
                        WriteLog("Order Drink " + jsonPathName + " failed:" + "ReasonPhrase: " + response.ReasonPhrase);
                        Console.WriteLine("Order Drink " + jsonPathName + " failed:" + "ReasonPhrase: " + response.ReasonPhrase);
                        break;
                    }

                }
                WriteLog("Order Drink End.");
            }
            catch (Exception ex)
            {
                WriteLog("Order Drink " + " failed:" + "Exception: " + ex.Message);
            }
        }

具体的OrderDrink的每一个具体步骤只是request的content不一样,所以这样写进一个方法提高代码利用率

public async Task OrderDrinkOneStep(string content, string errorJsonPath)
        {            
            HttpResponseMessage response = null;
            //跳过证书认证,可以不用
            var httpClientHandler = new HttpClientHandler();
            httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, error) => { return true; };
            using (HttpClient client = new HttpClient(httpClientHandler))
            {
                try
                {                    
                    var requestObj = JsonConvert.DeserializeObject(content);
                    StringContent strContent = new StringContent(JsonConvert.SerializeObject(requestObj), Encoding.UTF8, "application/json");                    
                    var request = new HttpRequestMessage()
                    {
                        RequestUri = new Uri(requestUrl),
                        Method = HttpMethod.Post,
                        Content = strContent
                    };
                    //本地创建bot不需要app auth认证,详细的在后面介绍
                    //string token = GetMSAJWTToken("YourAppId", "YouAppPassword");
                    //string authorization = "Bearer " + token;
                    //request.Headers.Add("Authorization", authorization);                   
                    response = await client.SendAsync(request);
                                      
                }
                catch (Exception e)
                {
                    string logContent = "RestoreFileOneStep" + "errorJsonPath " + errorJsonPath + "errorMessage: " + e.Message;
                    WriteLog(logContent);
                }
            }
            return response;
        }

其中Order.json文件的内容如下,直接复制第一张图片里面的json文本即可,注意改一下serviceurl的端口号,后面会监听这个端口号(7777致敬一下clearlove哈哈哈哈哈哈)

{
  "channelData": {
    "clientActivityID": "15584188744740.9l71xdomgu6",
    "state": "sent"
  },
  "channelId": "emulator",
  "conversation": {
    "id": "C743EA22-CE36-4409-A38C-FD6FF99ECE1C|livechat"
  },
  "entities": [
    {
      "requiresBotState": true,
      "supportsListening": true,
      "supportsTts": true,
      "type": "ClientCapabilities"
    }
  ],
  "from": {
    "id": "c9a42e69-b5fe-48c4-b24e-efdc50e6af34",
    "name": "User",
    "role": "user"
  },
  "id": "c5c38b50-7b8e-11e9-bcd2-17e98060b0ce",
  "localTimestamp": "2019-05-21T14:07:54+08:00",
  "locale": "en-us",
  "recipient": {
    "id": "1",
    "name": "Bot",
    "role": "bot"
  },
  "serviceUrl": "http://localhost:7777",
  "showInInspector": true,
  "text": "Tea",
  "textFormat": "plain",
  "timestamp": "2019-05-21T06:07:54.501Z",
  "type": "message"
}

运行一下TestWebRequest,暂时把serviceUrl的端口号改回去,这样就会在模拟器上就会得到模拟器输入"Tea"相同的结果

Chat Bot(聊天机器人)自动化测试脚本来解决人工测试的问题_第2张图片

2.创建一个项目Client来代码模拟器来监听服务器端(Bot)的回复请求

/// 
        /// 应用程序的主入口点。
        /// 
        [STAThread]
       
        static void Main(string[] args)
        {            
            int recv;//用于表示客户端发送的信息长度                       
            string ipadd = "127.0.0.1";           
            int port = 7777;
            IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(ipadd), port);
            Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            newsock.Bind(ipep);//绑定
            newsock.Listen(30);//监听
            Console.WriteLine("waiting for a client");
            Socket client = newsock.Accept();//当有可用的客户端连接尝试时执行,并返回一个新的socket,用于与客户端之间的通信
            IPEndPoint clientip = (IPEndPoint)client.RemoteEndPoint;
            Console.WriteLine("connect with client:" + clientip.Address + " at port:" + clientip.Port);           
            try
            {                
                while (true)
                {//用死循环来不断的从客户端获取信息
                    var data = new byte[client.ReceiveBufferSize];
                    recv = client.Receive(data);
                    if (recv == 0)//当信息长度为0,说明客户端连接断开
                        break;
                    string requestBody = System.Text.Encoding.Default.GetString(data);
                    //得到服务器返回的内容,就可以继续进行后面的测试输入了
                    //requestBody = requestBody.Substring(requestBody.IndexOf("{"));
                    //Activity activity = JsonConvert.DeserializeObject(requestBody);
                    //TestBotRequest.WebRequest webRequest = new TestBotRequest.WebRequest();
                    //webRequest.CreatePostActivity(activity);                                       
                }
            }
            catch (Exception ex)
            {

                WriteLog(ex.Message);
            }
            Console.WriteLine("Disconnected from" + clientip.Address);
            client.Close();
            newsock.Close();
            Console.ReadKey();

        }

 3.启动bot,这里不用虚拟器打开bot,然后启动Client和TestWebRequest,就完成了一轮自动化脚本实现的对话了。这里VS创建的bot不需要app auth认证的,因为appid是空,其他部署到Azure需要认证的话需要在request的header加上token,token的具体获取方法如下,

public string GetMSAJWTToken(string clientId,string clientSecret)
        {            
            var authendpoint = "https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token";

            using (var client = new WebClient())
            {
                var values = new NameValueCollection();
                values["grant_type"] = "client_credentials";
                values["client_id"] = clientId;
                values["client_secret"] = clientSecret;
                values["scope"] = clientId + "/.default";

                var response = client.UploadValues(authendpoint, values);
                var responseString = Encoding.Default.GetString(response);
                var result = JsonConvert.DeserializeObject(responseString);
                return result.Access_Token;               
            }
        }

4.具体源代码:这里

Chat Bot(聊天机器人)自动化测试脚本来解决人工测试的问题_第3张图片

你可能感兴趣的:(Microsoft,Bot,Framework开发)