I’m using the Marionette library with the Backbone framework. It provides a layer of functionality that I have needed in any moderately involved backbone application I have put together.
As I get more involved with these tools, I’m going to start putting down a few things I have discovered. For the next few posts on this, specifically in regards to testing during the integration of new code into an existing Backbone/Marrionette application.
(If you haven’t seen them, there are already plenty of useful tips and guides for developing Test Driven backbone applications, that you should not miss.)
One of Marionette’s most useful features is it’s module system. In addition to allowing you to keep your concerns separated, it also features initializers that can be triggered when the module is started, or when it’s parent application (or module – modules can contain sub-modules) is started. Modules can also be stopped individually to save memory and resources when they are no longer used.
The first thing that tripped me up was gaining access to public variables and methods defined within a module.
Until you call an application’s start() function, you won’t be able to access public variables declared inside modules. This is a problem: how can you test something if you can’t reach it?
Additionally, (and this is applicable to non-marrionette applications, too) you may need to initialize a external system in order to interact with it. I have one app that is a javascript front end for a hardware MIDI music interface written in Java. So, in order to test the integrated behaviour of the module with the system, I need to instantiate and initialize the JVM.
Now, in the past I’ve gotten around this by instantiating a cloned version of the entire app for every test, and then deleting it – both slow and not strictly an integration test, since >everything< is getting started when the marrionette application start() is called. However, this is no longer (entirely) necessary: Marrionette’s author noticed the problem and has created a fix for it .
So, each test can start like this:
You’ll need to switch to the module definitions branch, to start modules individually like this, until it’s merged into the main branch,
Also, any initializers that you need to go with that code can be started by using an initializer attached to the module instead of the app to run anything that you need to, before the test (such as my Java MIDI interface)
Now, starting modules gets you part of the way, and depending on what is going on in the module under test, it may be perfectly sufficient to simply initialize the module and be able to access internal functions and variables, and generally interact with it
However, this still leaves the fact that the modules aren’t being erased between the tests. In some cases, this can cause trouble, particularly if you want to
But this can be solved – through my previous practice of instantiating a clone of the application before each test. This slows things down, yes, but if you need greater isolation of your code, or to start up and shut down something external, it’s an option:
So, there you go: instantiation of marrionette modules, with more or less isolation, as required.
In the next few posts on this, I’m going to talk about methods for testing your backbone application with the entire app instantiated and integration testing server interactions.
February 16th, 2013 at 6:19 am
Great article. I am currently learning Marrionette (I am moderate in backbone).
Looking forward to the next article