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!).

AttachmentSize
javascript_unit_testing.patch14.31 KB
Testbed results
javascript_unit_testing.patchre-testing

#1

dmitrig01 - March 22, 2008 - 19:59

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.

AttachmentSize
javascript_unit_testing.patch 13.76 KB
Testbed results
javascript_unit_testing.patchre-testing

#2

quicksketch - March 23, 2008 - 04:25

Subscribe (thanks dmitri).

#3

dmitrig01 - March 23, 2008 - 17:04

I have found out a way to do functional testing. Now we need naming conventions for JS files

#4

catch - March 24, 2008 - 13:29

This looks great! Subscribing.

#5

moshe weitzman - March 25, 2008 - 11:43

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

Freso - March 27, 2008 - 20:01

This is awesome. Thank you, Dmitri! (Subscribing. :))

#7

beeradb - April 7, 2008 - 22:42

subscribing - thanks for the great work so far.

#8

dropcube - May 28, 2008 - 08:00

subscribing...

#9

Dries - May 30, 2008 - 13:22

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

moshe weitzman - June 6, 2008 - 03:53

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

nedjo - June 24, 2008 - 21:21

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

dmitrig01 - August 2, 2008 - 12:30

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

Rob Loach - September 10, 2008 - 16:17

There must be a way we could get this working nicely in a SimpleTest test.

#14

Morbus Iff - September 12, 2008 - 14:13

Subscribing.

#15

System Message - November 16, 2008 - 21:40
Status:needs review» needs work

The last submitted patch failed testing.

#16

lilou - November 17, 2008 - 13:13

#17

chx - December 18, 2008 - 19:27

#18

bdragon - December 18, 2008 - 19:33

Subscribing.

#19

jhedstrom - December 19, 2008 - 00:31

subscribing

#20

stewsnooze - December 19, 2008 - 21:37

subscribing

#21

katbailey - December 24, 2008 - 01:11

I made a minor change to dmitri's patch so that Drupal.tests.testAttachBehaviors works with the new Drupal.behaviors.

AttachmentSize
javascript_unit_testing_1.patch 13.46 KB
Testbed results
javascript_unit_testing_1.patchfailedFailed: Failed to apply patch. Detailed results

#22

System Message - January 8, 2009 - 13:15
Status:needs review» needs work

The last submitted patch failed testing.

#23

Rob Loach - January 14, 2009 - 21:23

#24

Rob Loach - February 24, 2009 - 04:17

#25

vaeiou - February 24, 2009 - 05:36

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

stella - February 24, 2009 - 09:52

subscribe

#27

dmitrig01 - February 25, 2009 - 04:13

@vaeiou selenium and celerity are bad because you have to install them in your browser.

#29

dmitrig01 - March 21, 2009 - 16:04

i applied for the beta on behalf of drupal

#30

moshe weitzman - June 8, 2009 - 03:08

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...

 
 

Drupal is a registered trademark of Dries Buytaert.