zoukankan      html  css  js  c++  java
  • UI自动化测试底层原理

      底层原理如下:

      1.在自动化测试过程中,存在三部分组件:客户端脚本+驱动+浏览器终端。

      2.驱动文件,以geckodriver.exe为例,这个可执行的驱动文件启动后,相当于一个暴露了一系列接口的服务器,监听某一端口,例如:89890。

      3.客户端的操作(访问页面,定位元素,输入数据,点击按钮等)都是封装成了接口请求(eg:/session/xx/yy),然后提交到驱动服务器。

      4.驱动服务器接收到客户端的请求后,再跟终端浏览器交互。

      5.终端浏览器做出相应操作。

        下图描述了整个交互过程:

      

      以定位元素为例,定位搜索框,我们来看底下这行代码在执行的时候底层到底经历了些什么:

    WebElement searchInputBox = driver.findElement(By.id("js_keyword"));

      

    实际,底层请求时,每个请求会被封装为一个command,然后根据不同的commannd封装得到不同的HttpRequest对象:

    根据此命令,得到接口地址:

    拿到此接口地址封装为一个HttpRequest请求。

    client.execute(httpRequest,true),执行接口调用:

      至于其他操作:往输入框输入数据,点击按钮等,都是对应一个接口地址,通过调用接口,请求驱动来处理,最后驱动同浏览器进行交互,浏览器按照指示做出对应操作。

      Selenium有一个类AbstractHttpCommandCodec,此类中维护了众多自动化操作对应的接口地址:

      

    复制代码
    public AbstractHttpCommandCodec() {
        defineCommand(STATUS, get("/status"));
    
        defineCommand(GET_ALL_SESSIONS, get("/sessions"));
        defineCommand(NEW_SESSION, post("/session"));
        defineCommand(GET_CAPABILITIES, get("/session/:sessionId"));
        defineCommand(QUIT, delete("/session/:sessionId"));
    
        defineCommand(GET_SESSION_LOGS, post("/logs"));
        defineCommand(GET_LOG, post("/session/:sessionId/log"));
        defineCommand(GET_AVAILABLE_LOG_TYPES, get("/session/:sessionId/log/types"));
    
        defineCommand(SWITCH_TO_FRAME, post("/session/:sessionId/frame"));
        defineCommand(SWITCH_TO_PARENT_FRAME, post("/session/:sessionId/frame/parent"));
    
        defineCommand(CLOSE, delete("/session/:sessionId/window"));
        defineCommand(SWITCH_TO_WINDOW, post("/session/:sessionId/window"));
    
        defineCommand(FULLSCREEN_CURRENT_WINDOW, post("/session/:sessionId/window/fullscreen"));
    
        defineCommand(GET_CURRENT_URL, get("/session/:sessionId/url"));
        defineCommand(GET, post("/session/:sessionId/url"));
        defineCommand(GO_BACK, post("/session/:sessionId/back"));
        defineCommand(GO_FORWARD, post("/session/:sessionId/forward"));
        defineCommand(REFRESH, post("/session/:sessionId/refresh"));
    
        defineCommand(SET_ALERT_CREDENTIALS, post("/session/:sessionId/alert/credentials"));
    
        defineCommand(UPLOAD_FILE, post("/session/:sessionId/file"));
        defineCommand(SCREENSHOT, get("/session/:sessionId/screenshot"));
        defineCommand(ELEMENT_SCREENSHOT, get("/session/:sessionId/screenshot/:id"));
        defineCommand(GET_TITLE, get("/session/:sessionId/title"));
    
        defineCommand(FIND_ELEMENT, post("/session/:sessionId/element"));
        defineCommand(FIND_ELEMENTS, post("/session/:sessionId/elements"));
        defineCommand(GET_ELEMENT_PROPERTY, get("/session/:sessionId/element/:id/property/:name"));
        defineCommand(CLICK_ELEMENT, post("/session/:sessionId/element/:id/click"));
        defineCommand(CLEAR_ELEMENT, post("/session/:sessionId/element/:id/clear"));
        defineCommand(
            GET_ELEMENT_VALUE_OF_CSS_PROPERTY,
            get("/session/:sessionId/element/:id/css/:propertyName"));
        defineCommand(FIND_CHILD_ELEMENT, post("/session/:sessionId/element/:id/element"));
        defineCommand(FIND_CHILD_ELEMENTS, post("/session/:sessionId/element/:id/elements"));
        defineCommand(IS_ELEMENT_ENABLED, get("/session/:sessionId/element/:id/enabled"));
        defineCommand(ELEMENT_EQUALS, get("/session/:sessionId/element/:id/equals/:other"));
        defineCommand(GET_ELEMENT_RECT, get("/session/:sessionId/element/:id/rect"));
        defineCommand(GET_ELEMENT_LOCATION, get("/session/:sessionId/element/:id/location"));
        defineCommand(GET_ELEMENT_TAG_NAME, get("/session/:sessionId/element/:id/name"));
        defineCommand(IS_ELEMENT_SELECTED, get("/session/:sessionId/element/:id/selected"));
        defineCommand(GET_ELEMENT_SIZE, get("/session/:sessionId/element/:id/size"));
        defineCommand(GET_ELEMENT_TEXT, get("/session/:sessionId/element/:id/text"));
        defineCommand(SEND_KEYS_TO_ELEMENT, post("/session/:sessionId/element/:id/value"));
    
        defineCommand(GET_ALL_COOKIES, get("/session/:sessionId/cookie"));
        defineCommand(GET_COOKIE, get("/session/:sessionId/cookie/:name"));
        defineCommand(ADD_COOKIE, post("/session/:sessionId/cookie"));
        defineCommand(DELETE_ALL_COOKIES, delete("/session/:sessionId/cookie"));
        defineCommand(DELETE_COOKIE, delete("/session/:sessionId/cookie/:name"));
    
        defineCommand(SET_TIMEOUT, post("/session/:sessionId/timeouts"));
        defineCommand(SET_SCRIPT_TIMEOUT, post("/session/:sessionId/timeouts/async_script"));
        defineCommand(IMPLICITLY_WAIT, post("/session/:sessionId/timeouts/implicit_wait"));
    
        defineCommand(GET_APP_CACHE_STATUS, get("/session/:sessionId/application_cache/status"));
        defineCommand(IS_BROWSER_ONLINE, get("/session/:sessionId/browser_connection"));
        defineCommand(SET_BROWSER_ONLINE, post("/session/:sessionId/browser_connection"));
        defineCommand(GET_LOCATION, get("/session/:sessionId/location"));
        defineCommand(SET_LOCATION, post("/session/:sessionId/location"));
    
        defineCommand(GET_SCREEN_ORIENTATION, get("/session/:sessionId/orientation"));
        defineCommand(SET_SCREEN_ORIENTATION, post("/session/:sessionId/orientation"));
        defineCommand(GET_SCREEN_ROTATION, get("/session/:sessionId/rotation"));
        defineCommand(SET_SCREEN_ROTATION, post("/session/:sessionId/rotation"));
    
        defineCommand(IME_GET_AVAILABLE_ENGINES, get("/session/:sessionId/ime/available_engines"));
        defineCommand(IME_GET_ACTIVE_ENGINE, get("/session/:sessionId/ime/active_engine"));
        defineCommand(IME_IS_ACTIVATED, get("/session/:sessionId/ime/activated"));
        defineCommand(IME_DEACTIVATE, post("/session/:sessionId/ime/deactivate"));
        defineCommand(IME_ACTIVATE_ENGINE, post("/session/:sessionId/ime/activate"));
    
        // Mobile Spec
        defineCommand(GET_NETWORK_CONNECTION, get("/session/:sessionId/network_connection"));
        defineCommand(SET_NETWORK_CONNECTION, post("/session/:sessionId/network_connection"));
        defineCommand(SWITCH_TO_CONTEXT, post("/session/:sessionId/context"));
        defineCommand(GET_CURRENT_CONTEXT_HANDLE, get("/session/:sessionId/context"));
        defineCommand(GET_CONTEXT_HANDLES, get("/session/:sessionId/contexts"));
      }
    复制代码

      另外,可能会有人好奇,驱动服务器是何时启动的服务。其实是在执行下面这行代码的时候启动的,大家可执行去debug调试selenium的底层代码:

      

    //创建火狐驱动对象
    WebDriver driver = new FirefoxDriver();

      当上面这行代码执行完,可以发现eclipse的控制台显示了如下信息:

    1531911173760    geckodriver    INFO    geckodriver 0.19.0
    1531911173772    geckodriver    INFO    Listening on 127.0.0.1:21984

      说明此驱动服务器成功启动了,并且监听了本机的21984端口,等待客户端发起请求,并处理。

    转载于:https://www.cnblogs.com/nickjiang/p/9332480.html#4033469

  • 相关阅读:
    改变this指向的三个函数call, apply, bind的实现
    vscode 前端常用插件推荐
    Java SPI详解
    数据技术分享
    深入SpringMVC视图解析器
    .gitignore文件失效的解决方案
    Spring的事件监听机制
    Spring MVC 配置类 WebMvcConfigurerAdapter
    一起来读Netty In Action之传输(三)
    Tomcat性能调优参数简介
  • 原文地址:https://www.cnblogs.com/bingoTest/p/10844481.html
Copyright © 2011-2022 走看看