Seeing as unit testing your CFWheels plugins has yet to be thoroughly documented, I thought I would share my experiences with writing a unit test suite for my jQuack plugin. Here is my take on writing well organised unit tests, I am by no means an expert. In fact before embarking on this project, I was a total unit test noob, but I learned valuable lessons from trial, error and much advice from Tony Petruzzi.
Unit tests are a set of repeatable tests that determine if your code meets its requirements. In a way, they also document your plugin’s behaviour as the tests themselves describe its requirements. Unit tests encourage you to write re-useable, modular code and are invaluable for checking that your plugin still function as designed when:
- A new version of CFWheels is released
- Testing across CFML engines
- Expanding or refactoring your plugin
For more information on developing plugins for CFWheels, go here.. I will use my jQuack plugin as the basis for my examples, your plugins will of course need different types of tests.. but that’s why you get paid the big bucks!
But enough jibber jabber.. Let’s get testing fool!
1. Create a folder called “tests” in your plugin’s folder (eg /plugins/jquack/tests).
This is where your tests code, and any assets required for the tests will reside. This assets folder can (and should) mimic your application folder structure, but only create the folders you use in your tests (see the next step for how to use them). For jQuack, I needed an isolated bunch of assets (files, folders & variables) that I could butcher with my tests without affecting my actual application.
2. Create a Base.cfc in the tests folder and be sure to extend the wheels Test component.
This is not required, but I would consider it good practice and will make your test suite scalable. This cfc will contain tasks that are common to all of your tests, primarily for setup and teardown, but it may also contain helper functions that are used by your tests. This particular implementation of the setup and teardown methods are VERY important. At the start of each test, the setup method will be called, which will copy the existing application scope and massage it for this test. The test will then run and the teardown method will revert the application scope back to its original state. NOTE: The setup and teardown happens before and after EVERY test.. not just before and after the request. This isolated assets environment was probably the single most important concept for me, once I got this working, writing the actual tests was a breeze!
3. Create your unit tests cfc
Be sure to prefix the file with “Test” or it will be skipped. Also make sure to extend your Base.cfc AND call super.setup() and super.teardown() in this cfc. I like to number my tests so they run in the order specified. I also like to give my tests descriptive names. Don’t be afraid to break your tests up into separate packages. I have split mine up into TestData.cfc, TestMarkup.cfc and TestScaffold.cfc. I like to test simple variable names against each other (a eq b) rather than have my assert() methods all messy… see tests 04 and 05.
The above is a snippet only for demo purposes.. the full test suite is available using the links below.
Once you have written your tests, you should run them using the ‘Run Tests’ link next to the name of your plugin in the CFWheels debug area.
In order to test any private methods in your plugin, they will need to be made public.. I prefix my “private” (but public) methods with a $ as per the CFWheels framework convention.
<cffunction name="$CRLF" returntype="string" access="public"> <cfreturn Chr(13) & Chr(10) /> </cffunction>
This plugin uses the mixin=“controller” attribute, I’ve not yet built a plugin with any other value.
These 2 settings are pretty handy..
<!--- In config/design/settings.cfm ---> <cfset set(overwritePlugins=false)> <cfset set(deletePluginDirectories=false)>
Please comment if there are any parts that are unclear and I will try to clarify.