Anzo.JS Debugging Guide
For developers working on Anzo.JS (Anzo RDF Client API for JavaScript), this page describes helpful hints and tools for debugging issues in Anzo.JS.
Since Anzo.JS uses the Dojo package framework, many of the facilities and tools described in the Dojo Book are useful for working with Anzo.JS also.
Unit Tests Run on Different JavaScript Runtimes
The Anzo.JS project uses the Dojo D.O.H. framework for running JavaScript unit tests as part of the Anzo build. That framework uses the Rhino JavaScript runtime for running the tests. Thus, when unit tests are run in the build, they are running in a different JavaScript interpreter than when they are run in Firefox (the SpiderMonkey JavaScript runtime) or Internet Explorer (JScript JavaScript runtime).
Due to differences in various JavaScript runtime it is common for a test to pass in one runtime and not another. Each runtime has various tools to help debug scripts in it and various differences. I'll try to describe some of the differences we've run into and some of the debugging tools available for each runtime.
Rhino (command line build)
Debugging tools
- doh.debug() - Using this function to output messages to the console perhaps the simplest, most effective, cross-platform debugging tool.
- Rhino JavaScript Debugger - A fairly impressive graphical debugger for Rhino.
- The anzo-js/tools/debugTests.bat and .../debugTests.sh scripts will launch the debugger ready to run the Anzo.JS unit test suite.
- Because Anzo.JS is loaded dynamically by the Dojo loader, you may not be able to place breakpoints in a test before its file has been loaded. There are various techniques to deal with this.
- Place a debugger; statement in your test while debugging it. Be sure to remove it before checking in.
- Place calls to Rhino's load() function to load the source file that contains your test early in the runtime process.
- Conveniently, the Rhino debugger knows the name and location of each file as it's loaded. It does not suffer from the debugger bug found in SpiderMonkey. Look in the Windows menu of the debugger for the list of files.
Common Problematic Rhino Differences
- Rhino has no DOM - References to document, window, DOMParser, and XMLHttpRequest cannot be resolved. Consider writing the test such that it does not depend on those objects. Split it into two tests, for example. You may use the anzo.tests.utilities.skipTestInRhino function to cause a test to be skipped when run under Rhino.
- Object Properties in different order - JavaScript properties don't guarantee a particular order when iterating over them. Improperly written tests sometimes depend on the order. This is common in tests dealing with JSON serialization. Firefox may serialize an object like this: "{ 'propA' : 'valA', 'propB' : 'valB' }" but Rhino might serialize it as "{ 'propB' : 'valB', 'propA' : 'valA' }". So one can't compare the serialization to an expected string without accounting for this. Sometimes the anzo.tests.utilities.deepCompareJSONObjects function can be effective in tests where you might otherwise use JSON string comparison.
Firefox
Firefox has some of the best JavaScript debugging tools around.
Firebug Tip: Make sure you use Firebug version 1.1 or higher (even if 1.1 is in Beta). The 1.1 or higher version is much more useful for debugging Dojo-based code since it can accurately debug inside code loaded via eval. Make sure you select show eval() sources and use Last Source Line for eval() names in the Script tab's Options menu. Running with Break on All Errors set is sometimes useful for debugging but can sometimes slow things down.
Internet Explorer
Common Problematic Internet Explorer Differences
- Strict on Syntax - Rhino is much stricter about syntax than the browsers. One particularly common issue is trailing commas in object literals. For example: { "propA" : "valA", "propB" : "valB", } - Internet Explorer is also picky in this respect. The trailing , is the most common reason why a dojo class will work fine in Firefox but fails to load in Internet Explorer.
Debugging problems loading files in Internet Explorer:
- Use the anzo-js/tools/debuggerAid.html file to get line number information syntax errors.
- The Dojo D.O.H. unit test harness has an error console at the bottom of the page. Make sure to scroll down! There, you will find the name of the files which had problems loading. The first file listed is typically the one with problems.
- Edit the anzo-js/tools/debuggerAid.html file to add a <script> element for loading the problematic file.
- Open the debuggerAid.html in Internet Explorer and you'll see a script error with an informative line number and message.
NOTE: You may need to select Display a notification about every script error in the Advanced tab of the Internet Options dialog. You may need to click on an error icon in the Internet Explorer status bar to see the script errors.
If you can afford Visual Studio, then it has a great script debugger. If you have a copy of Microsoft Office, the it comes with the Microsoft Script Editor which is a good JavaScript debugger for IE. Otherwise, I recommend using the free Microsoft Script Debugger. It may be old but it does a good job.
You can try using the free Visual Studio Web Developer Express which includes a good JavaScript debugger. It's not immediately obvious how to use the Express edition to debug JavaScript but there are good instructions and even a video demonstrating the setup. However, I've found that setting up the Express edition makes IE's debugging setup problematic. It seems to register itself as a script debugger in IE but it's crippled so that you can't debug directly from IE. This seems to cause IE to simply not report script errors in many situations. So the Visual Studio Express edition isn't a good tool for this in my opinion.
Common Problems
Is your problem perhaps related to the JavaScript engine differences described above?
Network operations seem to hang
Be sure to check the plug. Try increasing the log level in the server or using Wireshark.
Are you waiting for operations to finish? Did you return from a unit test in the middle of closing the anzo client? See the best practices for an example.
Things Intermittently Fail
Perhaps your code/test is dependent on initial state of the repository. Try making the code resilient (perhaps use preconditions) or, in tests, you can reset the repository to a known state like this:
anzo.tests.utilities.reset(anzoClient, callback);
Logging
Nothing is as tried and true for debugging as the good old print statement. Anzo.JS has some very helpful logging facilities. Read more at AnzoJSLoggingGuide
Best Practices
- In tests with asynchrous operations, wrap all of your callbacks with the Deferred.getTestErrorWrapper method. It'll make test more readable and robust. It beats lots of try/catch statements and conditionals calling d.errback() or d.callback(false) all over the place.
var d = new doh.Deferred();
var anzoClient = new anzo.client.AnzoClient(anzo.test.properties);
anzoClient.connect(d.getTestErrorWrapper(function onConnect(status, msg) {
tests.assertTrue(status == anzo.messaging.CONNECTION_STATUS_CONNECTED);
// ... do stuff ...
d.callback(true); // Call when done with successful test
}));
- When testing with an AnzoClient, never return from the unit test until the service is completely closed:
var d = new doh.Deferred();
// ...
anzoClient.close(d.getTestErrorWrapper(function() {
d.callback(true);
}));
- When testing an anzo service, always reset the server first to avoid mixing your test data with stale data:
var d = new doh.Deferred();
var anzoClient = new anzo.client.AnzoClient(anzo.test.properties);
anzoClient.connect(d.getTestErrorWrapper(function onConnect(status, msg) {
tests.assertTrue(status == anzo.messaging.CONNECTION_STATUS_CONNECTED);
// Reset the repository data
anzo.tests.utilities.reset(anzoClient, d.getTestErrorWrapper(function(suc) {
tests.assertTrue(suc);
// ... do stuff ...
d.callback(true); // Call when done with successful test
}));
}));
Code Coverage
I have only found one - JavaScript Coverage Validator - but i am not sure how good it is and it is not cheap ($199.00).


