Venus.js Documentation

Introduction

Getting started

Install Venus.js

  1. Install Node.js:
brew install node
  1. Install PhantomJS:
brew install phantomjs
  1. Install Venus via NPM:
npm install -g venus
  1. Verify installation:
venus demo

Write your first test

In the directory of your choice, create a new file (lets call it example.js)

Contents of example.js:

describe('First unit test using venus.js', function() {
  it('Gives us the ability to run test from the command line', function() {
    expect(2 + 2).to.be(4);
  });
});

Save the file

Run your first test

venus run -t example.js --phantom

Output should look similar to:

PhantomJS

   First unit test using venus.js
     ✓ Gives us the ability to run test from the command line

✓ 1 test completed (0.01ms)

General overview

The example above uses mocha as its test runer and expect as its assertion library. That combination of libraries are what Venus.js ships with “out of the box”.

If you prefer other test runners, Venus.js also support, qunit, and jasmine while giving you the ability to extend support to more libraries by tailoring your own custom-adaptor template.

As far as assertion libraries go, you can choose whatever you’d like by making a simple config change.

Tutorials

Debugging failing tests

Sometimes tests will give you a useful message explaining why they failed, but there are other times where they fail or hang without providing a clue of what is going on.

When you are having this issue the best way to debug the issue is to open the test in your favorite browser.

_images/image1.png

There is more happening on the browser than what we see at first glance. If you take a look at the DOM you will see an iframe with a src attribute something like /venus-core/sandbox/1, and this is where all the action happens. In there you can see all the libraries being loaded for your test, the file you are testing and the test code.

_images/image2.png

If you don’t see your script files being loaded, this is a good indicator that something is wrong with your test. This is an example of how the iframe looked on one test were I was triggering a redirect and by doing that breaking my tests:

_images/image3.png

Knowing this is also useful to find out why a test is failing or something is not working as expected. Since you now have access to your JS files from your developer tools you can set break points and go through the code step by step to figure out why something is failing.

_images/image4.png

Test execution environments

Local (Manual)

You can run a unit test with any browser you have installed locally on your machine

Below is an example of running tests.js locally:

$ venus run -t tests.js

PhantomJS

PhantomJS is a headless browser that Venus leverages to seamlessly run unit tests

The command line option -n or –phantom will specify the test to run with PhantomJS

Below is an example of running tests.js with PhantomJS:

$ venus run -t tests.js -n

Selenium Grid

Using Selenium, you can request a VM with a given browser to execute a unit test via Venus

The command line option -s or –selenium will specify the test to run with Selenium

Below is an example of running tests.js on a selenium grid hosted on example.selenium.com:

$ venus run -t tests.js -s example.selenium.com

Command line options:

  • -s, –selenium [server url]
  • –browser [browser|version]

Sauce Labs

Venus provides Sauce Labs integration so that you can run your tests remotely on their browser farms

The command line option –sauce-labs will specify the test to run with Sauce Labs

Run the following command to run your tests with Sauce Labs:

$ venus run -t tests.js --sauce-labs

Below is an example of running tests.js on a Sauce Labs with Firefox 20:

$ venus run -t tests.js --sauce-labs --browser "Firefox|20"

Command line options:

  • –sauce-labs [server url]
  • –browser [browser|version]
  • –platform [platform]
  • –username [username]
  • –access-key [accessKey]

Using different testing libraries

Venus simplifies running unit tests for JavaScript. To minimize overhead, we set out to create a tool that makes it easier to work with an existing test library such as Mocha, Jasmine or QUnit.

Mocha

Mocha is a feature-rich test framework that provides a wealth of features, not limited to, but including: async support, watching for slow tests, and integration with various assertion libraries. However, it doesn’t contain integration with any browsers (ex. WebKit). By simply adding Venus annotations, you can use Venus to run your tests using PhantomJS, while still being able to run them using the mocha CLI.

Let’s say you have this test file, tests.js:

describe('Array', function() {
  describe('#indexOf()', function() {
    it('should return -1 when the value is not present', function() {
      expect([1, 2, 3].indexOf(5)).to.be(-1);
      expect([1, 2, 3].indexOf(0)).to.be(-1);
    });
  });
});

In order to make tests.js runnable in Venus, modify your file as follows:

/**
 * @venus-library mocha
 * @venus-template sandbox
 */
describe('Array', function() {
  describe('#indexOf()', function() {
    it('should return -1 when the value is not present', function() {
      expect([1, 2, 3].indexOf(5)).to.be(-1);
      expect([1, 2, 3].indexOf(0)).to.be(-1);
    });
  });
});

NOTE: This file uses expect.js, but can be modified to use any assertion library supported by Mocha.

Now you can run your tests using Venus:

$ venus run -t tests.js -n

info:   Serving test: http://localhost:2013/venus-core/1
info:   executor started on localhost:2013
info:   Phantom browser is loading http://localhost:2013/venus-core/1

--------------------------------------------------------


PhantomJS/1.7.0

   Array >> #indexOf()
     ✓ should return -1 when the value is not present


✓ 1 test completed (0.01ms)

Jasmine

Jasmine is a behavior-driven development framework for testing JavaScript code. By default, it includes an HTML file that serves as a test runner. However, it doesn’t provide a command-line interface to run your unit tests. By simply adding Venus annotations, you can use Venus to run your tests both from the command line, while still preserving the ability to use the HTML test runner.

Let’s say you have this test file, tests.js:

describe('A suite', function() {
  it('contains spec with an expectation', function() {
    expect(true).toBe(true);
  });
});

In order to make tests.js runnable in Venus, modify your file as follows:

/**
 * @venus-library jasmine
 * @venus-template sandbox
 */
describe('A suite', function() {
  it('contains spec with an expectation', function() {
    expect(true).toBe(true);
  });
});

Now you can run your tests using Venus:

$ venus run -t tests.js -n

info:   Serving test: http://localhost:2013/venus-core/1
info:   executor started on localhost:2013
info:   Phantom browser is loading http://localhost:2013/venus-core/1

--------------------------------------------------------


PhantomJS/1.7.0

   A suite
     ✓ contains spec with an expectation


✓ 1 test completed (0ms)

QUnit

QUnit is a JavaScript unit test suite used by jQuery, jQuery UI, and jQuery Mobile. It provides a web page interface for running your unit tests. However, it doesn’t provide a command-line interface to run your unit tests. By simply adding Venus annotations, you can use Venus to run your tests both from the command line, while still preserving the ability to use the web page interface.

Let’s say you have this test file, tests.js:

test( "hello test", function() {
  ok( 1 == "1", "Passed!" );
});

In order to make tests.js runnable in Venus, modify your file as follows:

/**
 * @venus-library qunit
 * @venus-template sandbox
 */

test( "hello test", function() {
  ok( 1 == "1", "Passed!" );
});

Now you can run your tests using Venus:

$ venus run -t tests.js -n

info:   Serving test: http://localhost:2013/venus-core/1
info:   executor started on localhost:2013
info:   Phantom browser is loading http://localhost:2013/venus-core/1

--------------------------------------------------------


PhantomJS/1.7.0

   hello test
     ✓ Passed!


✓ 1 test completed (20ms)

Using fixtures

Why?

@venus-fixture imports HTML markup into your test page and gives you quick access to DOM nodes for testing your client side interactions. Importing HTML fixtures saves you the time otherwise spent stubbing or mocking the DOM or elements.

How?

Include the @venus-fixture directive in your venus annotation block. The argument passed to @venus-fixture is a file path, it’s relative to test file you’re annotating. An example of this directive is below:

@venus-fixture ../fixtures/exampleFixture.fixture.html

The full annotation block to may look like the following:

/**
 * @venus-library mocha
 * @venus-include ../lib/zepto.1.0.min.js
 * @venus-include ../src/Silence.js
 * @venus-fixture ../fixtures/exampleFixture.fixture.html
 */

When you run your test, the markup from exampleFixture.fixture.html will be available on your test page. The ability to test your DOM manipulations and callbacks to user interactions is now at your fingertips.

Examples

Example test directory structure:

// Example Test Folder Structure

|-simpleFixtureExample
  |-lib
    |-zepto.1.0.min.js
  |-specs
    |-exampleFixture.spec.js
  |-fixtures
    |-exampleFixture.fixture.html

The contents of our HTML fixture file exampleFixture.fixture.html:

<div id="example-fixture-container"></div>

Example test uses zepto to verify that our HTML fixture has been loaded on the page:

describe('Testing @venus-fixture', function() {
  it('Loads our html', function() {
    var length = $('#example-fixture-container').length;
    expect(length).to.be(1);
  });
});

Example test verifies that a callback was fired by a click event, and that the arguments passed contained a specific DOM id:

describe('Test event delegation target', function() {
  it('Click target should equal "example-fixture-container"', function() {
    var spy = sinon.spy();

    document.addEventListener('click', spy, true);
    $('#example-fixture-container').trigger('click');

    // Callback gets called once
    expect(spy.calledOnce).to.equal(true);
    // The expected element id was passed
    expect(spy.args[0][0].target.id).to.equal('example-fixture-container');
  });
});

VIM Integration

The venus.vim vim plugin allows you to easily run tests without leaving your editor. Supported commands:

  • :VenusRun – run current file in Venus.js in the PhantomJS environment

We recommend using a nice VIM package manager, such as vundle, to manage your vim plugins. It is also helpful to map the :VenusRun command to a shortcut key, such as F12. You can do this in your .vimrc very easily:

map <F12> :VenusRun<CR>

Reference

Annotations (@venus-*)

Venus allows you to use comment-based annotations to define configurations for your unit test:

@venus-library

Indicates the test library you wish to use. The test libraries that are currently supported are mocha, jasmine and qunit (Default library is Mocha)

@venus-include

JavaScript file to include with your unit test. Use a seperate @venus-include annotation for every file you wish to include. The path is relative to the location of your test file.

@venus-include-group

Includes the given include group. An include group is a set of JavaScript files to include, defined in the Venus config.

For example, let’s say we want to include a group named groupA, which will include fileA.js and fileB.js:

/**
 * @venus-include-group groupA
 */

But before we can actually use that annotation, we need to update our Venus config to define what files are included with groupA:

{
  libraries: {
    ...
  },

  // Include groups
  includes: {
    groupA: [
        'fileA.js',
        'fileB.js'
    ],
    groupB: [
      ...
    ]
  },
      ...
}

@venus-fixture

The location of the file that will include HTML on the test harness page. This is useful for including some DOM elements that your JavaScript control depends on, for example. The path is relative to the location of your test file.

@venus-template

The location of the file that will serve as your test harness page for your unit test (Default file is .venus/templates/default.tl)

Example:

/**
 * @venus-library mocha
 * @venus-include ../src/Greeter.js
 * @venus-fixture ../fixtures/Greeter.html
 * @venus-tempalte custom
 */

Command line flags

venus run

Run tests specified as an argument to the -t or –test option. When this command is executed, venus will look for a .venus config file in the current directory or otherwise traverse upwards until one is found. If no config file is found you will recieve an error.

Options:

-h, --help                        output usage information
-t, --test [tests]                Comma separated string of tests to run
-p, --port [port]                 port to run on
-n, --phantom [path to binary]    Use phantomJS client to run browser tests
-s, --selenium                    Use selenium client to run browser tests
-r, --selenium-server [url]       Specify selenium server to use
-b, --selenium-browser [browser]  Specify browser to use with selenium
-l, --locale [locale]             Specify locale to use
-v, --verbose                     Run in verbose mode
-d, --debug                       Run in debug mode
-c, --coverage                    Generate Code Coverage Report
--require-annotations             Ignore test files lacking Venus annotations (@venus-*)

Basic format:

venus run --test [path to folder containing tests or single test file] [options]

Usage (Run JavaScript tests found in a folder and its subfolders in phantomjs headless browser):

venus run -t myproject/containing/tests --phantom
venus init

Generates a .venus project folder, with a boilerplate config file

Options:

-h, --help             output usage information
-l, --locale [locale]  Specify locale to use
-v, --verbose          Run in verbose mode
-d, --debug            Run in debug mode

Usage:

venus init

Output:

|-.venus/
  |-config
  |-adaptors/
  |-templates/
  |-libraries/

Boilerplate .venus/config file:

// Configuration file for Venus
// All paths can be relative (to the location of this config file) or absolute
{
  default: {},
  libraries: {},
  binaries: {},
  static: {},
  includes: {},
  basePaths: {}
}

venus demo

Runs an example venus test using Mocha and PhantomJS

Example:

venus demo

Config files

The configuration file for Venus can be found in ./venus/config

In this file, you can define the following:

  • Default settings to use when running Venus
  • Files to include when using Mocha, Jasmine and QUnit
  • Path to PhantomJS binary

Development Guide

Build a custom adaptor

Background

Venus uses adaptors to communicate with different test libraries. Each adaptor normalizes the output of it’s respective framework in order for Venus to process the test results.

The libraries currently supported are:

All adaptors can be found in the adaptors folder under the root Venus application.

Inside adaptors, you will find a file named adaptor-template.js. This file serves as the base template for all adaptors.

Example

Let’s say we want to create an adaptor for a test framework named FooBar (library file is named foobar.js)

The first step is to place foobar.js in libraries.

Next, create a file named foobar.js and place it in adaptors.

The contents of foobar.js should do the following:

  1. Instantiate the adaptor function Adaptor() {};
  2. Inherit the adaptor template Adaptor.prototype = new AdaptorTemplate();
  3. Override the following methods, which are defined in adaptor-template.js, based on the FooBar test framework:
    • start()
    • getTestMessage()
    • getTestName()
    • getTestStatus()
    • getTestStackTrace()
    • getTotal()
    • getTotalFailed()
    • getTotalPassed()
    • getTotalRuntime()

Finally, define the configuration for FooBar in ./config:

foobar: {
  includes: [
    'libraries/foobar.js',
    'adaptors/adaptor-template.js',
    'adaptors/foobar-.js'
  ]
}

Now you can add the annotation @venus-library foobar at the top of any JS unit test to use the FooBar test library with your tests.