<progress id="jnld5"><th id="jnld5"></th></progress>

        <pre id="jnld5"></pre>

        <strike id="jnld5"><noframes id="jnld5"><pre id="jnld5"></pre>
        <strike id="jnld5"></strike>

        <strike id="jnld5"><span id="jnld5"><pre id="jnld5"></pre></span></strike>

        <font id="jnld5"><track id="jnld5"></track></font>

        前端自動化測試漫長路之——Selenium初探

        發表于:2017-12-18來源:cnblogs作者:Young Dreamer點擊數: 標簽:
        最近想解決前端開發或測試中的兩個問題:一是界面UI的布局適配,能否在測試的過程中,通過命令操作真機打開相應頁面然后截屏,通過對圖片識別分類,發現有問題的圖片,然后及時

        引言

        最近想解決前端開發測試中的兩個問題:一是界面UI的布局適配,能否在測試的過程中,通過命令操作真機打開相應頁面然后截屏,通過對圖片識別分類,發現有問題的圖片,然后及時修復;二是頁面性能分析,很多時候頁面只能在指定的Webview中使用,能否直接通過命令打開指定的頁面,分析頁面在真實APP中的性能,并生成報告。這兩個問題的前提就是通過命令直接操作手機App,帶著問題找線索,于是我就結識了Selenium,下面將結合實例和大家分享一下。

        Selenium是什么?

        先看一下官網的解釋:

        Selenium automates browsers. That's it! What you do with that power is entirely up to you. Primarily, it is for automating web applications for testing purposes, but is certainly not limited to just that. Boring web-based administration tasks can (and should!) be automated as well.
        Selenium has the support of some of the largest browser vendors who have taken (or are taking) steps to make Selenium a native part of their browser. It is also the core technology in countless other browser automation tools, APIs and frameworks.

        從上面的話我們可以知道3個點:

        1. 利用Selenium可以自動化操作瀏覽器,來實現web程序的自動化測試;
        2. Selenium是一個綜合性的項目,提供了提供了不同語言版本的類庫和工具,來支持瀏覽器的自動化;
        3. 主流瀏覽器基于W3C規定的的Web Driver規范,提供了相應的Web Driver,而標準的主要技術支持來源于Selenium項目。

        一圖勝千言,Selenium在自動化測試中扮演的角色如下圖所示:

        Selenium如何用?

        我們的訴求是通過腳本控制本地和手機上的瀏覽器,甚至APP中的Webview,Selenuim正好提供了WebDriver API供我們使用。從上面可以知道Selenium支持多種語言,如python、go、javascript等,對于前端而言,首選當然是javascript。以下是相關的操作步驟:

        環境準備

        該環節主要是兩步:

        1. 在項目中下載selenium-webdriver

          npm install selenium-webdriver --save
        2. 下載瀏覽器提供的WebDriver,并將該命令文件放置在系統變量PATH下
          我使用的是chrome的WebDriver,針對不同的chrome版本,需要下載不同版本的WebDriver,否則程序會報錯。網上有好心人已經整理出了chrome的WebDriver與chrome的版本映射表,可以點擊查看。

        代碼編寫

        selenium-webdriver的說明文檔相當的贊,在selenium-webdriver包的目錄下有幾個文件:chrome.js、edge.js、ie.js、phantom.js等,這些都是selenium-webdriver針對不同的瀏覽器的webdriver的調用做了封裝,打開chrome.js,在文件的開頭有詳細的文檔說明。
        chrome.js中提到了3種使用場景:分別是Headless Chrome、Customizing the ChromeDriver Server、Working with Android。而我需要的場景就是Working with Android。
        實例代碼如下:

        let chrome = require('selenium-webdriver/chrome');
        let {Builder} = require('selenium-webdriver');
        let driver = new Builder()
                  .forBrowser('chrome')
                  .setChromeOptions(new chrome.Options()
                      .androidPackage('com.example')
                      .androidActivity('com.example.Activity'))
                  .build();

        其中需要要點就是指定要操作的瀏覽器類型、APP包的名字、android程序的Activity名字。一般webview的內核都是基于webkit的,指定瀏覽器類型為chrome即可,APP的包名和Activity名字可以通過命令工具aapt獲取,關于aapt的詳細介紹可以參考這篇博客。
        通過以上兩步,就可以通過node執行相應的js文件,實現通過命令來控制APP了,這里是幾個我測試的demo,供大家下載。

        selenium-webdriver運行原理

        上面的操作涉及到了兩個核心,即瀏覽器提供的webdriver和瀏覽器(chrome/chromium)。selenium-webdriver的作用就是利用webdriver將瀏覽器啟動起來,并實現一系列自動操作。但究竟webdriver和瀏覽器是怎樣一個協同關系呢,從chrome.js文件的注釋中可以找到一些線索。

        By default, every Chrome session will use a single driver service, which is started the first time a Driver instance is created and terminated when this process exits. The default service will inherit its environment from the current process and direct all output to /dev/null. You may obtain a handle to this default service using getDefaultService getDefaultService() and change its configuration with setDefaultService setDefaultService().

        從上面可以知道,selenium-webdriver先通過webdriver啟動了一個driver service,該service又啟動chrome,分別起在不同的端口。
        通過查閱資料,可以知道driver service在開啟chrome的同時,為chrome安裝了一個Chrome Automation Extension擴展程序,該擴展程序的描述是:Exposes extension APIs for automating Chrome,通過查看其源碼,可以看到launchApp、getWindowInfo等函數,主要是提供了一些操作chrome的相關方法。
        一圖勝千言,selenium-webdriver的工作原理如下圖所示,該圖來源于網絡

        Tips:
        上面知道了driver service與chrome之間的關系,知道默認情況下driver service的生命周期和測試的Chrome session是同步的,意味著每次測試都需要開啟一個driver service,如果頻繁的開啟和關閉service,勢必會造成資源浪費。
        針對這個情況,官方的描述是這樣的:

        The ChromeDriver class starts the ChromeDriver server process at creation and terminates it when quit is called. This can waste a significant amount of time for large test suites where a ChromeDriver instance is created per test.

        官方針對該情況提出了兩個解決辦法:

        1. Start the ChromeDriver server separately before running your tests, and connect to it using the Remote WebDriver.
          即測試之前先單獨啟動driver server,然后使用Remote WebDriver連接上driver server所在的端口。官方提供了一個python的示例:

          import time
          from selenium import webdriver
          import selenium.webdriver.chrome.service as service
          service = service.Service('/path/to/chromedriver')
          service.start()
          capabilities = {'chrome.binary': '/path/to/custom/chrome'}
          driver = webdriver.Remote(service.service_url, capabilities)
          driver.get('http://www.google.com/xhtml');
          time.sleep(5) # Let the user actually see something!
          driver.quit()
        2. Use the ChromeDriverService. This is available for most languages and allows you to start/stop the ChromeDriver server yourself.
          可自己創建一個driver,同時為這個driver指定相應的service。這樣不僅可以為driver提供個性化的服務(如log日志),還可以控制service的生命周期。
          代碼如下:

          let chrome = require('selenium-webdriver/chrome');
          let service = new chrome.ServiceBuilder()
          .loggingTo('/my/log/file.txt')
          .enableVerboseLogging()
          .build();
          let options = new chrome.Options();
          // configure browser options ...
           let driver = chrome.Driver.createSession(options, service);

        小結

        前端自動化測試的道路是漫長的,對selenium的挖掘才剛剛開始。本文并沒有解決引言中提到的兩個問題,selenium-webdriver只是解決了第一步,即通過命令行來操作app,后面將繼續學習,繼續總結分享。

        原文轉自:http://www.cnblogs.com/wmhuang/p/8011815.html

        欧美日韩亚洲中文字幕|欧美变态另类z0z0禽交|久久国产精品-国产精|久久激情四射婷婷五月天

        <progress id="jnld5"><th id="jnld5"></th></progress>

              <pre id="jnld5"></pre>

              <strike id="jnld5"><noframes id="jnld5"><pre id="jnld5"></pre>
              <strike id="jnld5"></strike>

              <strike id="jnld5"><span id="jnld5"><pre id="jnld5"></pre></span></strike>

              <font id="jnld5"><track id="jnld5"></track></font>