• 12
  • 12
分享

  Selenium是当前最流行的Web UI自动化测试框架,熟悉Selenium的人也知道,Selenium是基于WebDriver。那么能不能不用Selenium,直接调用WebDriver来实现Web UI自动化呢?答案当然是可以的,本文就带你来实现基于WebDriver的Web U自动化。本文通过调用Selenium、Curl命令、直接调用ChromeDriver三种方式,实现了同样的功能。编程语言为C#,已在Visual Studio 2019测试通过,其他主流编程语言也可以完成同样功能。对比三种实现方式,大家就可以容易的理解如何不用Selenium而直接调用WebDriver完成Web U自动化。阅读以下内容前,需要有Selenium和WebDriver相关基础知识。

  手动步骤

  1.打开Chrome浏览器

  2.进入https://www.baidu.com/主页

  3.搜索框输入“Selenium”

  4.点击“百度一下”

  5.关闭Chrome浏览器

  调用Selenium的C#代码

using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace HelloSelenium
{
    class Program
    {
        static void Main(string[] args)
        {
            IWebDriver driver = null;
            try
            {
                //1.  打开Chrome浏览器
                driver = new ChromeDriver();
                //2.  进入https://www.baidu.com/主页
                driver.Navigate().GoToUrl("https://www.baidu.com/");
                //3.    搜索框输入“Selenium”
                driver.FindElement(By.Id("kw")).SendKeys("Selenium");
                //4.  点击“百度一下”
                driver.FindElement(By.Id("su")).Click();
            }
            finally
            {
                //5.  关闭Chrome浏览器
                if (driver != null)
                {
                    driver.Dispose();
                }
            }
        }
}
}

  Curl命令

  1.打开Chrome浏览器

  启动命令提示符,执行chromedriver.exe --port=9515 (注意选用与Chrome版本对应的chromedriver版本,端口只要未被占用即可)。

1-1.png


  另起一个命令提示符,执行curl命令(注意端口号),记住返回的sessionId。

curl  -d @JsonFile1.json http://localhost:9515/session

  JsonFile1.json内容:

  {
    "desiredCapabilities": {
      "caps": {
        "nativeEvents": false,
        "browserName": "chrome",
        "version": "",
        "platform": "ANY"
      }
    }
  }


1-2.png

  2.进入https://www.baidu.com/主页

curl -d @JsonFile2.json http://localhost:9515/session/36d903cbd2177c278b5d39bbe74a3318/url

  JsonFile2.json内容:

  {"url":"https://www.baidu.com/"}

  3.搜索框输入“Selenium”

  获取elementId:

curl -d @JsonFile3.json http://localhost:9515/session/36d903cbd2177c278b5d39bbe74a3318/element

  JsonFile3.json内容:

{"using":"css selector","value":"#kw"}


1-3.png

  输入“Selenium”:

curl -d @JsonFile4.json http://localhost:9515/session/36d903cbd2177c278b5d39bbe74a3318/element/0.7861531328870939-1/value

  JsonFile4.json内容:

{"value":["Selenium"]}


  4.点击“百度一下”

  获取elementId:

curl -d @JsonFile5.json http://localhost:9515/session/36d903cbd2177c278b5d39bbe74a3318/element

  JsonFile5.json内容:

  {"using":"css selector","value":"#su"}


  点击:

curl -d @JsonFile4.json curl -d @JsonFile6.json http://localhost:9515/session/36d903cbd2177c278b5d39bbe74a3318/element/0.7861531328870939-2/click

  JsonFile6.json内容:

  {}

  5.关闭Chrome浏览器

  关闭Chrome:

关闭Chrome
curl -X DELETE http://localhost:9515/session/36d903cbd2177c278b5d39bbe74a3318

  关闭chromedriver.exe:

curl http://localhost:9515/shutdown

  调用ChromeDriver的C#代码

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace HelloSelenium
{
    class Program
    {
        static IList<HttpCmd> cmdArr;
        static readonly string baseUrl = "http://localhost:9515/";
        static readonly string extendUrlFormat1 = "session";
        static readonly string extendUrlFormat2 = "session/{sessionId}/url";
        static readonly string extendUrlFormat3 = "session/{sessionId}/element";
        static readonly string extendUrlFormat4 = "session/{sessionId}/element/{elementId}/value";
        static readonly string extendUrlFormat5 = "session/{sessionId}/element";
        static readonly string extendUrlFormat6 = "session/{sessionId}/element/{elementId}/click";
        static readonly string extendUrlFormat7 = "session/{sessionId}";
        static readonly string extendUrlFormat8 = "shutdown";
        static readonly string jsonData1 = @"{""desiredCapabilities"": { ""caps"": {""nativeEvents"": false, ""browserName"": ""chrome"", ""version"": """",""platform"": ""ANY""}}}";
        static readonly string jsonData2 = @"{""url"":""https://www.baidu.com/""}";
        static readonly string jsonData3 = @"{""using"":""css selector"",""value"":""#kw""}";
        static readonly string jsonData4 = @"{""value"":[""Selenium""]}";
        static readonly string jsonData5 = @"{""using"":""css selector"",""value"":""#su""}";
        static readonly string jsonData6 = @"{}";
        static Dictionary<string, string> dicSe = new Dictionary<string, string>()
            {{"{sessionId}", null}};
        static Dictionary<string, string> dicSeEl = new Dictionary<string, string>()
            {{"{sessionId}", null},{"{elementId}", null}};
        static Program()
        {
            cmdArr = new List<HttpCmd>()
            {
                new HttpCmd(null, null, null, null),
                new HttpCmd("POST", extendUrlFormat1, jsonData1, null),
                new HttpCmd("POST", extendUrlFormat2, jsonData2, dicSe),
                new HttpCmd("POST", extendUrlFormat3, jsonData3, dicSe),
                new HttpCmd("POST", extendUrlFormat4, jsonData4, dicSeEl),
                new HttpCmd("POST", extendUrlFormat5, jsonData5, dicSe),
                new HttpCmd("POST", extendUrlFormat6, jsonData6, dicSeEl),
                new HttpCmd("DELETE", extendUrlFormat7, null, dicSe),
                new HttpCmd("GET", extendUrlFormat8, null, null),
            };
        }
        
        static void Main(string[] args)
        {
            Process p = null;
            try
            {
                string response = null, sessionId = null, elementId = null, extendUrl;
                JObject jObj = null;
                //1.  打开Chrome浏览器
                //启动chromedriver.exe
                p = Process.Start(@"D:\Software\chromedriver.exe", "--port=9515");
                Thread.Sleep(1000);
                //启动chrome
                response = HttpOp(cmdArr[1]);
                jObj = JsonConvert.DeserializeObject(response) as JObject;
                sessionId = jObj["sessionId"].Value<string>();
                dicSe["{sessionId}"] = sessionId;
                dicSeEl["{sessionId}"] = sessionId;
                Thread.Sleep(1000);
                //2.  进入https://www.baidu.com/主页
                HttpOp(cmdArr[2]);
                Thread.Sleep(1000);
                //3.    搜索框输入“Selenium”
                //获取elementId
                response = HttpOp(cmdArr[3]);
                jObj = JsonConvert.DeserializeObject(response) as JObject;
                elementId = jObj["value"]["ELEMENT"].Value<string>();
                dicSeEl["{elementId}"] = elementId;
                //输入“Selenium”
                HttpOp(cmdArr[4]);
                Thread.Sleep(1000);
                //4.  点击“百度一下”
                //获取elementId
                response = HttpOp(cmdArr[5]);
                jObj = JsonConvert.DeserializeObject(response) as JObject;
                elementId = jObj["value"]["ELEMENT"].Value<string>();
                dicSeEl["{elementId}"] = elementId;
                //点击
                HttpOp(cmdArr[6]);
                Thread.Sleep(1000);
                //5.  关闭Chrome浏览器
                //关闭Chrome
                HttpOp(cmdArr[7]);
                //关闭chromedriver
                HttpOp(cmdArr[8]);
            }
            finally
            {
                if (p != null)
                {
                    p.WaitForExit(3000);
                    p.Dispose();
                }
            }
        }
        private static string HttpOp(HttpCmd cmd)
        {
            var fullUrl = baseUrl + cmd.ExtendUrl;
            HttpClient client = new HttpClient();
            Task<HttpResponseMessage> response = null;
            switch (cmd.Method)
            {
                case "GET":
                    response = client.GetAsync(fullUrl);
                    break;
                case "DELETE":
                    response = client.DeleteAsync(fullUrl);
                    break;
                case "POST":
                    HttpContent content = new StringContent(cmd.JsonData, Encoding.UTF8, "application/json");
                    response = client.PostAsync(fullUrl, content);
                    break;
            }
            return response.Result.Content.ReadAsStringAsync().Result;
        }
        internal class HttpCmd
        {
            public string Method { get; set; }
            public string ExtendUrlFormat { get; set; }
            public string JsonData { get; set; }
            public Dictionary<string, string> ParaDictionary { get; set; }
            public string ExtendUrl => BuildExtendUrl();
            public HttpCmd(string method, string extendUrlFormat, string jsonData, Dictionary<string, string> paraDictionary)
            {
                this.Method = method;
                this.ExtendUrlFormat = extendUrlFormat;
                this.JsonData = jsonData;
                this.ParaDictionary = paraDictionary;
            }
            private string BuildExtendUrl()
            {
                var extendUrl = ExtendUrlFormat;
                if (ParaDictionary != null && ParaDictionary.Count > 0)
                {
                    foreach (var pair in ParaDictionary)
                    {
                        extendUrl = extendUrl.Replace(pair.Key, pair.Value);
                    }
                }
                return extendUrl;
            }
        }
    }
}

  总结

  Curl命令就是Http调用WebDriver命令。

  调用ChromeDriver的代码也是Http调用WebDriver命令。

  调用Selenium的代码实际上还是Http调用WebDriver命令。只不过不是直接调用,而是通过Selenium去执行WebDriver命令。Selenium封装了WebDriver。至于Selenium具体是怎么封装WebDriver的,内容较多,本文不做这部分的分析。

  使用直接Http调用WebDriver命令的方式来做Web UI自动化,写代码很麻烦,实用价值很低。本文并不鼓励大家在实际工作中使用这样的方式来做自动化。但是,如果你在工作中经常用到Selenium,想具体了解Selenium的原理,成为高手,学习这种方式是必要的。这种方式非常有助于深入学习和理解Selenium,是Selenium高手所必备的知识和技能。



作者:Paladin王   

来源:http://www.51testing.com/html/94/n-4480494.html

  • 【留下美好印记】
    赞赏支持
登录 后发表评论
+ 关注

热门文章

    最新讲堂

      • 推荐阅读
      • 换一换
          • 前言开发人员与测试人员齐心协力,相爱相杀, 荣辱与共,方能打造出优秀的产品。若是bug描述不知所云,bug修复仓促随意,bug管理如同儿戏,则金玉其外已是造化,败絮其中当属必然。bug描述好的描述能降低沟通成本,让人审题时如沐春风,解题时酣畅淋漓。bug描述的主体,应该包含如下部分:标题:指明所测模块,简明扼要地描述问题现象[前提条件] 说明完成测试的预设条件是什么[重现步骤] 句子简练,步骤清晰,表达无歧义[实际结果] 按照步骤执行下来,实际结果是什么;不要有主观色彩[期望结果] 正确的结果应该是什么;应该有说服力,不要唯经验论Tips:其他如所测版本,附件信息,bug优先级等,不一而足,也...
            0 0 1384
            分享
          • 在上一个模块,我们从方法论层面讲了测试用例设计的方法,这一讲我们将会从实战的角度来讲,设计一个「好用例」的过程和方法。本模块的第一节,我们来看拿到需求后,如何开始着手用例设计。熟悉需求细节设计用例的根本,是对需求的了解和把握。只有清楚的理解了需求中的每一个细节,才能够让自己的用例足够得好。有些同学拿到需求后,还没有通读需求全文,就开始设计起用例了。在我看来,这样做是不可取的。要熟悉需求,我们建议要做到以下几点:充分阅读,透彻理解。拿到一个需求后,我建议大家先对需求文档做充分的阅读,通过至少三遍的阅读,来对需求有一个充分而透彻的理解,这里不仅包括对需求中细节的理解,还包括需求背景和目的的理解。只...
            0 0 76
            分享
          •   之前小编有和大家讲到测试思维,今天来讲一下思维的直接体现是什么——测试用例。  测试用例包括的元素:功能/模块,测试标题,前置条件,优先级,测试步骤,预期结果。这些是用例中必须有的字段,除了测试标题,其他都很好写的。下面重点讲解测试标题。测试标题也叫测试点,测试是分析设计的结果。  分析是分析需求,分系统,分析业务,甚至分行业。这样才能知道测试对象是什么行业的什么系统,有什么功能,哪些是核心,哪些是非核心。  设计是设计测试数据用来执行的。这个数据不用十分具体,也包括不同的测试条件和场景。  测试点形成方法有:等价类,边界值,流程图,场景法,因果图,错误推测法。这几个是基础,也是非常常用的...
            0 0 985
            分享
          •   应用场景:设想要集中测试一个Web服务器的性能表现, 我们用一台机器模拟上千个用户不断地访问被测试的服务器,可能会遇到一些瓶颈,模拟的用户不够,服务器设置了安全措施、拒绝接收(当有超量的数据来自同一台机器在短时间内,服务器就会认为这是外来的攻击行为),测试机的配置过低、不能完成上千个用户的请求。  解决方案:利用JMeter的分布式测试配置,就可以很轻松的解决上述问题。如下图所示,我们选择一台主机(Master),然后配置一些节点服务器(Slaves),主机发送测试运行指令,节点服务器在同一时间模拟用户对终端服器发送请求。这样总模拟的用户数量 = 单个节点用户数 * 节点服务器个数  学习...
            5 4 5255
            分享
          • 国内的大多数互联网公司只注重软件功能,却往往忽略了极为重要的软件质量,在一个月以前,我认为遵循了代码规范(阿里规约、sonar)的软件系统已经算是一个质量比较好的软件系统了,但是在我了解单元测试以后,才发现自己以前的想法有多么愚蠢,单元测试的作用远比我想象的要重要许多。经过一段时间的研究,总算对单元测试有了一个大概的了解,然而网上的文章零零散散,大多是讲解一些比较简单的demo,参考价值比较有限,因此我决定写一篇关于单元测试的文章来总结自己这段时间的收获与心得。背景软件系统刚开发完成时几乎不会出现Bug。为什么呢?因为刚开发第一版软件系统时,需求并不复杂,场景也不是很多,因此实现起来比较简单,...
            0 0 2120
            分享
      • 51testing软件测试圈微信