jQuery test suite and jsUnit compatibility
|
View:
New views
7 Messages
—
Rating Filter:
Alert me
|
|
|
jQuery test suite and jsUnit compatibilityOn the Fluid Project, we have been using Edward Hieatt's jsUnit (http://www.jsunit.net/ ) for unit testing all of our code. A number of problems--including the inability to use Firebug to debug failing tests--caused us to look elsewhere for a less intrusive JavaScript testing framework. The jQuery testing suite is great! I've ported all of my tests over to it, and have been really happy with the results. Along with this, I've made some simple extensions to the jQuery testing suite (which I've started calling "jqUnit" for convenience) that I wanted to share with the wider community and get your feedback. First of all, I've attached a patch to testrunner.js, which moves all its functions into a closure for privacy and exposes the public test API within a namespace called "jqUnit." This will help avoid conflicts in the global namespace. Since I pass $ in as an argument, it also ensures that we don't have any problems in noConflicts mode. This patch isn't an example of beautiful refactoring, but I wanted to favour clarity--if people find this interesting, I can clean up the code and indenting. Secondly, I've written a number of adaptor functions to provide compatibility for my old jsUnit tests. These provide xUnit-style asserts, and are just wrappers around the underlying jQuery assert functions such as ok(). Perhaps these are useful for others who are porting from jsUnit? Lastly, I've added support for setUp() and tearDown() functions which get run before and after each test. I've created a simple object called TestCase. Its constructor takes three arguments: the module's name, your setUp function, and your tearDown function. Is this useful to anyone? Colin var jqUnit = jqUnit || {}; (function ($) { var jsUnitCompat = { assertEquals: function (msg, expected, actual) { jqUnit.equals (actual, expected, msg); }, assertTrue: function (msg, expected) { jqUnit.ok (expected, msg); }, assertFalse: function (msg, expected) { jqUnit.ok (!expected, msg); }, assertUndefined: function (msg, expected) { jqUnit.equals ((typeof expected), 'undefined', msg); }, assertNotUndefined: function (msg, expected) { jqUnit.ok (!(typeof expected === 'undefined'), msg); }, assertNull: function (msg, expected) { jqUnit.equals (expected, null, msg); }, assertNotNull: function (msg, expected) { jqUnit.ok (!(expected === null), msg); } }; // Mix these compatibility functions into the jqUnit namespace. $.extend(jqUnit, jsUnitCompat); // TestCase object function TestCase (moduleName, setUpFn, tearDownFn) { this.moduleName = moduleName; this.setUp = setUpFn || null; this.tearDown = tearDownFn || null; jqUnit.module(this.moduleName); }; TestCase.prototype.test = function (string, testFn) { if (this.setUp) { this.setUp (); } jqUnit.test (string, testFn); if (this.tearDown) { this.tearDown (); } }; // Mix the TestCase type into the jqUnit namespace. $.extend(jqUnit, {TestCase: TestCase}); }) (jQuery); Test Title Goes Here--- Colin Clark Technical Lead, Fluid Project http://fluidproject.org |
|
|
Re: jQuery test suite and jsUnit compatibility |
|
|
Re: jQuery test suite and jsUnit compatibilitythanks for the post. i love the idea of having tests in the same module using the same setup and teardown, great idea.
Noticed a glitch though. You'll need to call jqUnit.module(this.moduleName) just before jqUnit.test(). Otherwise, you end up with whatever module name was last called, and not the associated module name (e.g. if you create module1 and module2 first, then tests afterwards, all tests will say module2) This is an interesting one. Since QUnit's original intent was to test the core of jQuery, testrunner.js can only use vanilla javascript. I think its a great idea though, and it would be an easy thing for the jquery team to build another version as a plugin, and would be another thing to spread the adoption of QUnit. to the jquery team: QUnit is great in that can be easily incorporated into the enterprise build process, and one of the few JS unit testing frameworks with active development these days. but if you really want QUnit to have a greater adoption, it should really be released as an offical plugin, and include xunit assertions and namespacing. |
|
|
QUnit, jqUnit, and rhinoI was thinking about modifying testrunner.js (the rhino version) with jqUnit, and getting it run to a point where it will be compatible with the latest QUnit and jqUnit test framework.
before I dive in, has anyone done any work on this they'd be able to share, so I won't be reinventing the wheel? thanks |
|
|
Re: QUnit, jqUnit, and rhinoI'm working on this (well, trying to get more of the jQuery test suite to pass). I've broken it out into a separate project here: http://github.com/jeresig/env-js/tree/master I'm also trying to get it to run on more platforms (such as Ruby/Johnson, Perl/Spidermonkey, and Python/Spidermonkey). --John On Thu, Jun 26, 2008 at 12:18 AM, fuzziman <Kenneth.Ko@...> wrote: > > > I was thinking about modifying testrunner.js (the rhino version) with jqUnit, > and getting it run to a point where it will be compatible with the latest > QUnit and jqUnit test framework. > > before I dive in, has anyone done any work on this they'd be able to share, > so I won't be reinventing the wheel? > > thanks > -- > View this message in context: http://www.nabble.com/jQuery-test-suite-and-jsUnit-compatibility-tp15882865s27240p18126261.html > Sent from the jQuery General Discussion mailing list archive at Nabble.com. > > |
|
|
Re: QUnit, jqUnit, and rhinoSo excited to see that you are actively working on this John!
![]() I can see you've been concentrating on document parsing behavior, while I've just been looking at "automated testing in rhino". From my testing perspective, I made a couple of patches: - in test(), wrapping fn() and the next lines in try/catch/fail, so tests don't fail silently but get logged - as part of testrunner's results() method, quit with error code if there was a failure, so ant build can stop if a failure occurred. I also patched another bug (I'm not sure whether you experience this bug too..) $.get callback wasn't being called. I tracked it down to the setInterval/clearInterval code. 2 problems: - the very first setInterval returns 0, which evaluates to false in jquery, and so timer will never be stopped, because in jquery you do if (ival) - as soon as stop() is called, the entire rhino engine stops! not sure why..... stop() is deprecated anyway. easy workaround though, I changed it to use the standard java runnable stop pattern of checking a local variable and returning: //-------------- // Timers var timers = [{}]; window.setTimeout = function(fn, time){ var num; return num = setInterval(function(){ fn(); clearInterval(num); }, time); }; window.setInterval = function(fn, time){ var num = timers.length; var isRunning = true; var timerObj = { thread: new java.lang.Thread(new java.lang.Runnable({ run: function(){ while (isRunning){ java.lang.Thread.currentThread().sleep(time); fn(); } } })), stop: function() {isRunning = false;} }; timers[num] = timerObj; timers[num].thread.start(); return num; }; window.clearInterval = function(num){ if ( timers[num] ) { timers[num].stop(); delete timers[num]; } }; //-------------- If you like, I can keep posting my findings on this thread as I find them. Once again, good to see you working on env.js, its amazing! Keep up the good work John!
|
|
|
Re: QUnit, jqUnit, and rhinoWow this is good news. I've been mucking up env.js for awhile now locally and was afraid I wouldn't see it go where I hope it will.
John you mentioned the other platforms you want it to be used on and I think this would be ideal. One thing that is currently preventing that is that the basic window code, which essentially emulates the browsers behavior and provides the standard global functions and objects available in browsers, is mixed with Java specific code. If env.js has these provided by the container, eg rhino jar + 'implementation of xmlhttprequest jar', then env.js could stay generic across all the implementations. It's a little more work but inverts the control so env.js could be used by javascript/spidermonkey to emulate the browser as well. This doesnt really help perl/python but might keep the patterns clearer. So I guess what I'm asking is, for the javascript 'env.js' is it worth it to abstract so the same script could be used across javascript engines? A simple way to achieve this is to use 'providers' which are just aliases to implementations: - in env.js - window.XMLHttpRequest = Env.XMLHttpRequest; - in rhino.env.js - Rhino = { XMLHttpRequest = function()... }; EnvProvider.XMLHttpRequest = RhinoEnv.XMLHttpRequest; allows you to include a second script, say 'rhino.env.js' , to keep env.js reusable in spidermonkey? Thatcher On Thu, Jun 26, 2008 at 11:00 AM, fuzziman <Kenneth.Ko@...> wrote:
-- Christopher Thatcher |
| Free embeddable forum powered by Nabble | Forum Help |
