brew install node
brew install phantomjs
npm install -g venus
venus demo
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
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)
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.
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.
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.
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:
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.
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 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
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:
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:
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 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 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 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)
@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.
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.
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');
});
});
The venus.vim vim plugin allows you to easily run tests without leaving your editor. Supported commands:
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>
Venus allows you to use comment-based annotations to define configurations for your unit test:
Indicates the test library you wish to use. The test libraries that are currently supported are mocha, jasmine and qunit (Default library is Mocha)
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.
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: [
...
]
},
...
}
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.
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
*/
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
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: {}
}
The configuration file for Venus can be found in ./venus/config
In this file, you can define the following:
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.
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:
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.