Using Test Cases

nzakas edited this page Nov 23, 2011 · 3 revisions

The basis of YUI Test is the YUITest.TestCase object. A TestCase object is created by using the YUITest.TestCase constructor and passing in an object containing methods and other information with which to initialize the test case. Typically, the argument is an object literal, for example:

var testCase = new YUITest.TestCase({

    name: "TestCase Name",
    
    //traditional test names
    testSomething : function () {
        //...
    },

    testSomethingElse : function () {
        //...
    }
});

In this example, a simple test case is created named "TestCase Name". The name property is automatically applied to the test case so that it can be distinguished from other test cases that may be run during the same cycle. The two methods in this example are tests methods ( testSomething() and testSomethingElse()), which means that they are methods designed to test a specific piece of functional code. Test methods are indicatd by their name, either using the traditional manner of prepending the word test to the method name, or using a "friendly name," which is a sentence containing the word "should" that describes the test's purpose. For example:

var testCase = new YUITest.TestCase({

    name: "TestCase Name",
    
    //friendly test names
    "Something should happen here" : function () {
        //...
    },

    "Something else should happen here" : function () {
        //...
    }
});

Regardless of the naming convention used for test names, each should contain one or more assertions that test data for validity.

setUp() and tearDown()

As each test method is called, it may be necessary to setup information before it's run and then potentially clean up that information after the test is run. The setUp() method is run before each and every test in the test case and likewise the tearDown() method is run after each test is run. These methods should be used in conjunction to create objects before a test is run and free up memory after the test is run. For example:

var testCase = new YUITest.TestCase({

    name: "TestCase Name",
    
    //---------------------------------------------
    // Setup and tear down
    //---------------------------------------------
    
    setUp : function () {
        this.data = { name : "Nicholas", age : 28 };
    },

    tearDown : function () {
        delete this.data;
    },

    //---------------------------------------------
    // Tests
    //---------------------------------------------

    testName: function () {
        YUITest.Assert.areEqual("Nicholas", this.data.name, "Name should be 'Nicholas'");
    },

    testAge: function () {
        YUITest.Assert.areEqual(28, this.data.age, "Age should be 28");
    }    
});

In this example, a setUp() method creates a data object with some basic information. Each property of the data object is checked with a different test, testName() tests the value of data.name while testAge() tests the value of data.age. Afterwards, the data object is deleted to free up the memory. Real-world implementations will have more complex tests, of course, but they should follow the basic pattern you see in the above code.

**Note: **Both setUp() and tearDown() are optional methods and are only used when defined.

init() and destroy()

Sometimes you may need to initialize some data before all tests are run in a single test case. The init() method is run once before the tests start to run (also before the first call to setUp(). Likewise, the destroy() method is run just once after every test has been executed (and after the last tearDown() call). For example:

var testCase = new YUITest.TestCase({

    name: "TestCase Name",
    
    //---------------------------------------------
    // init and destroy
    //---------------------------------------------
    
    init : function () {
        this.data = { name : "Nicholas", age : 28 };
    },

    destroy : function () {
        delete this.data;
    },

    //---------------------------------------------
    // Tests
    //---------------------------------------------

    testName: function () {
        YUITest.Assert.areEqual("Nicholas", this.data.name, "Name should be 'Nicholas'");
    },

    testAge: function () {
        YUITest.Assert.areEqual(28, this.data.age, "Age should be 28");
    }    
});

In this example, a init() method creates a data object with some basic information. Each property of the data object is checked with a different test, testName() tests the value of data.name while testAge() tests the value of data.age. Afterwards, the data object is deleted to free up the memory using destroy(). Unlike the previous example using setUp() and tearDown(), both tests are running on the same object.

**Note: **Both init() and destroy() are optional methods and are only used when defined. You can use init() and destroy() together with setUp() and tearDown() for maximum amount of control over test data.

Ignoring Tests

There may be times when you want to ignore a test (perhaps the test is invalid for your purposes or the functionality is being re-engineered and so it shouldn't be tested at this time). To specify tests to ignore, use the ignore: annotation at the beginning of the test name. This works regardless of the naming convention of the test:

var testCase = new YUITest.TestCase({

    name: "TestCase Name",
    
    //---------------------------------------------
    // Setup and tear down
    //---------------------------------------------

    setUp : function () {
        this.data = { name : "Nicholas", age : 28 };
    },
    
    tearDown : function () {
        delete this.data;
    },
  
    //---------------------------------------------
    // Tests
    //---------------------------------------------        

    //this test will be ignored
    "ignore:testName": function () {
        YUITest.Assert.areEqual("Nicholas", this.data.name, "Name should be 'Nicholas'");
    },

    //this test will not be ignored
    testAge: function () {
        YUITest.Assert.areEqual(28, this.data.age, "Age should be 28");
    },

    //this test will be ignored
    "ignore:This test should pass": function(){
        YUITest.Assert.areEqual(28, this.data.age, "Age should be 28");
    }

});

Here the ignore:testName() method will be ignored when the test case is run. This is accomplished simply by using the ignore: annotation at the beginning of the test name. The method "ignore:This test should pass" will also be ignored due to the annotation being used.