Running Tests

nzakas edited this page Nov 23, 2011 · 1 revision

In order to run test cases and test suites, use the YUITest.TestRunner object. This object is a singleton that simply runs all of the tests in test cases and suites, reporting back on passes and failures. To determine which test cases/suites will be run, add them to the YUITest.TestRunner using the add() method. Then, to run the tests, call the run() method:

//add the test cases and suites
YUITest.TestRunner.add(testCase);
YUITest.TestRunner.add(testSuite);

//run all tests
YUITest.TestRunner.run();

If at some point you decide not to run the tests that have already been added to the TestRunner, they can be removed by calling clear():

YUITest.TestRunner.clear();

Making this call removes all test cases and test suites that were added using the add() method.

TestRunner Events

The YUITest.TestRunner provides results and information about the process by publishing several events. These events can occur at four different points of interest: at the test level, at the test case level, at the test suite level, and at the YUITest.TestRunner level. The data available for each event depends completely on the type of event and the level at which the event occurs.

Test-Level Events

Test-level events occur during the execution of specific test methods. There are three test-level events:

  • YUITest.TestRunner.TEST_PASS_EVENT - occurs when the test passes.
  • YUITest.TestRunner.TEST_FAIL_EVENT - occurs when the test fails.
  • YUITest.TestRunner.TEST_IGNORE_EVENT - occurs when a test is ignored.

For each of these events, the event data object has three properties:

  • type - indicates the type of event that occurred.
  • testCase - the test case that is currently being run.
  • testName - the name of the test that was just executed or ignored.

For YUITest.TestRunner.TEST_FAIL_EVENT, an error property containing the error object that caused the test to fail.

TestCase-Level Events

There are two events that occur at the test case level:

  • YUITest.TestRunner.TEST_CASE_BEGIN_EVENT - occurs when the test case is next to be executed but before the first test is run.
  • YUITest.TestRunner.TEST_CASE_COMPLETE_EVENT - occurs when all tests in the test case have been executed or ignored.

For these two events, the event data object has three properties:

  • type - indicates the type of event that occurred.
  • testCase - the test case that is currently being run.

For TEST_CASE_COMPLETE_EVENT, an additional property called results is included. The results property is an object containing the aggregated results for all tests in the test case (it does not include information about tests that were ignored). Each test that was run has an entry in the result object where the property name is the name of the test method and the value is an object with two properties: result, which is either "pass" or "fail", and message, which is a text description of the result (simply "Test passed" when a test passed or the error message when a test fails). Additionally, the failed property indicates the number of tests that failed in the test case, the passed property indicates the number of tests that passed, and the total property indicates the total number of tests executed. A typical results object looks like this:

{
    failed: 1,
    passed: 1,
    ignored: 0,
    total: 2,
    type: "testcase",
    name: "Test Case 0",

    test0: {
        result: "pass",
        message: "Test passed",
        type: "test",
        name: "test0"
    },

    test1: {
        result: "fail",
        message: "Assertion failed",
        type: "test",
        name: "test1"
    }
}

The TEST_CASE_COMPLETE_EVENT provides this information for transparency into the testing process.

TestSuite-Level Events

There are two events that occur at the test suite level:

  • YUITest.TestRunner.TEST_SUITE_BEGIN_EVENT - occurs when the test suite is next to be executed but before the first test is run.
  • YUITest.TestRunner.TEST_SUITE_COMPLETE_EVENT - occurs when all tests in all test cases in the test suite have been executed or ignored.

For these two events, the event data object has three properties:

  • type - indicates the type of event that occurred.
  • testSuite - the test suite that is currently being run.

The TEST_SUITE_COMPLETE_EVENT also has a results property, which contains aggregated results for all of the test cases (and other test suites) it contains. Each test case and test suite contained within the main suite has an entry in the results object, forming a hierarchical structure of data. A typical results object may look like this:

{    
    failed: 2,
    passed: 2,
    ignored: 0,
    total: 4,
    type: "testsuite",
    name: "Test Suite 0",

    testCase0: {
        failed: 1,
        passed: 1,
        ignored: 0,
        total: 2,
        type: "testcase",
        name: "testCase0",

        test0: {
            result: "pass",
            message: "Test passed."
            type: "test",
            name: "test0"
        },            
        test1: {
            result: "fail",
            message: "Assertion failed.",
            type: "test",
            name: "test1"
        }
    },
    testCase1: {
        failed: 1,
        passed: 1,
        ignored: 0,
        total: 2,
        type: "testcase",
        name: "testCase1",

        test0: {
            result: "pass",
            message: "Test passed.",
            type: "test",
            name: "test0"
        },            
        test1: {
            result: "fail",
            message: "Assertion failed.",
            type: "test",
            name: "test1"
        }
    }
}   

This example shows the results for a test suite with two test cases, but there may be test suites contained within test suites. In that case, the hierarchy is built out accordingly, for example:

{
    failed: 3,
    passed: 3,
    ignored: 0,
    total: 6,
    type: "testsuite",
    name: "Test Suite 0",

    testCase0: {
        failed: 1,
        passed: 1,
        ignored: 0,
        total: 2,
        type: "testcase",
        name: "testCase0",

        test0: {
            result: "pass",
            message: "Test passed.",
            type: "test",
            name: "test0"                
        },            
        test1: {
            result: "fail",
            message: "Assertion failed.",
            type: "test",
            name: "test1"                
        }
    },

    testCase1: {
        failed: 1,
        passed: 1,
        ignored: 0,
        total: 2,
        type: "testcase",
        name: "testCase1",

        test0: {
            result: "pass",
            message: "Test passed.",
            type: "test",
            name: "test0"                
        },            
        test1: {
            result: "fail",
            message: "Assertion failed.",
            type: "test",
            name: "test1"                
        }
    },

    testSuite0:{
        failed: 1,
        passed: 1,
        ignored: 0,
        total: 2,
        type: "testsuite",
        name: "testSuite0",        

        testCase2: {
            failed: 1,
            passed: 1,
            ignored: 0,
            total: 2,
            type: "testcase",
            name: "testCase2",

            test0: {
                result: "pass",
                message: "Test passed.",
                type: "test",
                name: "test0"
            },   

            test1: {
                result: "fail",
                message: "Assertion failed.",
                type: "test",
                name: "test1"
            }
        }
    }
} 

In this code, the test suite contained another test suite named "testSuite0", which is included in the results along with its test cases. At each level, the results are aggregated so that you can tell how many tests passed or failed within each test case or test suite.

TestRunner-Level Events

There are two events that occur at the YUITest.TestRunner level:

  • YUITest.TestRunner.BEGIN_EVENT - occurs when testing is about to begin but before any tests are run.
  • YUITest.TestRunner.COMPLETE_EVENT - occurs when all tests in all test cases and test suites have been executed or ignored.

The data object for these events contain a type property, indicating the type of event that occurred. COMPLETE_EVENT also includes a results property that is formatted the same as the data returned from TEST_SUITE_COMPLETE_EVENT and contains rollup information for all test cases and tests suites that were added to the TestRunner.

Subscribing to Events

You can subscribe to particular events by calling the subscribe() method. Your event handler code should expect a single object to be passed in as an argument. This object provides information about the event that just occured. Minimally, the object has a type property that tells you which type of event occurred. Example:

function handleTestFail(data){
    alert("Test named '" + data.testName + "' failed with message: '" + data.error.message + "'.");
}

var TestRunner = YUITest.TestRunner;
TestRunner.subscribe(TestRunner.TEST_FAIL_EVENT, handleTestFail);
TestRunner.run();

In this code, the handleTestFail() function is assigned as an event handler for TEST_FAIL_EVENT. You can also use a single event handler to subscribe to any number of events, using the event data object's type property to determine what to do:

function handleTestResult(data){
    var TestRunner = YUITest.TestRunner;

    switch(data.type) {
        case TestRunner.TEST_FAIL_EVENT:
            alert("Test named '" + data.testName + "' failed with message: '" + data.error.message + "'.");
            break;
        case TestRunner.TEST_PASS_EVENT:
            alert("Test named '" + data.testName + "' passed.");
            break;
        case TestRunner.TEST_IGNORE_EVENT:
            alert("Test named '" + data.testName + "' was ignored.");
            break;
    }

}

TestRunner.subscribe(TestRunner.TEST_FAIL_EVENT, handleTestResult);
TestRunner.subscribe(TestRunner.TEST_IGNORE_EVENT, handleTestResult);
TestRunner.subscribe(TestRunner.TEST_PASS_EVENT, handleTestResult);
TestRunner.run();

Viewing Results

There are two ways to view test results. The first is to output test results to a YUI Console component. To do so, you need only create a new Console instance; the result results will be posted to the logger automatically:

YUI({ logInclude: { TestRunner: true } }).use("console", function(Y){

    //tests go here

    //initialize the console
    var yconsole = new Y.Console({
        newestOnTop: false                   
    });
    yconsole.render('#log');

    //run the tests
    YUITest.TestRunner.run();
});