腳手架vue-cli系列五:基於Nightwatch的端到端測試環境

来源:https://www.cnblogs.com/yinn/archive/2018/09/30/9729258.html
-Advertisement-
Play Games

不同公司和組織之間的測試效率迥異。在這個富交互和響應式處理隨處可見的時代,很多組織都使用敏捷的方式來開發應用,因此測試自動化也成為軟體項目的必備部分。測試自動化意味著使用軟體工具來反覆運行項目中的測試,併為回歸測試提供反饋。 端到端測試又簡稱E2E(End-To-End test)測試,它不同於單元 ...


不同公司和組織之間的測試效率迥異。在這個富交互和響應式處理隨處可見的時代,很多組織都使用敏捷的方式來開發應用,因此測試自動化也成為軟體項目的必備部分。測試自動化意味著使用軟體工具來反覆運行項目中的測試,併為回歸測試提供反饋。

端到端測試又簡稱E2E(End-To-End test)測試,它不同於單元測試側重於檢驗函數的輸出結果,端到端測試將儘可能從用戶的視角,對真實系統的訪問行為進行模擬。對於Web應用來說,這意味著需要打開瀏覽器、載入頁面、運行JavaScript,以及進行與DOM交互等操作。簡言之,單元測試的功能只能確保單個組件的質量,無法測試具體的業務流程是否運作正常,而E2E卻正好與之相反,它是一個更高層次的面對組件與組件之間、用戶與真實環境之間的一種集成性測試 。

E2E測試的意義在於可以通過程式固化和模擬用戶操作,對於開發人員而言,基於E2E測試能極大地提高Web的開發效能,節約開發時間。

先來看看如果沒有E2E測試下的一次從開發到手工測試成功的過程:

這個過程還屬於簡化過的,還沒有包括在觀察結果時要打開瀏覽器的調試視窗觀看某些內部的運行變數或者網頁代碼結構。整個過程都是純人工操作,人工操作最大的問題是一個程式可能要調試好幾次,同樣的操作就要重覆數遍。即使有嚴格的規定,程式員們大多都還是隨便地做“通過”式操作,尤其在輸入樣本數據時,絕大多數的程式員幾乎都是亂輸,出現得最多的就是各種隨意的數字或者是“aaa”、“asd”、“aws”這樣毫無意義的字元。以這種方式開發出來的程式在驗收時產品經理或者客戶會經常說一句話:“我上次試過是沒有問題的!”這樣的失誤歸根結底不在程式員本身,因為這是一種人性!一個人如果重覆多次自己都覺得毫無意義的動作時,要不就逃避不做,如果不能逃避就會消極對待。

所以我們應該用更高效、更能彌補人性化缺陷和更有意義的辦法來處理,這就是E2E測試,先來看看如果使用E2E測試後的開發過程將會變成什麼:

從運行測試開始,所有的一切都是自動的!這就是最大的區別,還有更重要的一點是,當我們要寫出E2E測試時就需要對操作需求有深刻的理解,在這一過程中還有很大的機會對用戶的操作進行優化,從而提高用戶體驗。

 Nightwatch

vue-cli的webpack模板也為我們準備了一個當下很流行的E2E測試框架——Nightwatch。

Nightwatch是一套新近問世的基於Node.js的驗收測試框架,使用Selenium WebDriver API以將Web應用測試自動化。它提供了簡單的語法,支持使用JavaScript和CSS選擇器來編寫運行在Selenium伺服器上的端到端測試。

這個框架在配置好後的具體工作流程如下圖所示。

Nightwatch採用Fluent interface模式(https://en.wikipedia.org/wiki/Fluent_interface)來簡化端到端測試的編寫,語法非常簡潔易懂,正如以下代碼所示。

    this.demoTestGoogle = function (browser) {
      browser
        .url('http://www.google.com')
        

        .waitForElementVisible('body', 1000)
        .setValue('input[type=text]', 'nightwatch')
        .waitForElementVisible('button[name=btnG]', 1000)
        .click('button[name=btnG]')
        .pause(1000)
        .assert.containsText('#main', 'The Night Watch')
        .end();
    }

我們可以從Nightwatch網站找到當前提供特性的列表:

● 簡單但強大的語法。只需要使用JavaScript和CSS選擇器,開發者就能夠非常迅捷地撰寫測試。開發者也不必初始化其他對象和類,只需要編寫測試規範即可。

● 內建命令行測試運行器,允許開發者同時運行全部測試——分組或單個運行。

● 自動管理Selenium伺服器;如果Selenium運行在另一臺機器上,那麼也可以禁用此特性。

● 支持持續集成:內建JUnit XML報表,因此開發者可以在構建過程中,將自己的測試與系統(例如Hudson或Teamcity等)集成。

● 使用CSS選擇器或Xpath,定位並驗證頁面中的元素或是執行命令。

● 易於擴展,便於開發者根據需要,實現與自己應用相關的命令。

配置 Nightwatch

要瞭解Nightwatch的配置和用法,先從工程結構入手。

工程結構
    .
    └── test
          └── e2e
                ├── custom-assertions     // 自定義斷言
                │    └── elementCount.js
                ├── page-objects          // 頁面對象文件夾
                ├── reports               // 輸出報表文件夾
                ├── screenshots           // 自動截屏
                ├── nightwatch.conf.js    // nightwatch 運行配置
                ├── runner.js             // 運行器
                └── specs                 // 測試文件
                      └── test.spec.js

以上是vue-cli為我們自動創建的Nightwatch工程結構,specs是測試文件存放的文件夾,nightwatch.conf.js是Nightwatch的運行配置文件。其他的目錄將會在具體的章節逐一地進行講述。

 

基本配置

Nightwatch的配置項都集中在nightwatch.conf.js中,其實這個配置也可以是一個JSON格式,採用JSON格式只需要簡單地對配置項寫入一些常量即可。但使用模塊的方式進行配置可以執行一些額外的配置代碼,這樣則顯得更為靈活。以下是我調整過的nightwatch.conf.js文件內容:

    require('babel-register');
    var config = require('../../config');
    var seleniumServer = require('selenium-server');
    var phantomjs = require('phantomjs-prebuilt');

    module.exports = {
      "src_folders": ["test/e2e/specs"],
      "output_folder": "test/e2e/reports",
      "custom_assertions_path": ["test/e2e/custom-assertions"],
      "page_objects_path": "test/e2e/page-objects",
      "selenium": {
        "start_process": true,
        "server_path": seleniumServer.path,
        "port": 4444,
        "cli_args": {
          "webdriver.chrome.driver": require('chromedriver').path
        }
      },
      "test_settings": {
        "default": {
          "selenium_port": 4444,
          "selenium_host": "localhost",
          "silent": true,
          launch_url:"http://localhost:" + (process.env.PORT || config.dev.port),
          "globals": {
          }
        },
        "chrome": {
          "desiredCapabilities": {
            "browserName": "chrome",
            "javascriptEnabled": true,
            "acceptSslCerts": true
          }
        },
        "firefox": {
          "desiredCapabilities": {
            "browserName": "firefox",
            "javascriptEnabled": true,
            "acceptSslCerts": true
          }
        }
      }
    }                

Nightwatch的配置分為以下三類:

● 基本配置;

● Selenium配置;

● 測試環境配置。

在配置模塊中的所有根元素配置項都屬於基本配置,用於控制Nightwatch的全局性運行的需要。下表為Nightwatch的基本配置項的詳細說明。

 

Selenium 配置

Selenium是一組軟體工具集,每一個工具都有不同的方法來支持測試自動化。大多數使用Selenium的QA工程師只關註一兩個最能滿足他們項目需求的工具。然而,學習所有的工具你將有更多選擇來解決不同類型的測試自動化問題。這一整套工具具備豐富的測試功能,很好地契合了測試各種類型的網站應用的需要。這些操作非常靈活,有多種選擇來定位UI元素,同時將預期的測試結果和實際的行為進行比較。Selenium一個最關鍵的特性是支持在多瀏覽器平臺上進行測試。

Selenium誕生於2004年,當在ThoughtWorks工作的Jason Huggins在測試一個內部應 用時,作為一個聰明的家伙,他意識到相對於每次改動都需要手工進行測試,他的時間應該用得更有價值。他開發了一個可以驅動頁面進行交互的JavaScript庫,能讓多瀏覽器自動返回測試結果。那個庫最終變成了Selenium的核心,它是Selenium RC(遠程式控制制)和Selenium IDE所有功能的基礎。Selenium RC是開拓性的,因為沒有其他產品能讓你使用自己喜歡的語言來控制瀏覽器。

Selenium是一個龐大的工具,所以它也有自己的缺點。由於它使用了基於JavaScript的自動化引擎,而瀏覽器對JavaScript又有很多安全限制,有些事情就難以實現。更糟糕的是,網站應用正變得越來越強大,它們使用了新瀏覽器提供的各種特性,都使得這些限制讓人痛苦不堪。在2006年,一名Google的工程師Simon Stewart開始基於這個項目進行開發,這個項目被命名為WebDriver。此時,Google早已是Selenium的重度用戶,但是測試工程師們不得不繞過它的限制。Simon需要一款能通過瀏覽器和操作系統的本地方法直接和瀏覽器進行通話的測試工具,來解決JavaScript環境沙箱的問題。WebDriver項目的目標就是要解決Selenium的痛點。

Selenium 1 (又叫Selenium RC或Remote Control)在很長一段時間內,Selenium RC都是最主要的Selenium項目,直到WebDriver和Selenium合併而產生了最新且最強大的Selenium 2。Seleinum 1仍然被活躍地支持著(更多是維護),並且提供一些Selenium 2短時間內可能不會支持的特性,包括對多種語言的支持(Java、JavaScript、Ruby、PHP、Python、Perl和C#)和對大多數瀏覽器的支持。

Selenium 2 (又叫Selenium WebDriver)代表了這個項目未來的方向,也是最新被添加到Selenium工具集中的。這個全新的自動化工具提供了很多了不起的特性,包括更內聚和麵向對象的API,並且解決了舊版本限制。Selenium和WebDriver的作者都贊同兩者各具優勢,而兩者的合併使得這個自動化工具更加強健。Selenium 2.0正是於此的產品。它支持WebDriver API及其底層技術,同時也在WebDriver API底下通過Selenium 1技術為移植測試代碼提供極大的靈活性。此外,為了向後相容,Selenium 2仍然使用Selenium 1的Selenium RC介面。

你可以到http://selenium-release.storage.googleapis.com/index.html下載Selenium的各個穩定版本。

在Vue項目中如果使用vue-cli,那麼Nightwatch將不需要進行任何的附加配置,否則你需要在命令行內安裝Selenium的包裝類庫:

 $ npm i selenium-server -D

Nightwatch能引導Selenium的啟動,實際上我們並沒有必要去修改Selenium伺服器的預設運行配置,在nightwatch.conf.js配置文件中只需要聲明Selenium伺服器的二進位執行 文件的具體路徑即可,這個可以從selenium-server包提供的Selenium包裝對象的path屬性中獲取,而無須將本機的物理路徑寫死到配置文件內。

    var seleniumServer = require('selenium-server');

    module.exports= {
      "selenium": {        
        "start_process": true,
        "server_path": seleniumServer.path,
        "port": 4444,
        "cli_args": {
          "webdriver.chrome.driver": require('chromedriver').path
        }
      },
      // ... 省略
    }

以下是Selenium的詳細配置項說明:

 

 cli_args 的配置

● webdriver.firefox.profile:Selenium預設為每個會話創建一個獨立的Firefox配置方案。如果你希望使用新的驅動配置可以在此進行聲明。

● webdriver.chrome.driver:Nightwatch同樣可以使用Chrome瀏覽器載入測試,當然你要先下載一個ChromeDriver的二進位運行庫對此進行支持。此配置項用於指明ChromeDriver的安裝位置。除此之外,還需要在test_settings配置內使用desiredCapabilities對象為Chrome建立配置方案。

● webdriver.ie.driver:Nightwatch也支持IE,其作用與用法與Chrome相同,此處則不過多贅述。

 

測試環境配置

test_settings內的項目將應用於所有的測試實例,在E2E測試中我們可以通過Nightwatch提供的預設實例對象browser獲取這些配置值,vue-cli為我們創建了default、firefox和chrome三個環境配置項,default配置是應用於所有環境的基礎配置選項,其他的配置項會自動覆蓋與default相同的配置值。

firefox和chrome這兩個配置項是對兩種瀏覽器的驅動進行描述和配置。對於其他語言或框架而言它們也是常客,但由於性能太低,在實戰中通常只是個擺設,下文中我將會介紹一種實戰效率更高的無頭瀏覽器PhantomJS,對其取而代之。

不要被vue-cli創建預設配置所迷惑,test_settings並不單單隻是對瀏覽器的一些基本運行參數的配置,它正確的用法是對E2E測試環境的配置。單元測試只能運行於開發環境內,而E2E卻可以運行於本地環境與網路環境,更準確地說是開發環境與生產環境。所以這個配置項可以用以下的方式進行設置:

    "test_settings": {
        "default": {
          "selenium_port": 4444,
          "selenium_host": "localhost",
          "silent": true,
          launch_url:"http://localhost:" + (process.env.PORT || config.dev.port),
          "globals": {}
        },
        "dev": {
          "desiredCapabilities": {
            "browserName": "chrome",
            "javascriptEnabled": true,
            "acceptSslCerts": true
          }
        },
        "production": {
          "launch_url":"http://www.your-domain.com"
          "desiredCapabilities": {
            "browserName": "firefox",
            "javascriptEnabled": true,
            "acceptSslCerts": true
          }
        }
      }

雖然與原有的配置只是在用詞上做了一點點改變,但用詞的改變將會徹底地改變我們對其的認知與思路!

下表是測試環境配置項的詳細說明:

 

 執行 E2E 測試

vue-cli已經在package.json中配置了運行測試的指令:

 $ npm run e2e

這個指令是預設啟用Chrome運行環境的,如果指定運行環境可使用--env選項:

 $ npm run e2e --env

使用無頭瀏覽器 PhantomJS

vue-cli webpack腳手架模板非常好用,它將環境的複雜性降低了很多,但是卻沒有很好地詮釋它裡面採用的每個模塊的理由和功能,以及它們的使用特點。這對於入門者來說確實是將門檻降到最低點,但從工程化開發的角度來說,只知道有這些環境或者工具的存在是遠遠不夠的,在Nightwatch中就埋了一個這樣的坑。

我們的開發環境在配置Mocha和Karma時就已經安裝了PhantomJS,但如果你細讀Nightwatch的預設配置會驚奇地發現根本沒有採用PhantomJS,只是配置了Chrome和Firefox!問題何在?一個字:慢!

Chrome的啟動是很慢的,我們做E2E這種自動化測試如果用真實瀏覽器的話只能將性能拖下來,生命不能耗費在毫無意義的等待中!所以我們才會選擇PhantomJS!沒有預設配置PhantomJS作為主瀏覽器是這個環境的最大敗筆。

辦法總比問題多,所以如果沒有,我們還可以自己動手來配置,其實方法也很簡單。打開nightwatch.conf.js,在test_settings配置段的下方加入以下的內容:

    "test_settings": {
      "default": {
        // ...
      }
    },

    "phantom":{
      "desiredCapabilities": {
        "browserName": "phantomjs",
        "javascriptEnabled": true,
        "acceptSslCerts": true,
        "phantomjs.page.settings.userAgent" : "Mozilla/5.0 (Macintosh; Intel MacOS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36",
        "phantomjs.binary.path":"node_modules/phantomjs-prebuilt/bin/phantomjs"
      }
    }

Nightwatch是通過Selenium載入一個GhostDriver來引導PhantomJS瀏覽器的,上面的內容就相當於告訴Selenium載入一個GhostDriver,可執行程式則指向npm上安裝的phantomjs-prebuilt包,再通過這個包來引導安裝在本機上的PhantomJS啟動。

按上文這樣來引用PhantomJS的二進位程式的地址非常難看,還有原生配置中的Selenium執行程式地址也是一樣的,這裡介紹一個更DRY的方法來處理這些路徑:

    var seleniumServer = require('selenium-server');
    var phantomjs = require('phantomjs-prebuilt');


    module.exports = {
      // ...省略

      "selenium": {
        // ... 省略

        "server_path": seleniumServer.path,
      },

      "test_settings": {
        // ... 省略

        "phantom": {
          "desiredCapabilities": {
            // ... 省略

            "phantomjs.binary.path": phantomjs.path
          }
        }

        // ... 省略
      }
   }

 做完這個簡單的優化後就可以打開runner.js文件找到:

    if (opts.indexOf('--env') === -1) {
      opts = opts.concat(['--env', 'chrome'])
    }

 將chrome改為phantom就行了:

    if (opts.indexOf('--env') === -1) {
      opts = opts.concat(['--env', 'phantom'])
    }

重新載入測試程式,在同一臺iMac上的運行速度直接降到了5秒,測試運行速度提升了3倍!如果你有配置更好的機器,將硬碟換成SSD之後會有更驚人的速度。

 

Nightwatch 與 Cucumber

如果你正在開發的項目的業務複雜性不大,可以直接使用Nightwatch推薦的鏈式調用寫法。但是當這種做法真正應用在業務流程較多,或者業務操作相對複雜的應用場景時,你會覺得總有寫不完的E2E測試,因為這麼做E2E測試是沒有辦法一次性覆蓋所有需求的!

E2E測試其實是行為式驅動開發的實現手法,如果跳過了行為式驅動開發的分析部分直接編寫E2E,其結果只能是寫出一堆嚴重碎片化的測試場景,甚至會出現很多根本不應該出現的操作。

幸好Nightwatch具有很好的擴展性與相容性,能集成最正統的BDD測試框架Cucumber(https://cucumber.io/)。Cucumber是原生於Ruby世界的BDD框架,但它也有很多的語言實現版本,我們可以安裝一套專門為Nightwatch編寫的Cucumber版本——nightwatch-cucumber(https://github.com/mucsi96/nightwatch-cucumber)。本章只介紹關於環境與工具的配置,而關於如何來應用BDD,內容已經超出了本書的知識範圍,如果有興趣的話可以參考《攀登架構之巔》一書中行為式驅動開發的章節內容。

 $ npm i nightwatch-cucumber -D

然後在~/test/e2e/nightwatch.conf.js文件中加入對Cucumber的配置:

  // ... 省略
    require('babel-register');
    require('nightwatch-cucumber')({
      
    nightwatchClientAsParameter: true,
      featureFiles: ['test/e2e/features'],
      stepDefinitions: ['test/e2e/features/step_definitions'],      
      jsonReport: 'test/e2e/reports/cucumber.json',
      htmlReport: 'test/e2e/reports/cucumber.html',
      openReport: false
    });

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • iframe這個標簽之前瞭解過這個東西,知道它可以引入外來的網頁,但是實際開發中沒有用到過。這一次有一個需求是說準備要在網頁中嵌套另外一個網站,用iframe這個標簽,讓我測試一下這個可不可以在自己的網頁中對引入進來的iframe框架進行操作,操作dom和css的一些東西。讓我做出一個小案例看看可不 ...
  • 一、準備工作 1安裝vue-cli npm install vue-cli -g 2檢查是否安裝成功 vue -V(大寫V) 3初始化一個新的項目 vue init webpack vue-demo 進入項目目錄 npm install npm run dev 二、配置路由 1我們可以看到生成的ro ...
  • 向上遍歷 DOM 樹(祖先) 這些 jQuery 方法很有用,它們用於向上遍歷 DOM 樹: parent() 方法返回被選元素的直接父元素。親自試一試 parents() 方法返回被選元素的所有祖先元素,它一路向上直到文檔的根元素 親自試一試 您也可以使用可選參數來過濾對祖先元素的搜索。 親自試一 ...
  • 組件入口函數1: onLoad: 組件載入的時候調用, 保證了你可以獲取到場景中的其他節點,以及節點關聯的資源數據;2: start: 也就是第一次執行 update 之前觸發;3: update(dt):組件每次刷新的時候調用,距離上一次刷新的時間(會在所有畫面更新前執行);4: lateUpda ...
  • 先來看看position: fixed;的定義:生成絕對定位的元素,相對於瀏覽器視窗進行定位; 但是在iframe中使用fixed定位,實際上是相對於iframe視窗進行定位,原因在於iframe類似於創建了一個瀏覽器視窗,在使用一些獲取滑鼠位置以及元素位置等方法的時候把iframe當作瀏覽器視窗來 ...
  • 以下介紹的兩種屬性是為後面的屬性支持左鋪墊,大概一看就OK了。 事件屬性 ...
  • 大概是CSS3吧,出了一個叫CSS變數的東西,也叫自定義屬性,還是比較有用的東東,可以用JavaScript靈活控制,變數作用 我們來實現一個div跟隨滑鼠滾動的小東西用來說明如何自定義變數 HTML代碼如下: JavaScript代碼,我們來寫一段監聽,處理變數值 這樣就實現了我們想要的效果,當然 ...
  • 3d建築,3d消防,消防演習模擬,3d庫房,3d檔案室,3d密集架,webGL,threejs,3d機房,bim管理系統 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...