HTML and CSS Reference
In-Depth Information
2.2.1 Step 1: Write a Test
The first formal step of a test-driven development iteration is picking a feature to
implement, and writing a unit test for it. As we discussed in Chapter 1, Automated
Testing , a good unit test should be short and focus on a single behavior of a function/
method. A good rule of thumb to writing single behavior tests is to add as little code
as necessary to fail the test. Also, the new test should never duplicate assertions that
have already been found to work. If a test is exercising two or more aspects of the
system, we have either added more than the necessary amount of code to fail it, or
it is testing something that has already been tested.
Beware of tests that make assumptions on, or state expectations about the
implementation. Tests should describe the interface of whatever it is we are imple-
menting, and it should not be necessary to change them unless the interface itself
changes.
Assume we are implementing a String.prototype.trim method, i.e., a
method available on string objects that remove leading and trailing white-space.
A good first test for such a method could be to assert that leading white space is
removed, as shown in Listing 2.1.
Listing 2.1 Initial test for String.prototype.trim
testCase("String trim test", {
"test trim should remove leading white-space":
function () {
assert("should remove leading white-space",
"a string" === "
a string".trim());
}
});
Being pedantic about it, we could start even smaller by writing a test to ensure
strings have a trim method to begin with. This may seem silly, but given that
we are adding a global method (by altering a global object), there is a chance of
conflicts with third party code, and starting by asserting that typeof "".trim
== "function" will help us discover any problems when we run the test before
passing it.
Unit tests test that our code behaves in expected ways by feeding them known
input and asserting that the output is what we expect. “Input” in this sense is not
merely function arguments. Anything the function in question relies on, including
the global scope, certain state of certain objects, and so on constitute input. Likewise,
output is the sum of return values and changes in the global scope or surrounding
objects. Often input and output are divided into direct inputs and outputs, i.e.,
 
Search WWH ::




Custom Search