• 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

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

热门文章

    最新讲堂

      • 推荐阅读
      • 换一换
          • 读者提问:『阿常你好,想请教一下,回归测试如何确定测试范围,如何避免遗漏 ?』阿常回答:三种方式,可以结合起来使用。1、产品 & 开发 助力产品提供需求覆盖的范围,开发指出代码修改涉及的模块。2、测试根据经验分析如果开发修改的是模块A,回归测试时就覆盖模块A,根据测试经验判断模块 B 关联了模块A,回归测试时就覆盖模块A和模块B。3、用例关联矩阵分析用例中标识与之关联的其他用例,回归测试时,此用例回归,与之关联的其他用例也回归;建立代码块和用例对应的矩阵,回归测试时,根据修改的代码块,找到对应的回归用例。阿常碎碎念:以上,12应该是企业中常见做法,3落地有些难度。看完今天的分...
            0 0 1160
            分享
          •   Airtest简介  AirtestIDE是一款适用于游戏和应用程序的跨平台UI测试自动化集成开发环境(IDE),为移动应用程序开发人员和测试人员提供了广泛的工具,可在便利且易于使用的环境中编写全自动测试脚本。  相比较其他传统的自动化测试工具(如Appium,RF等),AirtestIDE主要具有两大优势:  1.基于图像识别的Airtest框架  Airtest是一个基于图片识别的跨平台的自动化测试框架,同时它最强大的地方在于它几乎兼容所有Android移动应用程序和Windows游戏等。  2.基于UI识别的Poco框架  Poco是一个跨引擎UI自动化框架,并且提供了独立于引擎的强...
            13 14 1971
            分享
          •   这段时间在自己搭建公司的测试平台框架,基本已经成型,可以满足编写接口、接口自动化、接口性能、数据展示等功能,回过头来看可以使用的工具,发现还是尽量保持“工具引用,不依赖工具”的思想,这里做一个总结。  1、首先只会独立使用工具,会带来很大的局限性  比如,我们会使用jmeter来写几个接口,会用postman来做接口,还有其它的工具,那么,我认为这只能局限在你的接口测试的最基础层面。通过阅读工具的文档,谁都可以通过UI页面的操作,搭建接口测试,然后执行,产生报告。但是遇到稍微复杂点的接口,你就无从下手了。我举个例子,我在测试微信小程序的时候,微信会根据每次登录产生一个不同的code,一但c...
            0 0 1322
            分享
          •   任天堂于一周前以“助长盗版肆虐”为由起诉 Tropic Haze 公司,也就是任天堂 Switch 模拟器 Yuzu 的开发商。  该公司面对“最强法务部”的施压最终选择了“投降”,不仅同意向任天堂支付 240 万美元(IT之家备注:当前约 1730.4 万元人民币),还同意交出域名等。  Tropic Haze 公司表示将永久停止开发、托管、分发 Yuzu 的代码或功能、不再通过网站或者社交媒体等渠道托管推广 Yuzu、后续也不会展开和从事任何其他规避任天堂版权保护的行为。  Tropic Haze 公司还将向任天堂交出 yuzu-emu.org 域名,不仅同意删除 Yuzu 下载链接,...
            0 0 292
            分享
          • 一、python 使用flask框架之get接口开发1、在pycharm中,安装flask 2、引入Flask模块,Flask模块实现了一个WSGI应用from flask import Flask,request import json3、app是Flask的实例,它接收包或者模块的名字作为参数,但一般都是传递(name)。让flask.helpers.get_root_path函数通过传入这个名字确定程序的根目录,以便获得静态文件和模板文件的目录。app = Flask(__name__)4、开启调试模式app...
            0 0 1454
            分享
      • 51testing软件测试圈微信