# Testing

CasperJS ships with its own testing framework, providing a handful set of tools to ease testing your webapps.

Warning

Changed in version 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;
- As of 1.1-beta3, you can’t override the preconfigured `casper` instance in this test environment. You can read more about the whys in the dedicated FAQ entry.

## 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 theoretically 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 here.

## Browser tests

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:

## Setting Casper options in the test environment

As you must use a preconfigured `casper` instance within the test environment, updating its options can be achieved this way:

    casper.options.optionName = optionValue; // where optionName is obviously the desired option name

    casper.options.clientScripts.push("new-script.js");

## Advanced techniques

The Tester#begin() accepts either a function or an object to describe a suite; the object option allows to set up `setUp()` and `tearDown()` functions:

    // cow-test.js
    casper.test.begin('Cow can moo', 2, {
        setUp: function(test) {
            this.cow = new Cow();
        },

        tearDown: function(test) {
            this.cow.destroy();
        },

        test: function(test) {
            test.assertEquals(this.cow.moo(), 'moo!');
            test.assert(this.cow.mowed);
            test.done();
        }
    });

## Test command args and options

### Arguments

The `casperjs 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 `Casper` instance 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

Options are prefixed with a double-dash (`--`):

- `--xunit=<filename>` will export test suite results in a XUnit XML file

- `--direct` or `--verbose` will print log messages directly to the console

- `--log-level=<logLevel>` sets the logging level (see the related section)

- `--auto-exit=no` prevents the test runner to exit when all the tests have been executed; this usually allows performing supplementary operations, though implies to exit casper manually listening to the `exit` tester event:

      // $ casperjs test --auto-exit=no
      casper.test.on("exit", function() {
        someTediousAsyncProcess(function() {
          casper.exit();
        });
      });

New in version 1.0.

- `--includes=foo.js,bar.js` will include the `foo.js` and `bar.js` files before each test file execution.
- `--pre=pre-test.js` will add the tests contained in `pre-test.js` before executing the whole test suite.
- `--post=post-test.js` will add the tests contained in `post-test.js` after having executed the whole test suite.
- `--fail-fast` will terminate the current test suite as soon as a first failure is encountered.
- `--concise` will create a more concise output of the test suite.
- `--no-colors` will create an output without (beautiful) colors from casperjs.

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

Warning

Deprecated since version 1.1.

`--direct` option has been renamed to `--verbose`, though `--direct` will still works, while is to be considered deprecated.

Hint

A demo gist is also available in order to get you started with a sample suite involving some of these options.

## Exporting results in XUnit format

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 --xunit=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 &quot;casperjs&quot; retrieves 10 or more results" time="0.001"/>
            <system-out/>
        </testsuite>
    </testsuites>

You can customize the value for the name property by passing an object to casper.test.fail() like:

    casper.test.fail('google search for "casperjs" retrieves 10 or more results', {name: 'result count is 10+'});

    <?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="results count is 10+" time="0.001"/>
                <failure type="fail">google search for "casperjs" retrieves 10 or more results</failure>
            <system-out/>
        </testsuite>
    </testsuites>

## CasperJS own tests

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.

## Extending Casper for Testing

This command:

    $ casperjs test [path]

is just a shortcut for this one:

    $ casperjs /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.