.. index:: Testing
CasperJS ships with its own :doc:`testing framework <modules/tester>`, providing a handful set of tools to ease testing your webapps.
Warning
.. versionchanged:: 1.1
The testing framework — hence its whole API — can only be used when using the casperjs test subcommand.
If you try to use the casper.test property out of the testing environment, you'll get an error.
.. index:: Unit testing
Imagine a dumb Cow object we want to unit test:
function Cow() {
this.mowed = false;
this.moo = function moo() {
this.mowed = true; // mootable state: don't do that at home
return 'moo!';
};
}
Let's write a tiny test suite for it:
// cow-test.js
casper.test.begin('Cow can moo', 2, function suite(test) {
var cow = new Cow();
test.assertEquals(cow.moo(), 'moo!');
test.assert(cow.mowed);
test.done();
});
Run the tests using the casperjs test command:
$ casperjs test cow-test.js
You should theoreticaly get something like this:
Make it fail:
casper.test.begin('Cow can moo', 2, function suite(test) {
var cow = new Cow();
test.assertEquals(cow.moo(), 'BAZINGA!');
test.assert(cow.mowed);
test.done();
});
You'll get this instead:
Hint
The whole tester module API is documented :doc:`here <modules/tester>`.
.. index:: Functional testing, Browser testing, Test suite
Now let's write a suite for testing google search (yes, you read it well):
// googletesting.js
casper.test.begin('Google search retrieves 10 or more results', 5, function suite(test) {
casper.start("http://www.google.fr/", function() {
test.assertTitle("Google", "google homepage title is the one expected");
test.assertExists('form[action="/search"]', "main form is found");
this.fill('form[action="/search"]', {
q: "casperjs"
}, true);
});
casper.then(function() {
test.assertTitle("casperjs - Recherche Google", "google title is ok");
test.assertUrlMatch(/q=casperjs/, "search term has been submitted");
test.assertEval(function() {
return __utils__.findAll("h3.r").length >= 10;
}, "google search for \"casperjs\" retrieves 10 or more results");
});
casper.run(function() {
test.done();
});
});
Now run the tests suite:
$ casperjs test googletesting.js
You'll probably get something like this:
The capserjs test command will treat every passed argument as file or directory paths containing tests. It will recursively scan any passed directory to search for *.js or *.coffee files and add them to the stack.
Warning
There are two important conditions when writing tests:
- You must not create a new
Casperinstance in a test file; - You must call
Tester.done()when all the tests contained in a suite (or in a file) have been executed.
Options are prefixed with a double-dash (--):
--xunit=<filename>will export test suite results in a :ref:`XUnit XML file <xunit_report>`--directwill print :doc:`log messages <logging>` directly to the console--log-level=<logLevel>sets the logging level (see the :doc:`related section <logging>`)
.. versionadded:: 1.0
--includes=foo.js,bar.jswill include thefoo.jsandbar.jsfiles before each test file execution;--pre=pre-test.jswill add the tests contained inpre-test.jsbefore executing the whole test suite;--post=post-test.jswill add the tests contained inpost-test.jsafter having executed the whole test suite;--fail-fastwill terminate the current test suite as soon as a first failure is encountered.
Sample custom command:
$ casperjs test --includes=foo.js,bar.js \
--pre=pre-test.js \
--post=post-test.js \
--direct \
--log-level=debug \
--fail-fast \
test1.js test2.js /path/to/some/test/dir
Hint
A demo gist is also available in order to get you started with a sample suite involving some of these options.
.. index:: XUnit, XML, Jenkins, Continuous Integration
CasperJS can export the results of the test suite to an XUnit XML file, which is compatible with continuous integration tools such as Jenkins. To save the XUnit log of your test suite, use the --xunit option:
$ casperjs test googletesting.js --save=log.xml
You should get a pretty XUnit XML report like this:
<?xml version="1.0" encoding="UTF-8"?>
<testsuites duration="1.249">
<testsuite errors="0" failures="0" name="Google search retrieves 10 or more results" package="googletesting" tests="5" time="1.249" timestamp="2012-12-30T21:27:26.320Z">
<testcase classname="googletesting" name="google homepage title is the one expected" time="0.813"/>
<testcase classname="googletesting" name="main form is found" time="0.002"/>
<testcase classname="googletesting" name="google title is ok" time="0.416"/>
<testcase classname="googletesting" name="search term has been submitted" time="0.017"/>
<testcase classname="googletesting" name="google search for "casperjs" retrieves 10 or more results" time="0.001"/>
<system-out/>
</testsuite>
</testsuites>CasperJS has its own unit and functional test suite, located in the tests subfolder. To run this test suite:
$ casperjs selftest
Note
Running this test suite is a great way to find any bug on your platform. If it fails, feel free to file an issue or to ask on the CasperJS mailing-list.
.. index:: extending
This command:
$ casperjs test [path]
is just a shortcut for this one:
$ casper /path/to/casperjs/tests/run.js [path]
So if you want to extend Casper capabilities for your tests, your best bet is to write your own runner and extend the casper object instance from there.
Hint
You can find the default runner code in run.js.


