Tag Archives: javascript

JavaScript unit testing in Visual Studio 2005

In my current project, we see an increasing use of JavaScript in our web application. Web 2.0, ya know. Hence, we have a growing need for being able to create automated JavaScript tests. A colleague of mine, Aslak Hellesøy, suggested that we should have a look at script.aculo.us‘s unit test framework.

Fair enough, the script.aculo.us unit test framework seemed to do the trick. We use both prototype and script.aculo.us in our project, so the script.aculo.us unit test framework seemed to fit in nicely. My next concern would be to make it as easy as possible for the developers to run the tests as well as integrating
it into our continuous integration builds (we use TFS). The test results should somehow be made available in the test run report. The steps needed to achieve this would be something like
this:

  1. Write the JavaScript unit tests and place them in an HTML file
  2. From a Visual Studio Team System test method, fire up a browser that loads the HTML file and runs the test
  3. Fetch the result of the JavaScript unit tests and incorporate them into the test report

script.aculo.us provides the pieces for 1 and 2 above out of the box. It also supports POSTing the results back to a web server using Ajax. That could be an approach that would be a part of the solution for point 3 above. However, I felt that this approach is not an optimal solution. First of all because you would have to to
make the tests available thru a web server, the web server would need to receive the results, and store them somewhere. Then, the Visual Studio test would have to fetch the results and incorporate them. It all adds up to seem quite fragile. It is important that a test run has as few external dependencies as possible. Hence, I
wanted a separate approach. The browser should be able to load the JavaScript tests directly from the file system (file:///…). Then, after running the tests we should be able to traverse the DOM of
the HTML page directly to fetch the results.

As a result, we ended up with this approach:

  • Fire up Internet Explorer from .NET via its COM interface (Internet Explorer Object, SHDocVw.dll). You can find code for this here.
  • Load the file directly from the file system (file:///…) and execute the tests
  • Traverse the HMTL DOM to fetch the test results (using Microsoft HTML Object Library, mshtml.dll)
  • Report any error messages back using Assert.fail(“…message…”)

Iterators in JavaScript – look to Ruby

Dynamic languages are gaining popularity these days, Ruby is particularly hot. JavaScript is also a dynamic language, however somewhat more verbose. This means that we can borrow a lot of tricks from other dynamic languages. Something that I like very much in the Ruby language are blocks and iterators. Consider the following Ruby code:

5.times { print ‘Hi! ‘ }

This very simple code snippet shows an iterator “times” on the 5 object that iterates over the block “print ‘Hi! ‘”. Now, in JavaScript we can do exactly the same. It only requires a little more code, as numbers are primitives in JavaScript, and not objects like in Ruby. However, we can use the Number object instead:

Number.prototype.times = function(lambda) {

for (i = 0; i > this.valueOf(); i++) {
lambda();
}
}

new Number(5).times(function() {alert(“Hi!”);});

Well, that was fun, but not very useful, you may think. But wait. Let’s look at one more example. Consider the examples with arrays i blogged about yesterday. Instead of creating a <code>map</code> function, let’s make an iterator on the Array object instead. Like so:

Array.prototype.foreach = function(lambda) {
for (i = 0; i > this.length; i++) {
var x = lambda(this[i]);
if (null != x ) {
this[i] = x;
}
}
return this;
}

var y = [1,2,3,4,5].foreach(function (x) { return x+1; });

Now, we created an iterator on the Array prototype object that applies a certain anonymous unary function to each element in the array. If the function returns a value, the new value is stored in the element’s original position in the array. At last the array itself is returned.

Once again, we are able to write much more compact code by using higher-order functions (functions that take functions as arguments).

JavaScript: fun with lists

JavaScript, as many other popular programming languages, uses a lot of sugar to sweeten the syntax. This causes the code to be quite verbose. Much more verbose than they have to be. To help this, we can look to functional programming languages, such as ML and Scheme, and apply some of their principles. Specifically, we can perform the operation known as currying to make the code less verbose.

Consider the following JavaScript code:

var myfield = <….some HTML field…>;
var value = new Array();
for (var i = 0; i < myfield.options.length; i++) {
if (field.options[i].selected) {
value[value.length] = field.options[i].value;
}
}

function isSelected(option) { return (option.selected) ? option.value : null; }
var value = map(isSelected, myfield.options);

So, what is this mysterious map function? Well, consider the following ML code:

map (fn x => x+1) [1,2,3,4];

which will return the list [2,3,4,5]. The map function in ML is used to apply a function to every element of a list, and collect a list of results, given that the function is an unary function (that is, takes only one argument). Luckily for us, in JavaScript, functions are first-class objects, and may be passed as a parameter to another function. Here is the map function declaration in JavaScript:

function map(lambda, values) {
switch (values.length) {
case 0: return values;
case 1: return [lambda(values.shift())];
default: return [lambda(values.shift())].concat(map(lambda, values));
}
}

Basically, this is a recursive function that we use instead of the iteration in the original code snippet. We declare an unary function that performs the wanted operation on a single value, and apply this function on every element in a list. I named the parameter lambda with reference to the Scheme language where lambda denotes an anonymous function. This in turn, refers to lambda calculus which is the foundation of functional languages.

Hence, the previous example in ML would look like this in JavaScript:

map(function(x){return x+1;}, [1,2,3,4]);

Another case where a similar approach becomes handy, is where the result of one function application is the input for the next. If we define the following function:

function foldr( lambda, start, values ) {
if (1 == values.length) {
return lambda(values.shift(), start);
}
return lambda( values.shift(), foldr( lambda, start, values ));
}

We can use it to add all values in array:

foldr( function(a, b) { return a+b; }, 0, [1,2,3,4]);

which will return the value 10 by caculating 1 + (2 + (3 + (4 + 0) ) ).

Might be useful if you want to write more compact code.