Using PHANTOMJS to test JavaScript

Source: Internet
Author: User
Tags script tag

I don't think I need to convince you that testing your JavaScript code is a good idea. However, it is sometimes tedious to test the JavaScript code that requires DOM manipulation. This means that you need to test the code in your browser and not use the terminal, right? Wrong, the fact is: into the PHANTOMJS.

What exactly is PHANTOMJS? Well, here's an introduction from the PHANTOMJS website:

PHANTOMJS is a non-interface webkit with JavaScript APIs.

As you know, WebKit is the layout engine used by Chrome, Safari, and some other niche browsers. Therefore, PHANTOMJS is a browser and is a browser with no interface. This means that the rendered page is never actually displayed. This may be incredible to you, so you can use it as a programmable browser terminal. We'll look at a simple example, but first we need to install PHANTOMJS.

Installing PHANTOMJS

Installing PHANTOMJS is actually simple: you download only a single binary file, and then stick the file path to the terminal. On the PHANTOMJS download page, select your operating system and download the correct package. Next, move the binaries from the downloaded package to a directory in your terminal path (I like to put this stuff in ~/bin).

If you're using Mac OS X, there's an easier way to install PHANTOMJS (which is actually the method I'm using). Just use homebrew like this:

Brew Update && Brew install PHANTOMJS

You should have installed the PHANTOMJS now. You can run the following command to check the installation information carefully:

Phantomjs--version

I see 1.7.0, what about you?

A simple example

Let's start with a simple example.

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 ();

Go ahead and issue the following command to run the code:

Phantomjs Simple.js

You should see output from two rows of console.log in the terminal window.

Of course, this is easy, but it proves a pretty good point: Phantomjs can execute javascript like a browser. However, this example does not have any PHANTOMJS-specific code ... All right, except for the last line. That line of code is important for each PHANTOMJS script because it exits script execution. This may not make sense, but keep in mind that JavaScript is not always executed sequentially. For example, you might want to put the call of exit () in a callback function.

Let's look at a more complex example.

Load page

By using the Phantomjs API, we can load any URL and work with a page from two dimensions:

    • As JavaScript on the page.
    • As a user who is browsing the page.

Let's start with the Select Load page. Create a new script file and add the following code:

Script.js

var page = require (' webpage '). Create (); Page.open (', function (s) {console.log (s); Phantom.exit ();});

We first load the PHANTOMJS webpage module and create a webpage object. Next, we call the open method, pass it a URL and a callback function, and it is within this callback function that we can interact with the actual page. In the above example, we just record the request state provided by the parameters of the callback function. If you run this script (with Phantomjs script.js), you see that the terminal prints "success".

However, let's load a Web page and execute some JavaScript code, which makes it more interesting. We start with the code above and then call Page.evaluate:

Page.open (', function () {var title = Page.evaluate (function () {var posts = Document.getelementsbyclassname ("post"); p Osts[0].style.backgroundcolor = "#000000"; return document.title; }); Page.cliprect = {top:0, left:0, width:600, height:700}; Page.render (title + ". png"); Phantom.exit (); });

Phantomjs is a browser, but it is a browser with no interface.

The functions we pass to Page.evaluate are executed as JavaScript on the loaded Web page. In this use case, we find all the elements with the Post class element, and then we set the background of the first element in the collection to black. Finally, we return to Document.title. This is a good feature to return a value from the evaluate callback function and assign it to a variable (here is the title).

We then set the Cliprect on the page, which is the screen size provided for the Render method. As you can see, we set the top and left values to set the starting point, and we also set the width and height. Finally, we call Page.render and pass it a filename (the title variable). Next, we call the Phantom.exit () End script

To continue running this script, you should have a picture that looks like this:

  

Here you can see the two sides of the PHANTOMJS coin: You can execute JavaScript within the page, and you can execute it externally for the page instance itself.

It's fun, but it's not very useful. Let's focus our attention on using PHANTOMJS to test DOM-related JavaScript.

Test with PHANTOMJS

Yeoman uses PHANTOMJS in its testing process, and it is almost seamless.

For a lot of JavaScript code, you can not rely on DOM testing, but there are times when your test cases require HTML elements to work together. If you like me, like running test cases on the command line, that's where Phantomjs comes in.

Of course, PHANTOMJS is not a test library, but many other popular test libraries can run in PHANTOMJS. As you can see from the PHANTOMJS wiki page about no-interface testing, the PHANTOMJS test drive can be used for almost every test library you might want to use. Let's take a look at how to use PHANTOMJS with Jasmine and mocha.

First, Jasmine and a disclaimer: There is no good PHANTOMJS driver for Jasmine. If you use Windows and visual Studio, you should go to check outchutzpah, and rails developers should try Guard-jasmine. But beyond that, the support for jasmine+ Phantomjs is sparse.

For this reason, I recommend that you use Mocha for the D om related tests.

Nonetheless, it is likely that you already have a project in use with Jasmine and want to use it with PHANTOMJS. A project called Phantom-jasmine needs a little bit of setup work, but it should be able to achieve the goal.

Let's start with a set of jasminejs test cases. Download the code for this tutorial (at the top of the link) and check the Outjasmine-starter folder. As you'll see, we have a separate tests.js file that creates a DOM element, sets several properties of the DOM element, and adds it to the body. Then, we run some jasmine test cases to make sure that this process does work correctly. The following is the contents of the file:

Tests.js

Describe ("DOM Tests", function () {var el = document.createelement ("div"); el.id = "Mydiv"; el.innerhtml = "Hi there!"; e L.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 ("Have the right text", function () {expect (myel.innerhtml). Toequal ("Hi there!");}); It ("Have the right background", function () {expect (myEl.style.background). Toequal ("RGB (204, 204, 204)");}); });

The specrunner.html file is quite a trunk; the only difference is that I move the script tag into the body to make sure that the DOM is fully loaded before running our tests. You can open the file in the browser and see that all the tests are well passed.

Let's transition this project to PHANTOMJS. First, clone the Phantom-jasmine project:

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

The project is not so organized, but it has two important components that you need:

    • PHANTOMJS driver (This allows Jasmine to use the Phantomjs DOM).
    • Jasmine Console Reporter (This provides console output).

These two files belong to the Lib folder and are copied to jasmine-starter/lib. Now we need to open the Specrunner.html file and adjust the <script/> element. They should look like this:

<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>

Please note that there are two reports in our test: HTML reporter and one console reporter. This means that specrunner.html and its tests can be run in both the browser and the console. This is very convenient. Unfortunately, we do need to have the console_reporter variable, because it is used internally for the Coffeescript file we are about to run.

So, how do you actually run these tests on the console? Assuming your terminal's current directory is the Jasmine-starter folder, here are the commands:

Phantomjs Lib/run\_jasmine\_test.coffeel

We are using PHANTOMJS to run the Run\_jasmine\_test.coffee script and pass the specrunner.html file as a parameter. You should see something like this:

  

Of course, if a test case fails, you'll see something like this:

  

If you intend to use this item frequently, moving the Run\_jasmine\_test.coffee to another location (such as ~/bin/run\_jasmine\_test.coffee) might be a good idea and create a terminal alias for the entire command. Here's how you can do this in the bash shell:

Alias phantom-jasmine= ' Phantomjs/path/to/run\_jasmine\_test.coffee '

Just leave it in your. BASHRC or. bash_profile file. Now, you can just run:

Phantom-jasmine specrunner.html

Now your Jasmine Test runs well through the PHANTOMJS on the terminal. You can see the final code in the Jasmine-total in the download folder.

Phantomjs and Mocha

Thankfully, it's easier to integrate Mocha and PHANTOMJS with MOCHA-PHANTOMJS. If you already have NPM installed (you should install it), then installing MOCHA-PHANTOMJS is super easy:

NPM install-g Mocha-phantomjs

This command installs a MOCHA-PHANTOMJS binary file that we will use to run our tests.

In the previous tutorial, I showed you how to use Mocha in a terminal, but when you use it to test DOM code, you do something different. As with Jasmine, we will start with an HTML test reporter that can run in the browser. Beautifully, for the console test results, we can run the same file on the terminal with PHANTOMJS, as we used Jasmine.

So, let's create a simple project. Create a project directory and switch to its path. Let's start with a Package.json file:

{"Name": "Project", "Version": "0.0.1", "devdependencies": {"Mocha": "*", "Chai": "*"}}

Mocha is the test framework, we will use chai as our assertion library. We run NPM to install these.

We name the test file Test/tests.js, and here is its test case:

Describe ("DOM Tests", function () {var el = document.createelement ("div"); el.id = "Mydiv"; el.innerhtml = "Hi there!"; e L.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 ("Have the right text", function () {expect (myel.innerhtml). To.equal ("Hi there!");}); It ("Have the right background", function () {expect (myEl.style.background). To.equal ("RGB (204, 204, 204)");}); });

They are very similar to jasmine test cases, but the Chai assertion syntax is a bit different (so don't just copy your Jasmine test case).

The last challenge is the testrunner.html file:

Here are a few important factors. First, note that this is fully capable of running in the browser, and we have CSS and JavaScript from the node module installed. Next, note the inline script tag. This will determine whether the PHANTOMJS is loaded and, if loaded, runs the PHANTOMJS function. Otherwise, it uses native Mocha functionality. You can try to run it in the browser and watch it work.

To run in the console, simply execute the following command:

Mocha-phantomjs testrunner.html

Look! Now your test cases are running in the console, thanks to Phantomjs.

Phantomjs and Yeoman

I bet you don't know that popular yeoman use PHANTOMJS in their testing process, and it's almost seamless. Let's look at a quick example. I'll assume you've set everything up for yeoman.

Create a new project directory, run the Yeoman init inside, and select "NO" for all options. Open the test/index.html file, and you'll find a script tag near the bottom, with a note in the script that tells you to replace it with your own use case. Completely ignoring that good advice and putting the following in the IT block:

var el = document.createelement ("div"); Expect (El.tagname). To.equal ("DIV");

Now, run Yeoman test and you'll see that the test runs pretty well. Now, open the test/index.html file in your browser. It's working! Perfect!

Of course, you can also do more with Yeoman, so check out its documentation for a deeper understanding.

Conclusion

Make your tests easier by using libraries that are extended to PHANTOMJS.

If you are using PHANTOMJS, learning Phantomjs is for no reason, you can only know its presence and use the library extended to Phantomjs to make your tests easier.

Hopefully this tutorial has inspired you to observe PHANTOMJS's interest. I recommend starting with the sample files and documents provided by PHANTOMJS; they really open your horizons and let you know what you can do with PHANTOMJS-everything from page automation to network sniffing.

So, can you think of a project that can be improved with PHANTOMJS? Let's hear it in the comments!

Using PHANTOMJS to test JavaScript

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.