Getting Started with Zombie.js

Exclusive offer: get 50% off this eBook here
Using Node.js for UI Testing

Using Node.js for UI Testing — Save 50%

Learn how to easily automate testing of your web apps using Node.js, Zombie.js, and Mocha with this book and ebook.

$14.99    $7.50
by Pedro Teixeira | May 2013 | Open Source Web Development

"Zombie.js is a lightweight framework for testing client-side JavaScript code in a simulated environment. No browser required."

This definition is from the Zombie.js documentation at http://zombie.labnotes.org. Automating tests for your web application is crucial to having a quality product but doing it properly can be a painful experience. That is why most of the time this part of the project never gets implemented. Developers either limit themselves to testing the underlying business logic and control flow in isolation, or, if they really want to test the user interface, must resort to complicated setups where you somehow connect to real browsers and command them using remote scripts.

Zombie.js provides a fast and easy alternative to this scenario, enabling you to easily and quickly create automated tests for your web application just by using JavaScript.

In this article by Pedro Teixeira from the book Using Node.js for UI Testing, we will cover following topics:

  1. A brief history of software testing

  2. Understanding the server-side DOM

  3. How Zombie.js works internally

By the end of this article, you should understand how Zombie.js works and what types of applications can be tested using it.

(For more resources related to this topic, see here.)

A brief history of software and user interface testing

Software testing is a necessary activity for gathering information about the quality of a certain product or a service. In the traditional software development cycle, this activity had been delegated to a team whose sole job was to find problems in the software. This type of testing would be required if a generic product was being sold to a domestic end user or if a company was buying a licensed operating system.

In most custom-built pieces of software, the testing team has the responsibility of manually testing the software, but often the client has to do the acceptance testing in which he or she has to make sure that the software behaves as expected.

Every time someone in these teams finds a new problem in the software, the development team has to fix the software and put it back in the testing loop one more time. This implies that the cost and time required to deliver a final version of the software increases every time a bug is found. Furthermore, the later in the development process the problem is found, the more it will impact the final cost of the product.

Also, the way software is delivered has changed in the last few years; the Web has enabled us to make the delivery of software and its upgrade easy, shortening the time between when new functionality is developed and when it is put in use. But once you have delivered the first version of a product and have a few customers using it, you can face a dilemma; fewer updates can mean the product quickly becomes obsolete. On the other hand, introducing many changes in the software increases the chance of something going wrong and your software becoming faulty, which may drive customers away.

There are many versions and iterations over how a development process can mitigate the risk of shipping a faulty product and increase the chances of new functionalities to be delivered on time, and for the overall product to meet a certain quality standard, but all people involved in building software must agree that the sooner you catch a bug, the better.

This means that you should catch the problems early on, preferably in the development cycle. Unfortunately, completely testing the software by hand every time the software changes, would be costly. The solution here is to automate the tests in order to maximize the test coverage (the percentage of the application code that is tested and the possible input variations) and minimize the time it takes to run each test. If your tests take just a few seconds to run, you can afford to run them every time you make a single change in the code base.

Enter the automation era

Test automation has been around for some years, even before the Web was around. As soon as graphical user interfaces (GUIs) started to become mainstream, the tools that allowed you to record, build, and run automated tests against a GUI started appearing. Since there were many languages and GUI libraries for building applications, many tools that covered some of these started showing up. Generally they allowed you to record a testing session that you could later recreate automatically. In this session, you could automate the pointer to click on things (buttons, checkboxes, places on a window, and so on), select values (from a select box, for instance), and input keyboard actions and test the results.

All of these tools were fairly complex to operate and, worst of all, most of them were technology-specific.

But, if you're building a web-based application that uses HTML and JavaScript, you have better alternatives. The most well known of these is likely to be Selenium, which allows you to record, change, and run testing scripts against all the major browsers.

You can run tests using Selenium, but you need at least one browser for Selenium to attach itself to, in order to load and run the tests. If you run the tests with as many browsers as you possibly can, you will be able to guarantee that your application behaves correctly across all of them. But since Selenium plugs into a browser and commands it, running all the tests for a considerably complex application in as many browsers as possible can take some time, and the last thing you want is to not run the tests as often as possible.

Unit tests versus integration tests

Generally you can divide automated tests into two categories, namely unit tests and integration tests.

  • Unit tests: These tests are where you select a small subset of your application—such as a class or a specific object—and test the interface the class or object provides to the rest of the application. In this way, you can isolate a specific component and make sure it behaves as expected so that other components in the application can use it safely.

  • Integration tests: These tests are where individual components are combined together and tested as a working group. During these tests, you interact and manipulate the user interface that in turn interacts with the underlying blocks of your application. The kind of testing you do with Zombie.js falls in this category.

What Zombie.js is

Zombie.js allows you to run these tests without a real web browser. Instead, it uses a simulated browser where it stores the HTML code and runs the JavaScript you may have in your HTML page. This means that an HTML page doesn't need to be displayed, saving precious time that would otherwise be occupied rendering it.

You can then use Zombie.js to conduct this simulated browser into loading pages and, once a page is loaded, doing certain actions and observing the results. And you can do all this using JavaScript, never having to switch languages between your client code and your test scripts.

Understanding the server-side DOM

Zombie.js runs on top of Node.js (http://nodejs.org), a platform where you can easily build networking servers using JavaScript. It runs on top of Google's fast V8 JavaScript engine that also powers their Chrome browsers.

At the time of writing, V8 implements the JavaScript ECMA 3 standard and part of the ECMA 5 standard. Not all browsers implement all the features of all the versions of the JavaScript standards equally. This means that even if your tests pass in Zombie.js, it doesn't mean they will pass for all the target browsers.

On top of Node.js, there is a third-party module named JSDOM (https://npmjs.org/package/jsdom) that allows you to parse an HTML document and use an API on top of a representation of that document; this allows you to query and manipulate it. The API provided is the standard Document Object Model (DOM).

All browsers implement a subset of the DOM standard, which has been dictated as a set of recommendations by a working group inside the World Wide Web Consortium (W3C). They have three levels of recommendations. JSDOM implements all three.

Web applications, directly or indirectly (by using tools such as jQuery), use this browser-provided DOM API to query and manipulate the document, enabling you to create browser applications that have complex behavior. This means that by using JSDOM you automatically support any JavaScript libraries that most modern browsers support.

Zombie.js is your headless browser

On top of Node.js and JSDOM lies Zombie.js. Zombie.js provides browser-like functionality and an API you can use for testing. For instance, a typical use of Zombie.js would be to open a browser, ask for a certain URL to be loaded, fill some values on a form, and submit it, and then query the resulting document to see if a success message is present.

To make it more concrete, here is a simple example of what the code for a simple Zombie.js test may look like:

browser.visit('http://localhost:8080/form', function() {
browser
.fill('Name', 'Pedro Teixeira')
.select('Born', '1975')
.check('Agree with terms and conditions')
.pressButton('Submit', function() {
assert.equal(browser.location.pathname, '/success');
assert.equal(browser.text('#message'),
'Thank you for submitting this form!');
});
});

Here you are making typical use of Zombie.js: to load an HTML page containing a form; filling that form and submitting it; and then verifying that the result is successful.

Zombie.js may not only be used for testing your web app but also by applications that need to behave like browsers, such as HTML scrapers, crawlers, and all sorts of HTML bots.

If you are going to use Zombie.js to do any of these activities, please be a good Web citizen and use it ethically.

Summary

Creating automated tests is a vital part of the development process of any software application. When creating web applications using HTML, JavaScript, and CSS, you can use Zombie.js to create a set of tests; these tests load, query, manipulate, and provide inputs to any given web page. Given that Zombie.js simulates a browser and does not depend on the actual rendering of the HTML page, the tests run much faster than they would if you instrumented a real browser. Thus it is possible for you to run these tests whenever you make any small changes to your application. Zombie.js runs on top of Node.js, uses JSDOM to provide a DOM API on top of any HTML document, and simulates browser-like functionalities with a simple API that you can use to create your tests using JavaScript

Resources for Article :


Further resources on this subject:

Using Node.js for UI Testing Learn how to easily automate testing of your web apps using Node.js, Zombie.js, and Mocha with this book and ebook.
Published: March 2013
eBook Price: $14.99
Book Price: $29.99
See more
Select your format and quantity:

About the Author :


Pedro Teixeira

Pedro Teixeira is a prolific open source programmer and author of many Node.js modules. After he graduated as a software engineer over 14 years ago, he has been a consultant, a programmer, and an active and internationally known Node.js community member.

He is a founding partner of The Node Firm (a consulting company specializing in Node.js) and author of the popular Node Tuts screencasts (www.nodetuts.com) and three other books about Node.js, namely, Hands-on Node.js (self-published), Professional Node.js, Wrox, and Node.js for UI Testing, Packt Publishing.

When he was ten years old, his father taught him how to program a ZX Spectrum, and since then, he never wanted to stop. He taught himself how to program his father's Apple IIc and then entered the PC era. During college, he was introduced to the universe of Unix and open source, becoming seriously addicted to it. In his professional life, he has developed systems and products with Visual Basic, C, C++, Java, PHP, Ruby, and JavaScript for big Telco companies, banks, hotel chains, and others.

He has been a Node.js enthusiast since the very beginning, having authored many applications and also many well-known modules, such as Fugue, Alfred.js, Carrier, Nock, and others.

He's the organizer of LXJS— the Lisbon JavaScript Conference.

Books From Packt


Instant NodeJS Starter [Instant]
Instant NodeJS Starter [Instant]

Node Cookbook
Node Cookbook

CoffeeScript Programming with jQuery, Rails, and Node.js
CoffeeScript Programming with jQuery, Rails, and Node.js

Node Web Development
Node Web Development

HP Network Node Manager 9: Getting Started
HP Network Node Manager 9: Getting Started

Node Web Development (2nd Edition)
Node Web Development (2nd Edition)

Backbone.js Cookbook
Backbone.js Cookbook

Getting Started with Meteor.js JavaScript Framework
Getting Started with Meteor.js JavaScript Framework


No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
b
v
i
i
q
m
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software