Automated JavaScript unit testing framework
dmitrig01 - March 22, 2008 - 19:19
| Project: | Drupal |
| Version: | 7.x-dev |
| Component: | javascript |
| Category: | task |
| Priority: | critical |
| Assigned: | dmitrig01 |
| Status: | needs work |
Description
If we need full unit test coverage for code, I would assume this includes JavaScript.
I made a patch which has a light-weight unit-testing framework for JS.
Currently it has no UI, but you can run Drupal.test() through firebug.
Also, the checkPlain tests don't pass, and this is for good reason, because checkPlain is broken (yay tests!).
| Attachment | Size |
|---|---|
| javascript_unit_testing.patch | 14.31 KB |
| Testbed results | ||
|---|---|---|
| javascript_unit_testing.patch | re-testing | |

#1
The fix to the checkPlain bug is http://drupal.org/node/237577, and I have a new patch, which doesn't do stuff in drupal.js but moves tests over to tests.drupal.js.
I will file separate patches for more tests.
#2
Subscribe (thanks dmitri).
#3
I have found out a way to do functional testing. Now we need naming conventions for JS files
#4
This looks great! Subscribing.
#5
This looks terrific. Should we build upon the testing library of jquery - either testrunner or jqunit? Maybe you did already since they look similar.
#6
This is awesome. Thank you, Dmitri! (Subscribing. :))
#7
subscribing - thanks for the great work so far.
#8
subscribing...
#9
Is this something that we could invoke from within SimpleTests so that with one click on a button, we can run all tests, including the JS tests.
#10
Jquery has promoted its QUnit unit test framework to be an independant project. They *want* other projects to use this. We should consider it strongly. See http://docs.jquery.com/QUnit
#11
Thanks for taking the lead dmitrig01.
Yes, there are big potential advantages to using the QUnit framework, since it is the standard for jQuery, is under active external development, and has documentation and samples in place.
That said, (a) the QUnit documentation is sketchy so far, (b) Dmitri's version is coded more closely to our existing Drupal js codebase (c) there look to be some methods in this patch not available in QUnit, e.g., Drupal.tests.randomName.
Maybe rework the patch to build off of QUnit while adding missing methods (could also contribute as patches to QUnit).
@Dries, I guess we need to add a JS behaviour that calls JS tests? There are several significant challenges:
* As most (all?) of our JS behaviours depend on specific page content, we have the challenge of rendering that content and adding needed JS and CSS (possibly inline).
* Some JS behaviours will require specific user interaction and data (e.g., the ahah.js behaviors like file uploads).
Do we visit each page with a behaviour in sequence? Do we try to render on a single page all the minimal content needed by all behaviours? I guess the latter is more in line with what we do in other tests. We would require the simple tests to render the HTML needed for a test. Following the upload with AHAH example, this might be something like:
<?php
global $conf;
// Cache any existing variable.
$cached = $conf;
// Explicitly allow uploads with stories.
$conf['upload_story'] = TRUE;
// Build and render the upload form.
// Generate a dummy form.
$form = array();
// Upload's form_alter requires a #node property.
$node = new StdObj();
$node->type = 'story';
$form['#node'] = $node;
drupal_alter('form', $form, array(), 'story_node_form');
$form_state = array('submitted' => FALSE);
$form = form_builder('story_node_form', $form, $form_state);
// Rendering the form will ensure we have the appropriate AHAH JS/CSS loaded.
$output = drupal_render($form);
// Restore the previous $conf values.
$conf = $cached;
return $output;
?>
But we're still stuck with the problem of emulating user interaction. Iinitially at least, we might want to limit ourselves to higher level stuff that doesn't involve user actions.
#12
Hm, I think it might actually be a good idea to have them each on separate pages, and when defining a JS test in PHP (I was thinking of hook_jstest or something), you could have a callback that would get rendered into an iframe where all the assertions would happen.
#13
There must be a way we could get this working nicely in a SimpleTest test.
#14
Subscribing.
#15
The last submitted patch failed testing.
#16
See: #335122: Test clean HEAD after every commit and http://pastebin.ca/1258476
#17
Firing events is http://www.rakshith.net/blog/?p=35 and http://www.howtocreate.co.uk/tutorials/javascript/domevents apparently possible.
#18
Subscribing.
#19
subscribing
#20
subscribing
#21
I made a minor change to dmitri's patch so that Drupal.tests.testAttachBehaviors works with the new Drupal.behaviors.
#22
The last submitted patch failed testing.
#23
jQuery 1.3 came out with http://docs.jquery.com/Release:jQuery_1.3#Testing .
#24
John Resig is pushing the function call profiling awesomeness.
#25
I'm not sure if this is entirely relevant, but there are automated browser testing frameworks available that emulate user interaction. Selenium (http://seleniumhq.org/) [multiple languages] and Celerity (http://celerity.rubyforge.org/) [Ruby and can run headless] come to mind.
Essentially, you can code, "click on this link and wait for the page to load" or "click on this to see if the drop down box expands". Nifty interactions that are very high level.
It might be useful to run these sorts of tests outside of the simpletest framework - it would probably take a lot of work and code to integrate the two.
I've just started playing around with Celerity, so let me know if any of you guys are interested in pursuing this.
#26
subscribe
#27
@vaeiou selenium and celerity are bad because you have to install them in your browser.
#28
Now Resig is tackling the cross browser problem in quite an innovative way - crowdsourcing.
#29
i applied for the beta on behalf of drupal
#30
anyone up for this. is a big hole in our test suite. here is an article on qunit just to whet the appetite - http://highoncoding.com/Articles/570_Unit_Testing_JavaScript_Using_JQuer...