David Phipps
Posts: 1
Nickname: dphipps
Registered: Apr, 2006
|
|
Re: How Do You Test JavaScript?
|
Posted: Apr 20, 2006 6:20 PM
|
|
Automated testing involves something like a JUnit test, in most developers' minds, hence projects such as JSUnit (http://www.edwardh.com/jsunit/), in which your unit test is written in Javascript (JSUnit also has very nice features like managing multiple testing boxes and distributing tests among machines to run against multiple browsers).
However, they all suffer from one core flaw most developers don't immediately realize: JavaScript has only one thread. This means you can't wait for one event to occur without preventing that one event from occurring.
The JavaScript object XMLHttpRequest supports making HTTP requests from Javascript in either synchronous or asynchronous mode, which allows you to bridge Java and JavaScript; technologies that use this include Direct Web Remoting (DWR) (more at http://getahead.ltd.uk/dwr/) and JSON-RPC (more at http://oss.metaparadigm.com/jsonrpc/).
However, leveraging this to make it easy to write unit tests is complicated, because most developers think in terms of serial, sequentical execution with thread-based waiting, which won't even with this approach; you need to generate instructions for Javascript to follow, which includes calling back to Java and asking for the next task to execute, all done in a way that allows your Ajax to run.
Here at BEA's Interaction Division (was: Plumtree), we use Selenium (http://www.openqa.org/selenium/). We use it in what is called "driven mode": a Java-centric mode that drives steps that Javascript executes, much like a standard unit test. Selenium has a handful of bugs in its driven mode, but luckily we have reasonably good developers that have been contributing back to the project. We've developed a dozen or so highly flexible JSF components in-house, and they are all unit tested using Selenium suites.
The best approach for unit testing on smaller components is to ensure that each smaller component builds its own WAR file that includes a page that renders the component, which Selenium tests can be run against. This does require that the build machine deploy and run a small WAR, but since there's no configuration necessary, it's not that much work.
One other approach that does *not* work is to use HttpUnit, a mock object testing library that has implemented an incredibly poor simulation of a javascript library. We've found we need to run against real-world browsers, and we need to run against more than one (right now, Firefox, IE, Safari, and Mozilla).
We've been exploring other mock-object JSF control wrapping testing systems, but even the most advanced one - the Shale test framework - suffers from that critical blocker: a bad or inaccurate Javascript implementation. The point behind an Ajax unit test is that it has to determine if your UI works on all browsers.
|
|