posted by | Comments Off on Customization Testing Framework

Bright is super powerful, really. During a demo last week, our partner/re-seller said “I can do anything I want”. Or something like that.

Only problem [at least from our perspective] is the proliferation of Bright customizations in the wild. This can be a bit stressful when we go to change “Bright core”. How do we keep from breaking all those cool client-side customizations!??!?!

Part of the problem has been the testing architecture of Bright itself. Bright server, tested to the hilt. A continuous integration chassis is testing Bright server up pretty much day and night. If it breaks, it’s because we didn’t write a test. Easy to fix.

Nice, but in the end, Bright is primarily used to serve web pages in “other” web stacks. How do we keep track of all that UI code sitting on top of the Bright API?

As an experiment, I decided to rig up qUnit onto the Bright.js library core. We added a special settings option in the Bright plugin for WordPress:

jstest

Set that, and next thing you know, your web pages are running the new Javascript test chassis. One nice thing is if this isn’t set, all the test javascript isn’t loaded. So there’s no performance impact on production sites.

With jstest=true test, here’s an example of the test output.

qunit2

The best part? Adding tests for client customizations, super easy!

For a Bright customizations plugin, just add something like this:


/* add this to your customizations plugin or anywhere you enqueue your Javascript */

function load_bright_customization_scripts() {
  if (bright_testing()) {
    wp_enqueue_script('my-custom-testing',
                      plugins_url('qunit-tests.js', __FILE__),
                      array('bright'));
  }
}
add_action('wp_enqueue_scripts', 'load_bright_customization_scripts');

Now add some tests:

// this is my qunit-tests.js 

// In this example, we are hooking to the bright tests hooks both BEFORE and AFTER the bright templates are rendered.
// In this test, we will validate the template rendered, that it has data in it, and the the jQuery data tables loaded
// and is usable.

MyTest = {};

Bright.addHook('before_load_tests', function () {
  if (jQuery('.bright-template-my_results_matrix').length > 0) {
	MyTest.my_results_matrix = jQuery('.bright-template-my_results_matrix').length;
  }
});

Bright.addHook('after_load_tests',function () {
  if (MyTest.my_results_matrix) 
	QUnit.test('my_results_matrix',function(assert) {
	  assert.equal(jQuery('.bright-template-my_results_matrix').length,MyTest.my_results_matrix,'an equal number of divs before and after render');
	  assert.equal(jQuery('.my-results-matrix .dataTables_wrapper').length > 0,true,"we find that datatables has loaded");
	  assert.equal(jQuery('.my-results-matrix .dataTables_wrapper table.my-results-matrix tbody tr').length > 1, true, "more than one row found in the results table");
	  assert.equal(jQuery('.my-results-matrix .dataTables_wrapper table.my-results-matrix thead span.filter_column input[value="Email"]').length === 1,true,
				   "A text entry search field is found for the email field");
	});
});

UGH CODE!!! Yeah don’t worry about that too much. Translated for humans, we’ve made it very simple to write unit tests for Bright templates. Testing rocks!