A Quick Unit Test in Lithium 0.5
Unit testing has always proven a chore in past projects. But a necessary one. The more specific the testing, the more effectively one isolates problems in the code. Well, and the more aesthetic, provided one knows how to use unit testing right. I have found Lithium’s built-in unit testing environment amazingly simple, and since a couple of folks have asked me recently about this feature, I thought I’d post a very quick unit test just to demonstrate how even a beginner can take up unit testing in Lithium in minutes. (This example already assumes you have Lithium 0.5 working in your localhost environment; if you don’t, take a look at Union of Rad’s installation tutorial or the project lead Garrett Woodworth’s screencast.)
Create the Test Class
To launch Lithium’s unit test dashboard, simply add test after your application’s root path. Assuming our new app is named “basic,” you’d type something like http://localhost/basic/test as your URL. By default, the dashboard only displays Lithium’s core tests. Let’s add one for our own app to evaluate a model.
Create a model test file in app/tests/cases/models and name it after the model class you intend to simulate. In my case, I’m testing a table holding data on composers for a sheet music application, so I’ll name my file ComposerTest.php. Now, place some standard code in this file so that the test classes will execute the unit tests appropriately:
1 <?php
2
3 namespace app\tests\cases\models;
4
5 use \lithium\data\Model;
6 use \app\models\Composer;
7
8 class ComposerTest extends \lithium\test\Unit {
9
10 }
11
12 ?>
On line 3, we specify the namespace for this class, which corresponds to the path in the application where this test class appears. Lines 5 and 6 call two classes that will allow the ComposerTest class to connect to the database and/or run methods in the Composer model, which, of course, is my runtime model for all of my Composer methods in the live app. Line 8 names the class following a convention: we add “Test” to the end of the model name we’re testing and we extend from the core unit testing class available as lithium/test/Unit.php.
Go back to the unit test dashboard and your new test class should appear on the left under app > cases > models > ComposerTest. Click the link to run tests on ComposerTest, and the results should light up green with zero passes, fails, or exceptions.
Perform a Unit Test
A very basic unit test performs a query to see whether the model connects to the database and can fetch records. I’m going to write a test function that allows me to see whether my model can perform a basic find query. In the ComposerTest class, I’ve written a function called testWhetherDbQueryWorks() that asserts whether a result set is null or populated with table data. It looks like this:
public function testWhetherDbQueryWorks() {
$composers = Composer::find('first')->to('array');
$this->expectException('Undefined index: id');
$this->assertTrue($composers['id'] != null, 'Query did not pull data');
}
Simple enough. You can see I’ve added an expectException method because, obviously, if the Composer::find() method turns up zero results, the ID field won’t be keyed in the $composers array. Lithium provides several other assertion methods, which are all described at the Unit class entry in the Lithium API.
Now, when I run the test in the dashboard, it ought to pass, provided I’ve set up my Composer class correctly.
Hope this helps for those beginners out there looking to try out Lithium. I’ll try adding more detailed information, or using screencasts, when I’ve got a little more time for documenting my experiences in Lithium.
Transitioning from CakePHP to Lithium
For anyone following the CakePHP project, you likely already know about the Cake3 project spinning off and becoming a separate framework called Lithium (li3 for short). After a couple of months of testing the Lithium framework and using it for my current web development needs, I’m so encouraged by the experience and the results, that I had to suggest to my readers that they consider making the transition from Cake to Lithium. As the framework nears its 1.0 release, I expect the core feature set to include all of the essentials that we Cake users already enjoy, but with some significant improvements. For those that appreciate good code like good art, Lithium is clearly a step in the right direction.
So far, I’ve only had occasion to try out a few features, and the outcomes have already been promising. Here are differences I’ve picked up from how things are done in Cake.
Bootstrapping and Additional Libraries
Lithium’s way of bootstrapping the various libraries allow for various server configuration settings more easily than Cake. Rather than defining constants in the app/webroot/index.php file, server paths are stored in the app/config/boostrap.php file. Only two constants need changing if you adjust the folder structure on your server: LITHIUM_LIBRARY_PATH, which points to the core libraries directory, and LITHIUM_APP_PATH, which points to the application itself. Other core settings may be included in bootstrap.php; as good practice, I added
ini_set('display_errors', 1);
Lithium uses third-party libraries much more seamlessly than Cake. Before, the scripts would have to be included through a vendors folder and brought into the application using, essentially, an include-like function. What I had wanted was a little more flexibility for where third-party scripts could be stored, since the possibilities for what third-party scripts require, in terms of server configuration and installations, usually call for install paths very different from how Cake structures itself in the background. Lithium provides a configuration file, app/config/boostrap/libraries.php, which allows you to add libraries either with a require directive or by using its built-in Libraries class. I was able to drop the Doctrine ORM library in the app/libraries directory and bring it into my app with:
Libraries::add('Doctrine', array(
'path' => LITHIUM_APP_PATH . '/libraries/doctrine/DoctrineORM-2.0.0/Doctrine'
));
Easy enough!
Namespaces and MVC
How Lithium makes use of PHP 5.3’s namespaces improves the flexibility of building model and controller classes. In one app, I have a sheet music database that provides downloads to web users. On the home page, it provides a list of all the composers in the database and a list of the top ten most downloaded files. In Cake, to do this, the ComposersController class has two options to fetch those top ten downloads. One is to perform a requestAction call to the DownloadsController class. The other is to call its own model class and perform a bindModel on the Download model, then run a find method to pull the top ten downloads. This isn’t too difficult or bloated, code-wise, but notice how Lithium improves upon this scenario.
I simply add:
use app\models\Download;
to the ComposersController class, then run the find method like so:
$downloads = Download::find('all', array('orderBy'=>'Download.downloads DESC', 'limit'=>10))->to('array');
One advantage here is that I don’t have to directly instantiate the Download model class in the controller; I simply call its namespace with the use method, and all of its methods are available to the controller. I don’t have to worry about table associations if I don’t want to. And, well, the code just feels cleaner and yet still adheres to the MVC paradigm that keeps the various classes abstracted from one another.
Console
When it comes to Lithium’s console, it’s just a fun piece of work, and much easier to implement than Cake’s Bake script, in my opinion. Because Lithium makes more direct use with its li3 console app, the integration with your application comes pre-built and ready to go. What I’ve always appreciated about Ruby On Rails and Symfony is their use of the console to automate development processes. But I’ve also admired Cake for not being overly tied down to the console that you must create a particular shell environment to get the framework to install easily. In fact, in my earliest days of web frameworks experience, this factor pulled me over to Cake in the first place; I had spent hours trying to get Symfony to run correctly in my local console environment, but Cake just worked after dropping the main folder into my server root. I didn’t care what core features Symfony offered at the time because I could get right to work in Cake without any headache.
Lithium, on the other hand, improves upon both of these paradigms of console development, if you ask me. It maintains the same drag-and-drop installation capabilities as Cake, but comes packaged with console features that rival Ruby On Rails and Symfony. (I realize, though, that I’m speaking of a framework that is currently at 0.6, so some of this is my own predictions of what will come through at the 1.0 phase.)
Getting li3 to run required a simple adjustment to my .profile file. I simply added:
export PATH=/usr/lib/lithium/console:$PATH
to my .profile (I have the Lithium core installed in my /usr/lib directory) and was able to call li3 in the terminal, and was in business. After following the Console Tutorial on the Lithium site, I had a numbers game up in minutes. In short, I created my own console class in the app/extensions/command directory and then ran it quite easily by pointing to the application with cd, and from there calling li3 numbers (numbers was the name of the console class). I didn’t have to add any flags to the command line, just simply browsed to the app folder, and li3 knew what to do from there. Now, obviously the numbers game is a trivial way of learning the capabilities of a shell environment for a framework. But the integration is such that I’ll be able to customize console commands to perform unit tests, populate the datasource with schematics, manage sessions, perform cron jobs, build custom classes automagically, and so on.
Datasources
I’ll admit that the hardest chapter to write for my Beginning CakePHP book was the one on datasources. This was simply because the documentation was sparse on even how to get datasources working, let alone explain a normative way for optimally doing so in the Cake environment. Since then, the documentation has gotten much better. Nevertheless, the datasource schema for bridging various sources favors a kind of database model, meaning, you still use the $useDbConfig property and define that value in the config/database.php file to attach a datasource to your Cake app.
Lithium, on the other hand, assumes wildly different ways of sourcing data to your app. In fact, it comes pre-built to handle cutting-edge datasources like MongoDB and CouchDB which require a little more flexibility to leverage their feature sets. It handles these sources not as databases per se, or as PDO abstractions, but as connections. This semantic difference actually amplifies the capabilities of the datasource structure because it further abstracts the way data is pulled, manipulated, and otherwise handled by the framework. Web services like the dozens Google and Facebook applications are providing all could interact with a Lithium app the same way a database would, without attaching duct tape here and there in your code base. This makes for leaner code, and above all, improves performance significantly.
Concluding Thoughts
Dedicating two months to Lithium after years on the CakePHP platform has made me a convert for one basic reason. In the end, they both will get it done, and will get it done well. But, to be honest, the experience feels different, and however else the pieces fall into place that make the two frameworks semantically and structurally different doesn’t really matter when push comes to shove. As a developer, I just want to enjoy coding and I want it to be lean and clean.
So it really has begun to feel a lot like my experiences on the Mac and PC platforms. On the one hand, the Apple paradigm fights vigorously to streamline the feature set and to zero-in on each feature as a unique contribution to the user experience. They are ready to scrap features if they have to in order to maintain an intuitive and clean experience because they know that in the end, the user has to come away with a positive and simple interaction with their software. But the Microsoft paradigm has always been one of amplifying the feature set as much as possible and creating a platform that cannot be brushed aside. They want to drag-race the competition and compete as a total platform, one that out-does everyone else’s feature set, though only recently are they working harder to focus on the user experience. (Check out The Marketing Playbook by John Zagula and Rich Tong for a detailed explanation of how Microsoft thinks about platform plays behind the scenes and demolishing competition through Windows integration.)
Cake has started to feel less clean and more like Zend Framework feels; chock full of features, but lacking in performance and rigorous streamlining of the core feature set. I give kudos to Garrett Woodworth, Nate Abele, Joel Perras, Alexander Morland, and David Persson for their vision for Lithium and encourage you to give their new rising-star framework a go.
Formatting Dates in Cappuccino with CPDateHelper
I missed being able to format dates like I do in PHP and with a current Cappuccino app I’m working on, I couldn’t help build a date formatting helper. I’ve posted it as an open source class on GitHub and invite your contributions, feedback, or use.
Using this class is simple. Just download and place the CPDateHelper.j file in your Cappuccino app directory. Then include the class using:
@import "CPDateHelper.j"
Anywhere in your Cappuccino app, just provide CPDateHelper with a date string and a formatting string and it will return a formatted date string. For example:
var formattedDateString = [CPDateHelper date:@"Wed Aug 5 2009 13:00:00" withFormat:@"D M jS Y g:i A"];
In this example, formattedDateString will contain:
Wed Aug 5th 2009 1:00 PM
CPDateHelper also returns the formatted date string as a CPString object, so you can use CPString methods on it right out of the box.
Again, jump on over to the GitHub project to download the source or

