GavinPanella/ImportingJavaScriptTestModules

Not logged in - Log In / Register

Rendering of reStructured text is not possible, please install Docutils.

---------------------------------
Importing JavaScript test modules
---------------------------------

If you're writing a JavaScript test module, you'll be familiar with
putting this at the end of your ``YUI().use(...)`` block::

  Y.lp.testing.Runner.run(suite);

That's really neat and concise but it causes a problem: there's no way
to just import the test module.

When subclassing widgets, for example, I've found it useful to extend
the parent widget's tests so that the child widget is subject to the
same set of tests as a baseline (with the ability to test additional
features, or override the parent's tests when behaviour changes). But
you can't do that if the parent's tests are intertwined with the test
runner.

I've been trying out an alternative approach.


The alternative approach
========================

- Put the tests in a regular module. For example, the tests for the
  ``lp.registry.distroseries.differences`` module are in
  ``lp.registry.distroseries.differences.test``.

- Remove all references to running tests from your test module.

- Export the test suite to the test module's namespace as ``suite``.

- Change the ``test_*.html`` to include the following snippet in the
  body::

    <ul id="suites">
      <li>lp.registry.distroseries.differences.test</li>
    </ul>

  If you've loaded ``lib/lp/app/javascript/testing/testrunner.js``
  processing of this snippet will happen at ``domready``. The modules
  named will be loaded in turn (it's a ``ul``; you can name multiple
  modules in there) and the test runner will execute the tests in
  ``suite``.

See ``lib/lp/registry/javascript/distroseries/tests`` for examples of
this pattern.


What you get
============

#. As mentioned above, the test module can now be imported and tests
   can be referenced. Anything added to its namespace can be used by
   any other test module.

#. Private things can be exported for testing without polluting the
   module's namespace.

   For example, in ``differences.js``::

     var namespace = Y.namespace('lp.registry.distroseries.differences'),
         testspace = Y.namespace('lp.registry.distroseries.differences.test'),
     ...
     // Exports.
     namespace.connect_packageset_picker = connect_packageset_picker;
     namespace.connect_last_changed_picker = connect_last_changed_picker;
     // Exports for testing.
     testspace.get_packagesets_in_query = get_packagesets_in_query;
     testspace.get_changed_by_in_query = get_changed_by_in_query;
     testspace.linkify = linkify;

   Then, in ``test_differences.js``::

     var namespace = Y.namespace('lp.registry.distroseries.differences.test');
     ...
     Assert.isFunction(namespace.get_packagesets_in_query);

   This is safe! Putting stuff in the ``test`` namespace can be done
   in production code without needing to load (or causing a load of)
   the ``test`` module.

#. This separates out the responsibility for defining test cases and
   actually *running* them. I suspect this constitutes a *Good Thing*.

GavinPanella/ImportingJavaScriptTestModules (last edited 2011-08-01 09:47:08 by allenap)