Assertions

nzakas edited this page Nov 23, 2011 · 1 revision

Test methods use assertions to check the validity of a particular action or function. An assertion method tests (asserts) that a condition is valid; if not, it throws an error that causes the test to fail. If all assertions pass within a test method, it is said that the test has passed. The simplest assertion is YUITest.Assert(), which takes two arguments: a condition to test and a message. If the condition is not true, then an assertion error is thrown with the specified message. For example:

var testCase = new YUITest.TestCase({

    name: "TestCase Name",
    
    testUsingAsserts : function () {                            
        YUITest.Assert(value == 5, "The value should be five.");
        YUITest.Assert(flag, "Flag should be true.");
    }
});

In this example, testUsingAsserts() will fail if value is not equal to 5 of flag is not set to true. The YUITest.Assert() method may be all that you need, but there are advanced options available. The YUITest.Assert object contains several assertion methods that can be used to validate data.

Equality Assertions

The simplest assertions are areEqual() and areNotEqual(). Both methods accept three arguments: the expected value, the actual value, and an optional failure message (a default one is generated if this argument is omitted). For example:

var testCase = new YUITest.TestCase({

    name: "TestCase Name",
    
    testEqualityAsserts : function () {
        
        YUITest.Assert.areEqual(5, 5);     //passes
        YUITest.Assert.areEqual(5, "5");     //passes
        YUITest.Assert.areNotEqual(5, 6);  //passes
        YUITest.Assert.areEqual(5, 6, "Five was expected."); //fails
    }
});

These methods use the double equals (==) operator to determine if two values are equal, so type coercion may occur. This means that the string "5" and the number 5 are considered equal because the double equals sign converts the number to a string before doing the comparison. If you don't want values to be converted for comparison purposes, use the sameness assertions instead.

Sameness Assertions

The sameness assertions are areSame() and areNotSame(), and these accept the same three arguments as the equality assertions: the expected value, the actual value, and an optional failure message. Unlike the equality assertions, these methods use the triple equals operator (===) for comparisions, assuring that no type coercion will occur. For example:

var testCase = new YUITest.TestCase({

    name: "TestCase Name",
    
    testSamenessAsserts : function () {
        YUITest.Assert.areSame(5, 5);      //passes
        YUITest.Assert.areSame(5, "5");    //fails
        YUITest.Assert.areNotSame(5, 6);   //passes
        YUITest.Assert.areNotSame(5, "5"); //passes
        YUITest.Assert.areSame(5, 6, "Five was expected."); //fails
    }
});

**Note: **Even though this example shows multiple assertions failing, a test will stop as soon as one assertion fails, causing all others to be skipped.

Data Type Assertions

There may be times when some data should be of a particular type. To aid in this case, there are several methods that test the data type of variables. Each of these methods accepts two arguments: the data to test and an optional failure message. The data type assertions are as follows:

  • isArray() - passes only if the value is an instance of Array.
  • isBoolean() - passes only if the value is a Boolean.
  • isFunction() - passes only if the value is a function.
  • isNumber() - passes only if the value is a number.
  • isObject() - passes only if the value is an object or a function.
  • isString() - passes only if the value is a string.

These are used as in the following example:

var testCase = new YUITest.TestCase({

    name: "TestCase Name",
    
    testDataTypeAsserts : function () {            
        YUITest.Assert.isString("Hello world");     //passes
        YUITest.Assert.isNumber(1);                 //passes
        YUITest.Assert.isArray([]);                 //passes
        YUITest.Assert.isObject([]);                //passes
        YUITest.Assert.isFunction(function(){});    //passes
        YUITest.Assert.isBoolean(true);             //passes
        YUITest.Assert.isObject(function(){});      //passes

        YUITest.Assert.isNumber("1", "Value should be a number.");  //fails
        YUITest.Assert.isString(1, "Value should be a string.");    //fails
    }
});

In addition to these specific data type assertions, there are two generic data type assertions. The isTypeOf() method tests the string returned when the typeof operator is applied to a value. This method accepts three arguments: the type that the value should be ("string", "number", "boolean", "undefined", "object", or "function"), the value to test, and an optional failure message. For example:

var testCase = new YUITest.TestCase({

    name: "TestCase Name",
    
    testTypeOf : function () {
        
        YUITest.Assert.isTypeOf("string", "Hello world");   //passes
        YUITest.Assert.isTypeOf("number", 1);               //passes
        YUITest.Assert.isTypeOf("boolean", true);           //passes
        YUITest.Assert.isTypeOf("number", 1.5);             //passes
        YUITest.Assert.isTypeOf("function", function(){});  //passes
        YUITest.Assert.isTypeOf("object", {});              //passes
        YUITest.Assert.isTypeOf("undefined", this.blah);    //passes
        
        YUITest.Assert.isTypeOf("number", "Hello world", "Value should be a number."); //fails
        
    }
});

If you need to test object types instead of simple data types, you can also use the isInstanceOf() assertion, which accepts three arguments: the constructor function to test for, the value to test, and an optional failure message. This assertion uses the instanceof operator to determine if it should pass or fail. Example:

var testCase = new YUITest.TestCase({

    name: "TestCase Name",
    
    testInstanceOf : function () {
        YUITest.Assert.isInstanceOf(Object, {});    //passes
        YUITest.Assert.isInstanceOf(Array, []);     //passes            
        YUITest.Assert.isInstanceOf(Object, []);     //passes            
        YUITest.Assert.isInstanceOf(Function, function(){});  //passes
        YUITest.Assert.isInstanceOf(Object, function(){});  //passes
        
        YUITest.Assert.isTypeOf(Array, {}, "Value should be an array."); //fails
        
    }
});

Special Value Assertions

There are numerous special values in JavaScript that may occur in code. These include true, false, NaN, null, and undefined. There are a number of assertions designed to test for these values specifically:

  • isFalse() - passes if the value is false.
  • isTrue() - passes if the value is true.
  • isNaN() - passes if the value is NaN.
  • isNotNaN() - passes if the value is not NaN.
  • isNull() - passes if the value is null.
  • isNotNull() - passes if the value is not null.
  • isUndefined() - passes if the value is undefined.
  • isNotUndefined() - passes if the value is not undefined.

Each of these methods accepts two arguments: the value to test and an optional failure message. All of the assertions expect the exact value (no type cohersion occurs), so for example calling isFalse(0) will fail.

var testCase = new YUITest.TestCase({

    name: "TestCase Name",
    
    testSpecialValues : function () {                            
        YUITest.Assert.isFalse(false);      //passes
        YUITest.Assert.isTrue(true);        //passes            
        YUITest.Assert.isNaN(NaN);          //passes            
        YUITest.Assert.isNaN(5 / "5");      //passes
        YUITest.Assert.isNotNaN(5);         //passes
        YUITest.Assert.isNull(null);        //passes
        YUITest.Assert.isNotNull(undefined);    //passes
        YUITest.Assert.isUndefined(undefined);  //passes
        YUITest.Assert.isNotUndefined(null);    //passes
        
        YUITest.Assert.isUndefined({}, "Value should be undefined."); //fails
        
    }
});

Forced Failures

While most tests fail as a result of an assertion, there may be times when you want to force a test to fail or create your own assertion method. To do this, use the fail() method to force a test method to fail immediately:

var testCase = new YUITest.TestCase({

    name: "TestCase Name",
    
    testForceFail : function () {
        YUITest.Assert.fail();  //causes the test to fail
    }
});

In this case, the testForceFail() method does nothing but force the method to fail. Optionally, you can pass in a message to fail() which will be displayed as the failure message:

var testCase = new YUITest.TestCase({

    name: "TestCase Name",
    
    testForceFail : function () {
        YUITest.Assert.fail("I decided this should fail.");
    }
});

When the failure of this method is reported, the message "I decided this should fail." will be reported.

Forced Pass

All tests fail by default if there are no assertions (a test without an assertion is probably an error), however, there may be times when you want to indicate that the test should pass. In that case, use the pass() method to tell YUI Test that the test has passed:

var testCase = new YUITest.TestCase({

    name: "TestCase Name",
    
    testForcePass: function () {
        YUITest.Assert.pass();  //causes the test to pass even though there are no assertions
    }
});

In this case, the testForcePass() method does nothing but force the method to pass.