運用PhantomJS測試JavaScript


 我認為我不需要說服你,測試你的JavaScript代碼是一個好主意。但是,測試需要DOM操作的JavaScript代碼有時候確是繁瑣的。這意味着你需要在瀏覽器中測試代碼而不能使用終端,對嗎?錯了,事實是:進入PhantomJS 。

  究竟PhantomJS是什么?好吧,這有一個來自PhantomJS網站的簡介:

  PhantomJS是一個擁有JavaScript API的無界面WebKit。

  正如你所知道的,Webkit是Chrome、Safari和其他一些小眾瀏覽器使用的布局引擎。因此,PhantomJS是一個瀏覽器,而且是一個無界面的瀏覽器。這意味着,渲染后的網頁實際上絕不會顯示。這對你來說可能不可思議,所以你可以把它作為一個可編程的瀏覽器終端。我們馬上將看一個簡單的例子,但首先需要安裝PhantomJS。

安裝PhantomJS

  安裝PhantomJS事實上很簡單:你下載的僅僅是單獨的一個二進制文件,接着將文件路徑粘帖到終端。在PhantomJS下載頁面 ,選擇您的操作系統並下載正確的軟件包。接着,將二進制文件從下載的程序包中移動到一個在你終端路徑的目錄中(我喜歡把這類玩意放到~/bin里)。

  如果你用的是Mac OS X,有一個更簡單的方法安裝PhantomJS(這實際上是我所使用的方法)。只需像這樣使用Homebrew:

  brew update && brew install phantomjs

  你現在應該已經安裝了PhantomJS。你可以運行以下命令仔細檢查安裝信息:

  phantomjs --version

  我看到1.7.0,你呢?

一個簡單的例子

  讓我們先從一個簡單的例子開始吧

simple.js

  console.log("we can log stuff out."); function add(a, b) { return a + b; } conslole.log("We can execute regular JS too:", add(1, 2)); phantom.exit();

  繼續前進,發出以下命令運行這段代碼:

  phantomjs simple.js

  你應該在終端窗口中看到來自兩行console.log的輸出。

  當然,這很容易,但它證明了一個很不錯的點:PhantomJS可以像一個瀏覽器那樣執行JavaScript。然而,這個例子並沒有任何特定於PhantomJS的代碼......好吧,除了最后一行。那行代碼對於每個PhantomJS腳本都很重要,因為它退出腳本執行。這可能說不通,但要記住,JavaScript並不總是順序執行。例如,你可能想要把exit()的調用放在一個回調函數中 。

  讓我們看一個更復雜的例子。

加載頁面

  通過使用PhantomJS API,我們可以加載任何URL,並從兩個維度來與頁面工作:

  • 作為頁面上的JavaScript。
  • 作為一個正在瀏覽頁面的用戶。

  讓我們從選擇加載頁面開始。創建一個新的腳本文件,並添加下面代碼:

script.js

  var page = require('webpage').create(); page.open('', function (s) { console.log(s); phantom.exit(); });

  我們首先加載PhantomJS的webpage模塊並創建一個webpage對象。接着,我們調用open方法,傳遞給它一個URL和一個回調函數;正是在這個回調函數內部,我們可以與實際的頁面交互。在上面的例子中,我們只是記錄由回調函數的參數提供的請求狀態。如果你運行這個腳本(用phantomjs script.js ),你看到終端打印出“成功”。

  但是,讓我們加載一個網頁,並執行一些JavaScript代碼,把這變得更加有趣些。我們從上面的代碼開始,接着調用page.evaluate :

  page.open('', function () { var title = page.evaluate(function () { var posts = document.getElementsByClassName("post"); posts[0].style.backgroundColor = "#000000"; return document.title; }); page.clipRect = { top: 0, left: 0, width: 600, height: 700 }; page.render(title + ".png"); phantom.exit(); });

  PhantomJS是一個瀏覽器,但是是一個無界面的瀏覽器。

  我們傳遞給page.evaluate的函數在加載的網頁上作為JavaScript執行。在這個用例中,我們找到的所有元素帶post類的元素;接着,我們設置集合中第一個元素的背景為黑色。最后,我們返回document.title 。這是一個很好的功能,從evaluate回調函數中返回值,並將其分配給一個變量(在這里是 title )。

  然后,我們在頁面上設置clipRect;這是給render方法提供的屏幕截圖尺寸。正如你所見,我們設置top和left值來設置起點,並且我們還設置了width和height 。最后,我們調用page.render ,傳給它一個文件名( title變量)。接着,我們調用phantom.exit()結束腳本

  繼續運行這個腳本,你應該擁有一副看起來像這樣的圖片:

  600x700

  在這里,你可以看到PhantomJS這枚硬幣的兩面:可以在頁面內執行JavaScript,還可以針對頁面實例自身從外部執行。

  這很有趣,但不是很有用。讓我們將目光集中在使用PhantomJS測試DOM相關的JavaScript。

用PhantomJS測試

  Yeoman在其測試過程中使用PhantomJS,並且它幾乎是無縫的。

  對於很多的JavaScript代碼,你可以不依賴DOM測試,但也有那么些時候,你的測試用例需要HTML元素一起工作。如果你像我一樣,喜歡在命令行上運行測試用例,這就是PhantomJS的用武之地。

  當然,PhantomJS是不是一個測試庫,但許多其他流行的測試庫可以運行在PhantomJS中。正如你可以從PhantomJS wiki頁面關於無界面測試中所看到的,PhantomJS的測試驅動可用於幾乎每一個你可能想使用的測試庫。讓我們來看看如何與Jasmine及Mocha一起使用PhantomJS。

  首先, Jasmine和一個免責聲明:現在並沒有一個優秀的用於Jasmine的PhantomJS驅動。如果你使用Windows和Visual Studio,你應該去check outChutzpah ,Rails開發人員應該試試guard-jasmine 。但除此之外,對Jasmine+ PhantomJS的支持非常稀疏。

  出於這個原因,我建議你使用Mocha進行D OM相關的測試。

  盡管如此,很可能你已經有一個項目在使用Jasmine ,並想與PhantomJS一起使用。一個叫 phantom-jasmine的項目 ,需要一點點的設置工作,但它應該能夠達到目的。

  讓我們從一組JasmineJS測試用例開始。下載本教程的代碼(在頂部的鏈接),並check outjasmine-starter文件夾。你會看到,我們有一個單獨的tests.js文件,該文件創建一個DOM元素,設置了DOM元素的幾個屬性,並將其添加到body中。然后,我們運行一些Jasmine 測試用例,以確保這個過程確實的正常工作。下面是該文件的內容:

tests.js

  describe("DOM Tests", function () { var el = document.createElement("div"); el.id = "myDiv"; el.innerHTML = "Hi there!"; el.style.background = "#ccc"; document.body.appendChild(el); var myEl = document.getElementById('myDiv'); it("is in the DOM", function () { expect(myEl).not.toBeNull(); }); it("is a child of the body", function () { expect(myEl.parentElement).toBe(document.body); }); it("has the right text", function () { expect(myEl.innerHTML).toEqual("Hi there!"); }); it("has the right background", function () { expect(myEl.style.background).toEqual("rgb(204, 204, 204)"); }); });

  SpecRunner.html文件是相當樹干;唯一的區別是,我將腳本標簽移到body中,以確保DOM在運行我們的測試前完全加載。你可以在瀏覽器中打開該文件,並看到所有的測試都很好的通過了。

  讓我們把這個項目過渡到PhantomJS。首先,克隆phantom-jasmine項目:

  git clone git://github.com/jcarver989/phantom-jasmine.git

  該項目並不是那么的有組織,但它有兩個重要的組成部分是你所需要的:

  • PhantomJS驅動(這使得Jasmine 能夠使用PhantomJS DOM)。
  • Jasmine 控制台報告器(這提供控制台輸出)。

  這兩個文件中都屬於lib文件夾,將其復制到jasmine-starter/lib 。現在,我們需要打開SpecRunner.html文件,並調整<script />元素。它們應該像這樣:

  <script src="lib/jasmine-1.2.0/jasmine.js"$amp;>amp;$lt;/script> <script src="lib/jasmine-1.2.0/jasmine-html.js"$amp;>amp;$lt;/script> <script src="lib/console-runner.js"$amp;>amp;$lt;/script> <script src="tests.js"$amp;>amp;$lt;/script> <script> var console_reporter = new jasmine.ConsoleReporter() jasmine.getEnv().addReporter(new jasmine.HtmlReporter()); jasmine.getEnv().addReporter(console_reporter); jasmine.getEnv().execute(); </script>

  請注意,我們的測試中有兩個報告器:HTML報告器和一個控制台報告器。這意味着SpecRunner.html和它的測試可以運行在瀏覽器和控制台。這非常方便。不幸的是,我們確實需要有console_reporter變量,因為它在內部被用於我們即將運行的CoffeeScript文件,。

  那么,如何在控制台上真實的運行這些測試呢?假設你的終端當前目錄是jasmine-starter文件夾,以下是這些命令:

  phantomjs lib/run\_jasmine\_test.coffeel

  我們正在使用PhantomJS運行run\_jasmine\_test.coffee腳本,並將SpecRunner.html文件作為參數傳遞。你應該會看到這樣的內容:

  542x174

  當然,如果一個測試用例失敗,你會看到類似以下內容:

  542x180

  如果你打算經常使用這貨,將 run\_jasmine\_test.coffee移動到另一個位置(比如~/bin/run\_jasmine\_test.coffee )也許是一個好主意,並為整個命令創建一個終端別名。這里告訴了你如何在Bash shell中做到這一點:

  alias phantom-jasmine='phantomjs /path/to/run\_jasmine\_test.coffee'

  只需丟在你的.bashrc或.bash_profile文件里。現在,你可以只運行:

  phantom-jasmine SpecRunner.html

  現在你的Jasmine測試通過PhantomJS在終端上運行良好。你可以在下載文件夾中的jasmine-total看到最終的代碼。

PhantomJS和Mocha

  值得慶幸的是,使用mocha-phantomjs整合Mocha與PhantomJS更加容易。如果你已經安裝了NPM(你應該要安裝),那么安裝mocha-phantomjs則是超級容易:

  npm install -g mocha-phantomjs

  此命令安裝一個mocha-phantomjs二進制文件,我們將用它來運行我們的測試。

  在前面的教程中 ,我向你展示了如何在終端使用Mocha,但當你用它來 測試DOM代碼時,你會做些不同的事情。與Jasmine一樣,我們將以一個可以運行在瀏覽器中的HTML測試報告器開始。美妙的是,對於控制台測試結果,我們可以用PhantomJS在終端上運行同一個文件;正如我們使用Jasmine那樣。

  那么,讓我們創建一個簡單的工程。創建一個工程目錄,並切換到它的路徑。我們以一個package.json文件為開始:

  { "name": "project", "version": "0.0.1", "devDependencies": { "mocha": "*", "chai" : "*" } }

  Mocha是測試 框架,我們將使用Chai作為我們的斷言庫。我們運行NPM安裝這些。

  我們將測試文件命名為test/tests.js ,這里是它的測試用例:

  describe("DOM Tests", function () { var el = document.createElement("div"); el.id = "myDiv"; el.innerHTML = "Hi there!"; el.style.background = "#ccc"; document.body.appendChild(el); var myEl = document.getElementById('myDiv'); it("is in the DOM", function () { expect(myEl).to.not.equal(null); }); it("is a child of the body", function () { expect(myEl.parentElement).to.equal(document.body); }); it("has the right text", function () { expect(myEl.innerHTML).to.equal("Hi there!"); }); it("has the right background", function () { expect(myEl.style.background).to.equal("rgb(204, 204, 204)"); }); });

  它們與Jasmine的測試用例非常相似,但是Chai 斷言語法則是有點不同的(所以,不要只是復制你的Jasmine測試用例)。

  最后一道難題是TestRunner.html文件:

  <html> <head> <title> Tests </title> <link rel="stylesheet" href="./node_modules/mocha/mocha.css" /> </head> <body> <div id="mocha"$amp;>amp;$lt;/div> <script src="./node_modules/mocha/mocha.js"$amp;>amp;$lt;/script> <script src="./node_modules/chai/chai.js"$amp;>amp;$lt;/script> <script> mocha.ui('bdd'); mocha.reporter('html'); var expect = chai.expect; </script> <script src="test/test.js"$amp;>amp;$lt;/script> <script> if (window.mochaPhantomJS) { mochaPhantomJS.run(); } else { mocha.run(); } </script> </body> </html>

  這里有幾個重要的因素。首先,請注意這是完全能夠運行在瀏覽器中的,我們擁有從安裝的node模塊中的CSS和JavaScript。接着,注意內聯的script標簽。這將確定PhantomJS是否加載,若加載,則運行PhantomJS的的功能。否則,它使用原生的Mocha功能。你可以嘗試在瀏覽器中運行,並觀察它的工作。

  要在控制台運行,只需執行以下命令:

  mocha-phantomjs TestRunner.html

  瞧!現在你的測試用例在控制台中運行,這一切都歸功於PhantomJS。

PhantomJS和Yeoman

  我敢打賭,你肯定不知道流行的Yeoman在其測試過程中使用PhantomJS,並且這幾乎是無縫的。讓我們看一個迅速的例子。我將假設你已經將Yeoman的一切設置好了。

  創建一個新的工程目錄,運行里面的yeoman init ,並對所有選項選擇“NO”。打開test/index.html文件,你會發現接近底部有一個腳本標簽,腳本中有一段注釋告訴你將其替換成你自己的用例。完全的忽略那個很好的建議,並把下面這些放到 it塊中:

  var el = document.createElement("div"); expect(el.tagName).to.equal("DIV");

  現在,運行yeoman test ,你會看到測試運行得相當好。現在,在瀏覽器中打開test/index.html文件。它運作了!完美!

  當然,你還可以用Yeoman做更多的事,所以check out出它的文檔做更深一步的了解。

結論

  使用擴展於PhantomJS的庫,使你的測試更加容易。

  如果你正在使用PhantomJS,學習PhantomJS是毫無任何理由的,你可以只知道它的存在和使用擴展於PhantomJS的庫來使你的測試更加容易。

  希望本教程已經激發了你去觀察PhantomJS的興趣。我建議從PhantomJS提供的示例文件和文檔開始 ;它們真的會打開你的視野,讓你知道你可以用PhantomJS做什么——從頁面自動化到網絡嗅探的任何事情。

  那么,你能想到一個能夠用PhantomJS改進的項目嗎?讓我們在評論中聽聽!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM