Tales from the Evil Empire

Bertrand Le Roy's blog

News


Bertrand Le Roy

BoudinFatal's Gamercard

Tales from the Evil Empire - Blogged

Blogs I read

My other stuff

Archives

December 2008 - Posts

Why are scripts slow to load in Firefox when using Visual Studio’s built-in development Web server (a.k.a. Cassini)?

If you’ve been doing some script development in Visual Studio and Firebug, you may have experienced something like this:
Slow script loading with Firefox and Cassini

Notice how all resources take more than a second to load? Loading of scripts being sequential doesn’t help either.

And of course, the more scripts you have on the page, the worse it gets. I’ve seen fairly simple pages take around 15 seconds to load because of this bug.

I’m not quite sure where that bug comes from, but the good news is I have two solutions for you. First, you can configure Visual Studio to use IIS (when you do “new web site”, choose HTTP as the location, then “local IIS”). But the easiest is just to replace “localhost” in the browser address bar with “127.0.0.1”. Here’s the performance of the same page as above, using that address:
FastFFCassini

From 6 seconds down to 215 milliseconds. Not bad, eh? Multiply this by the number of times you load pages in this configuration during a typical work day and you’ve got what I think is a pretty useful trick ;) Of course, not having this bug in the first place would be ideal…

I hope this helps.

UPDATE: Dan Wahlin has an explanation for this, which is an issue with DNS and IPv6 support in Firefox. An alternate workaround is to disable IPv6 in Firefox. Thanks to Marc for pointing me to this post.
http://weblogs.asp.net/dwahlin/archive/2007/06/17/fixing-firefox-slowness-with-localhost-on-vista.aspx

Wally’s introduction to 3.5 SP1

Wally McClure, MVP extraordinaire and ASP Insider, just published a short book about the new features in ASP.NET 3.5 SP1. It is a short and to the point read that should get you started in no time. I wouldn’t have shown web service access as the main advantage of jQuery myself (the selector and animation support adds more value for ASP.NET Ajax developers) but that’s a minor thing, and there are plenty of other resources to learn about jQuery. Topics in Wally’s book include:

  • Ajax History
  • Script Combining (including ScriptReferenceProfiler)
  • jQuery
  • Routing
  • Entity Framework
  • Dynamic Data
  • ADO.NET Data Services

http://www.wrox.com/WileyCDA/WroxTitle/New-Features-in-ASP-NET-3-5-Service-Pack-1.productCd-0470457341.html

Microsoft Ajax Client Templates and declarative jQuery

Apparently Brian likes our declarative syntax. And jQuery. And he did something quite fun with them, something we had clearly not anticipated: using Microsoft Ajax’s new declarative syntax to call jQuery plug-ins instead of Microsoft Ajax behaviors as was the original intent.

<input type="text" maxlength="20" size="40" 
   sys:key=”self” 
   sys:attach=”wajbar”  
   wajbar:submit=”{{ $(self).next(’input:submit’) }}/> 

The way he made that possible is by adding a registration step to make the plug-in accessible through sys:attach. This registration API actually creates a wrapper behavior for the plug-in that gets Microsoft Ajax to believe the plug-in is a regular behavior. The actual plug-in gets called during initialization of the wrapper behavior, using the behavior itself as the options for the plug-in. This works because the declarative engine in Microsoft Ajax will just set plain expando fields for namespaced attributes such as “wajbar:submit” that don’t correspond to a property. Clever.

This is quite interesting and opens up a number of possibilities, such as enabling our declarative syntax to instantiate components from any framework (without the hack of wrapping them in a Microsoft Ajax behavior) if we open up the right extensibility points. This is definitely something I’ll investigate.

What do you think?

Brian’s post:
http://weblogs.manas.com.ar/bcardiff/2008/12/declarative-jquery-with-microsoft-ajax/

Really Simple Testing for JavaScript

There are plenty of options to test JavaScript code. My goal here is not especially to add to this long list but I needed something for my samples that was brain dead simple to understand and that I could redistribute without any concerns about licensing (this is licensed under the very liberal MS-PL). I just think it’s good practice to distribute tests with sample code because it promotes TDD and helps to understand the intent of the code.

So I built the simplest test framework I could, both in terms of its code and ease of use. The result is very small and at 32 lines of code, it’s small enough that I can post it in its entirety here:

// Really Simple Testing for JavaScript
// (c) 2008 Bertrand Le Roy, licensed under MS-PL
function test(tests, consoleElement) {
    var results = {}, failed = 0,
        console = typeof(consoleElement) === "string" ?
            document.getElementById(consoleElement) :
            consoleElement || document.body;
    function write(message, color) {
        if (!console.appendChild) return;
        var div = document.createElement("div");
        div.style.color = color;
        div.innerHTML = message;
        console.appendChild(div);
    }
    for (var testName in tests) {
        try {
            tests[testName]();
            write(testName + " passed", "green");
            results[testName] = null;
        }
        catch (ex) {
            write(testName + " failed with " + ex.message, "red");
            results[testName] = ex;
            failed++;
        }
    }
    if (failed) write(failed + " failed." , "red");
    return results;
}
test.assert = function(condition, failMessage) {
    if (!condition) throw new Error(failMessage || "Assertion failed.");
}

Using it is just as simple. Just create an empty HTML page, include the script file and add a script tag right after the body tag. This is where you’ll write your tests. The test suite consists of a single call to the test function, where the argument is a plain object that contains a set of names and test case functions. Each test case may do one or several calls to test.assert. Assert just throws an exception if the condition is false. Any exception is interpreted as the test failing, except if that exception is expected and is being caught by the test code. Here is the test suite for testing the framework itself:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <
html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Testing Really Simple Testing for JavaScript</title> <script type="text/javascript" src="Script/RST.js"></script> </head> <body></body> <script type="text/javascript"> test({ simpleAssert: function() { test.assert(1 + 1 === 2, "1+1 is supposed to be 2."); }, failAssert: function() { try { test.assert(1 + 1 === 3, "FAIL"); } catch (ex) { test.assert(ex.message === "FAIL", "Failed to fail."); } }, testResults: function() { var testResults = test({ success: function() { }, failure: function() { throw new Error("failure"); } }, {}); test.assert(testResults.success === null,
"Success should give a null entry in the results."); test.assert(testResults.failure.message === "failure",
"Failure should store the exception in results."); } }); </script> </html>

The test function takes an optional second parameter that is the element to use as an output console (use an empty object if you don’t want any output, like I did in the testResults case or don’t specify it at all to use body). It returns an object that has the same structure as the test case parameter. Each case name points to null if the test passed, and to the exception object if it failed. This is useful when you want to use the test results and not just see them on the page. This is the case in testResults and also if you want to automate the tests and send a report somewhere.

By default the test framework will just display results in the body tag, in green for passing tests, in red with the exception message for failing ones, and if anything failed, it will display the number of failing tests:

simpleAssert passed
failAssert passed
testResults failed with Failed on purpose.
1 failed.

Here is a little FAQ to answer some of the questions you may still have:

  1. Why no assertEqual?
    I only included the bare minimum, an assert function. It’s fine for my usage. assertEqual would give a better automatic error message and if you need it, if would be very easy to write. Oh well, if you need it, here it is:
  2. test.assertEqual = function(expected, actual, failMessage) {
        if (expected !== actual) throw new Error(failMessage ||
    "Expected " + expected + ", got " + actual + "."); }
  3. What? No setup and teardown?
    No, you’ll have to call any setup and teardown functions you may have manually. Or modify the framework and add that capability. Shouldn’t add much more than four lines of code.
  4. How do I do expected exceptions?
    Just try/catch and don’t forget to assert something about the exception from the catch block. The failAssert case above gives an example of that.
  5. How do I find out what went wrong in my failing test?
    Attach a debugger, set a breakpoint in the test case, and step through the code. Know your F10, F11 and SHIFT+F11.
  6. Do I have to run all tests in the suite every time?
    Yep. Build smaller test suites or break one big suite into several small ones if that’s a problem.
  7. Does this work in all browsers?
    Yes. All browsers that support JavaScript, createElement, innerHTML and appendChild. That should be all the browsers you care about, right?
  8. How do I automate test runs?
    Pretty much all recent browsers support being launched from the command line with the url to navigate as the argument. Your page can then submit a form with serialized results as a field value to a server page that compares the results with a baseline. It’s just a matter of writing a bunch of batch files and a server page to receive the results and log them. I didn’t write that part because that wasn’t part of my goals but if you do, please tell me and I’ll post about it.
  9. How do I do asynchronous tests?
    One way you could do this is by doing your call to the test function from your asynchronous callback.
  10. How do I do deep object and array comparisons?
    Manually. What’s a little loop? Write a helper if you want, that shouldn’t be too hard.
  11. Any mocking facilities?
    No, but mocking is considerably easier in dynamic languages and JavaScript is no exception.
  12. Why put the test code after body?
    Because the framework is using it as its console so it must be ready when the script runs. You don’t have to if you want to use another element than body as the console, or if you don’t use a console, or if you run the tests on body load or on some framework’s document ready event.
  13. Is this limited to Microsoft Ajax?
    No, this doesn’t even use it. It’s plain JavaScript, no dependencies, and should work with any framework and any browser.

I hope this helps.

Download the testing framework and its test suite here:
http://weblogs.asp.net/blogs/bleroy/Samples/ReallySimpleTesting.zip

More Posts