Name

TestBuilder - Back end for building test libraries

Synopsis

  var Test = new TestBuilder();

  function ok (test, description) {
      Test.ok(test, description);
  }

Description

TestBuilder provides the a building block upon which to write test libraries like TestSimple and TestMore that can work together.

Construction

TestBuilder

  var Test = new TestBuilder();
Returns a TestBuilder object representing the current state of the test.

Since you only run one test per program, there is one and only one TestBuilder object. No matter how many times you call new TestBuilder(), you'll get the same object. (This is called a singleton).

create

  var Test = TestBuilder.create();
Ok, so there can be more than one TestBuilder object and this is how you get it. You might use this instead of new TestBuilder() if you're testing a TestBuilder-based module.

reset

  Test.reset();
Reinitializes the TestBuilder singleton to its original state. Mostly useful for tests run in persistent environments where the same test might be run multiple times in the same process.

Setting up tests

These methods are for setting up tests and declaring how many there are. You usually only want to call one of these methods.

plan

  Test.plan('no_plan');
  Test.plan('skip_all', reason );
  Test.plan('tests', numTests );
A convenient way to set up your tests. Call this method and TestBuilder will print the appropriate headers and take the appropriate actions.

If you call plan(), don't call any of the other test setup methods.

expectedTests

    var max = Test.expectedTests();
    Test.expectedTests(max);
Gets/sets the number of tests we expect this test to run and prints out the appropriate headers.

noPlan

  Test.noPlan();
Declares that this test will run an indeterminate number tests.

hasPlan

  var plan = Test.hasPlan();
Find out whether a plan has been defined. plan is either null (no plan has been set) "no_plan" (indeterminate number of tests) or an integer (the number of expected tests).

Running tests

These methods actually run the tests. The description argument is always optional.

ok

  Test.ok(test, description);
Your basic test. Pass if test is true, fail if test is false. Returns a boolean indicating passage or failure.

isEq

  Test.isEq(got, expect, description);
Tests to see whether the stringified form of got is equivalent to the stringified form of expect.

isNum

  Test.isNum(got, expect, description);
Tests to see whether the numeric form of got is equivalent to the stringified form of expect.

isntEq

  Test.isntEq(got, dontExpect, description);
The opposite of isEq(). Tests to see whether the stringified form of got is not equivalent to the stringified form of dontExpect.

isntNum

  Test.isntNum(got, dontExpect, description);
The opposite of isNum(). Tests to see whether the numeric form of got is not equivalent to the stringified form of dontExpect.

like

  Test.like(got, /regex/, description);
  Test.like(got, 'regex', description);
Tests to see whether got matches the regular expression in regex. If a string is passed for the regex argument, it will be converted to a regular expression object for testing.

unlike

  Test.unlike(got, /regex/, description);
  Test.unlike(got, 'regex', description);
The opposite of unlike(). Tests to see whether got does not match the regular expression in regex. If a string is passed for the regex argument, it will be converted to a regular expression object for testing.

cmpOk

  Test.cmpOk(got, op, expect, description);
Performs a comparison of two values, got and expect. Specify any binary comparison operator as a string via the op argument. In addition to the usual JavaScript operators, cmpOk() also supports the Perl-style string comparison operators:

eq - String equal

ne - String not equal

lt - String less than

gt - String greater than

le - String less than or equal

ge - String greater than or equal

skip

    Test.skip();
    Test.skip(why);
Skips the current test, reporting why.

todoSkip

  Test.todoSkip();
  Test.todoSkip(why);
Like skip(), only it will declare the test as failing and TODO.

Test style

useNumbers

    Test.useNumbers(onOrOff);
Whether or not the test should output numbers. That is, this if true:

  ok 1
  ok 2
  ok 3
or this if false

  ok
  ok
  ok
Most useful when you can't depend on the test output order. TestHarness will accept either, but avoid mixing the two styles. Defaults to true.

noHeader

    Test.noHeader(noHeader);
If set to true, no "1..N" header will be printed.

noEnding

    Test.noEnding(noEnding);
Normally, TestBuilder does some extra diagnostics when the test ends. It also changes the exit code as described below. If this is true, none of that will be done.

Output

Controlling where the test output goes.

diag

    Test.diag(msg);
    Test.diag(msg, msg2, msg3);
Prints out all of its arguments. All arguments are simply appended together for output.

Output will be indented and marked with a "#" so as not to interfere with test output. A newline will be put on the end if there isn't one already.

We encourage using this method rather than outputting diagnostics directly.

Returns false. Why? Because diag() is often used in conjunction with a failing test (ok() || diag()) it "passes through" the failure.

    return ok(...) || diag(...);

Test Status and Info

currentTest

    var currTest = Test.currentTest();
    Test.currentTest(num);
Gets/sets the current test number we're on. You usually shouldn't have to set this property.

If set forward, the details of the missing tests are filled in as "unknown". if set backward, the details of the intervening tests are deleted. You can erase history if you really want to.

summary

    my @tests = Test.summary();
A simple summary of the tests so far returned as an array or boolean values, true for pass, false for fail. This is a logical pass/fail, so todos are passes.

Of course, test #1 is tests[0], etc...

details

    my @tests = Test.details();
Like summary(), but with a lot more detail.

  tests[testNum - 1] = {
      ok:        is the test considered a pass?
      actual_ok: did it literally say 'ok'?
      desc:      description of the test (if any)
      type:      type of test (if any, see below).
      reason:    reason for the above (if any)
  };
Sometimes the TestBuilder test counter is incremented without it printing any test output, for example, when currentTest() is changed. In these cases, TestBuilder doesn't know the result of the test, so it's type is "unknown". The details for these tests are filled in. They are considered ok, but the name and actual_ok is left null.

For example "not ok 23 - hole count # TODO insufficient donuts" would result in this structure:

  tests[22] = {          // 23 - 1, since arrays start from 0.
      ok:        1,      // logically, the test passed since it's todo
      actual_ok: 0,      // in absolute terms, it failed
      desc:      'hole count',
      type:      'todo',
      reason:    'insufficient donuts'
  };

Examples

CPAN can provide the best examples. TestSimple and TestMore both use TestBuilder.

See Also

TestSimple

Simple testing with a single testing function, ok(). Built with TestBuilder.

TestMore

Offers a panoply of test functions for your testing pleasure. Also built with TestBuilder.

http://www.edwardh.com/jsunit/

JSUnit: elaborate xUnit-style testing framework. Completely unrelated to TestBuilder.

ToDo

Authors

Original Perl code by chromatic and maintained by Michael G Schwern <schwern@pobox.com>. Ported to JavaScript by David Wheeler <david@kineticode.com>.

Copyright

Copyright 2002, 2004 by chromatic <chromatic@wgz.org> and Michael G Schwern <schwern@pobox.com>, 2005 by David Wheeler.

This program is free software; you can redistribute it and/or modify it under the terms of the Perl Artistic License or the GNU GPL.

See http://www.perl.com/perl/misc/Artistic.html and http://www.gnu.org/copyleft/gpl.html.