打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
使用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('http://net.tutsplus.com', function (s) {    console.log(s);    phantom.exit();});

我们首先加载PhantomJS的 webpage 模块并创建一个webpage对象。接着,我们调用 open 方法,传递给它一个URL和一个回调函数;正是在这个回调函数内部,我们可以与实际的页面交互。在上面的例子中,我们只是记录由回调函数的参数提供的请求状态。如果你运行这个脚本(用 phantomjs script.js  ),你看到终端打印出“成功”。

但是,让我们加载一个网页,并执行一些JavaScript代码,把这变得更加有趣些。我们从上面的代码开始,接着调用 page.evaluate  :

page.open('http://net.tutsplus.com', 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 方法提供的屏幕截图尺寸。正如你所见,我们设置 topleft 值来设置起点,并且我们还设置了 widthheight  。最后,我们调用 page.render  ,传给它一个文件名(  title 变量)。接着,我们调用 phantom.exit() 结束脚本

继续运行这个脚本,你应该拥有一副看起来像这样的图片:

在这里,你可以看到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 out Chutzpah  ,Rails开发人员应该试试 guard-jasmine  。但除此之外,对Jasmine+ PhantomJS的支持非常稀疏。

出于这个原因,我建议你使用Mocha进行D OM相关的测试。

尽管如此,很可能你已经有一个项目在使用Jasmine ,并想与PhantomJS一起使用。一个叫  phantom-jasmine 的项目 ,需要一点点的设置工作,但它应该能够达到目的。

让我们从一组JasmineJS测试用例开始。下载本教程的代码(在顶部的链接),并check out jasmine-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"></script><script src="lib/jasmine-1.2.0/jasmine-html.js"></script><script src="lib/console-runner.js"></script><script src="tests.js"></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.coffee ./SpecRunner.html

我们正在使用PhantomJS运行 run\_jasmine\_test.coffee 脚本,并将 SpecRunner.html 文件作为参数传递。你应该会看到这样的内容:

当然,如果一个测试用例失败,你会看到类似以下内容:

如果你打算经常使用这货,将  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"></div>        <script src="./node_modules/mocha/mocha.js"></script>        <script src="./node_modules/chai/chai.js"></script>        <script>            mocha.ui('bdd');            mocha.reporter('html');            var expect = chai.expect;        </script>        <script src="test/test.js"></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改进的项目吗?让我们在评论中听听!

原文链接:http://net.tutsplus.com/tutorials/javascript-ajax/testing-javascript-with-phantomjs/
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
为React开发人员推荐8个测试工具、库和框架
五个值得尝试的前端开发工具
无头浏览器
自动化、跨浏览器的 JavaScript 单元测试
学习JQuery (一)
Mocha浏览器测试入门教程 | Fundebug博客
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服