Loading Fixtures Inside Functional Tests

Since I last wrote about Winning Side Ministries’ website (the one I was writing a custom CMS for) I’ve changed my mind yet again. Yes, I tend to do that a lot. I’m currently rebuilding the website based on the Symfony2 PHP web framework. It’s based on MVC and presents a nice clean interface to which one can code pretty much anything web-based and has lots of great built in tools for getting the job done.

Annoyed by past experiences with code-first-test-last development flow I’ve decided to try Test Driven Development for this particular project and I’m finding that I really like it. I will admit that there have been times when I’ve had to sit and ponder over how to bring about certain changes by first writing tests, but they’ve all been situations that I’ll run into time and time again so it hasn’t been time lost. One of those places was the first time I needed to begin writing the code to drive a view (aka, the page that will be rendered in the browser). Since this involves combining multiple components, the tests preceding development must by definition be functional tests; of course this in turn requires that we write some data fixtures so we’ll have something to run the tests against.

The Symfony framework by default uses an ORM called Doctrine, and happily enough there is a bundle (Symfony term that more or less equates to a module) called DoctrineFixturesBundle that handles most of the grunt work of maintaining the fixtures for you.  On the documentation page for the bundle it outlines the steps required for writing the fixtures and loading them into the database, though it only shows how to load them manually from the command line.  This puzzled me since one would think that it would be wiser to reload the fixtures each time the functional tests are run so that in the tests we can do all the CRUD on the database we want without worrying about spoiling things for the next run of tests.  That’s when I set off to find out how I could clear the database and load fresh fixtures at the beginning of each test run.

To start off, here is the class I came up with:

Let’s break it down a bit since a few of the constituent pieces of code are significant in their own right.

Base Class

We will be extending the class that has been provided for us in Symfony to facilitate functional tests: WebTestCase. It’s just a subclass of PHPUnit_Framework_TestCase that has a built-in web crawler to allow us to make requests and check the responses. The namespace defined there is where I keep my custom testing classes.

In PHPUnit 3.6.x if we want to call code just before all the tests in a *_TestCase subclass are run, we put that code in a public method called setUpBeforeClass() (as opposed to setUp() which is called before every individual test). Its destructive counterpart is tearDownAfterClass() just as you may expect. These methods will contain our code for loading the fixtures and then wiping them out when we’re done. If we need to use setUpBeforeClass() or tearDownAfterClass() in classes that extend FreshFixtureWebTestCase we have to be sure to call the parent:: version as well or our code here won’t be executed.

Accessing the Entity Manager

To get started, we need to grab a reference to EntityManager. This is pretty common code inside a WebTestCase instance so I’ll not go into the explanation, but here it is. Notice that I’ve assigned our reference to the Container to a static class variable…this is just a convenience for our subclasses and is not required.

Retrieving Entity class meta-data

Now comes the fun stuff. We don’t want to have to worry about the state of the database schema or migrations in the tests, so I like to dump the database and totally reload the schema directly from the Entities before the tests run. To do that we get a reference to the MetaDataFactory from our EntityManager and call its getAllMetaData() method. This returns an object that contains the meta-data for all our Entity classes.

Using SchemaTool to modify the database

The question is what do we with the meta-data once we have it? Symfony comes with a nice helper class called the SchemaTool. There are several different things we can do with this class including drop our current database and create a schema from meta-data.

Creating a CLI application object

The doctrine-fixtures bundle only gives us the ability to load fixtures from the command line. In order to run Symfony CLI commands from PHP code we need to create an Application object. We have to make sure we set autoExit to false or else our entire PHP script will exit as soon as the command has run—this would be rather counterproductive when we’re trying to run tests!

Running the doctrine:fixtures:load command

To actually run our command we create input and output objects and feed them to the Application object. The command to run goes into the input and the result (which would normally be printed to the terminal) will be read from the output. Our command will be in the form of a string so we’ll use StringInput. We want the output of the command in a string as well but unfortunately there is no StringOutput class; there is a however a StreamOutput which we can point to a temporary file. Once the command is done executing we can read the contents of the file back. Note that PHP automatically deletes files created with tmpfile() once the script exits so we don’t have to bother with it.

Checking for errors

If there were any errors the output of the command should contain the word ‘Exception’. I’m just running an assert to make sure we don’t see that in the output, though you may have to use a different method if you have a table or Entity with ‘Exception’ in the name.

Cleaning up

Once all our tests are done we want to clear the database again. This way if we accidentally forget to load something in another test class we’ll know immediately because all queries will fail.

Using FreshFixtureWebTestCase

To use this class we simply extend it the same way we would WebTestCase. All the fixture-loading code will be called automatically without so much as a thought from us, though I do want to reiterate my prior warning:

If we define setUpBeforeClass() or tearDownAfterClass() in a subclass of FreshFixtureWebTestCase, FreshFixtureWebTestCases’s method(s) will be overridden. To keep the fixture functionality we must call parent::[method_name] from within whichever method(s) we override.


PHP types, exceptions, and Smarty templates

Continuing on with the implementation of a custom CMS for the ministry website, I’ve been doing a lot more type checking than I used to do with PHP.  That’s actually one of the things that has always bothered me about languages like PHP; as a programmer I make a lot of mistakes and it’s a real boon if my programming language supports double checking me without any extra intervention, but PHP doesn’t offer much in the way of enforcing variable types.  Starting with PHP 5.1 we’ve had “type hinting”, which means I can force a parameter to a function/method to be an object of a certain type or an array.  Well, this doesn’t really help if my function needs a string, an int, or an array containing strictly typed elements.

What I’ve been doing to get around this is using type hinting wherever I can, then doing extra manual checks on the types of other parameters via the is_* family of functions.  If I get an incorrect type, I throw an InvalidArgumentException.  I’ve been using exceptions extensively in this project because of the multi-layered nature of it.  If I relied on return values alone for monitoring errors there would be layer after layer of if-statements and checks passing data back up the call stack, all the while making it very difficult for my functions and methods to return useful data to their callers without the use of output parameters.

One of the most recent things I’d done was to set up the page loading code to generalize error handling.  I am currently using a layout similar to this (not very pretty, I know—I’m working on it):

There’s actually a good bit more to it than that, but I’ve cut things out to make it less distracting.  Basically I get my page data, feed it to the template requested, and grab the parsed template output using $smarty->fetch().  If there is an exception thrown I check to see if the real exception message is safe to show the user or whether I need to use a general one, then I fetch the error page template to show the user instead.  Sounds OK, right?

When I tried testing this code be requesting an invalid photo album on the photo gallery page, I got two instances of the page header then the error message and page footer.  I thought I’d goofed up somewhere and included something wrong.  After more testing, I found that if the exception was thrown before the call to $smarty->fetch() (for instance if contentManger couldn’t find the page I fed it) there was no problem.  That got me to thinking about output buffering.

I knew smarty used output buffering in the implementation of fetch(), but I didn’t initially considering the implications that brought with it.  I haven’t looked at the code so I don’t know exactly how it’s written but the gist is something like this (again, my interpretation and that oversimplified):

See what’s happening? In the parseTheTemplate() section of the code, however smarty actually calls it, my template plugins get run as part of parsing the template. If one of my plugins throws an exception it gets passed back up the call stack until it gets caught by a catch block. What gets skipped? Yep, ob_get_clean(). That means any output that’s already been printed is still in the output buffer.  On the subsequent call to $smarty->fetch() it gets returned in with the rest of the output.  In order to fix it, all I had to do was add a call to ob_clean() like this:

No more problems.  Smarty could have handled this on it’s own by manually clearing the output buffer at the beginning of fetch() before anything was parsed but I’m sure there is a reason why it isn’t.  Perhaps there are people putting things in the output buffer before calling fetch() on purpose.

First GWT Experience

Well, I guess you could also call this an update on WSM Calendar.  I’d gotten so frustrated at trying to wrangle all that javascript myself, even with jQuery by my side, that I started looking for a better way.  A while ago, my friend Brandon Tilley introduced me to GWT (Google Web Toolkit).  It’s a really great web-app development platform that has a very unique feature.  You actually write your app in Java, and it “compiles” it to javascript.  Not only that, but it creates customized instances of that compiled javascript that are tweaked to work properly on each of the major browsers.

What this means is that, during development, you get the firmness and structure of Java.  I’ve never really liked coding in “web” languages like Javascript (or even PHP to some extent) because of their willy-nilly anything-goes approach to things.  Is that a string?  Or an int?  Object?  Who cares?  The thing is, I make a lot of mistakes; the more mistakes the compiler can catch for me, the better off I am.  I like languages like Java that aren’t quite as rigid as c++, but are firmer than Javascript or PHP.

So anyway, the calendar is working just enough to be semi-useful while I redo it with GWT.  I’m also trying to follow some advice I read concerning small development teams (does a team of one count as small?).  It said to start with the GUI, and then you’ll know exactly what the back-end does and does not need to do.  That allows you to really focus on what matters, which is critical for a small team.  Microsoft can afford to pay somebody to putz around with a feature that may never even be used, but those of us with very few man-hours at our disposal have to trim what we can.

Another update on WSM Calendar

Well, the going is slow with the calendar. It seems so hard to find contiguous time to work on it these days. I’ve fixed a LOT of bugs in the back-end, and the front-end isn’t looking too bad. I’m just now playing with getting dialogs set up for adding new events and editing existing ones.

My first instinct was was to use jquery-ui for my dialogs. After all, I’m already using jquery as my javascript helper library. I started out designing the event editor dialog, and I immediately realized that jquery-ui doesn’t provide any layout management…at all. Having to pixel-push every element in the dialog didn’t excite me.

That lead me to look at ExtJS as an alternative. ExtJS has a lot of very powerful (albeit complex) features, including a basic set of layout managers. While experimenting with it, however, I found that it’s form handling didn’t allow complex layouts. I had an idea in my head for what seemed to me the most intuitive way to lay out the event editing dialog, and I just couldn’t make it work with ExtJS. Any of the working alternatives I came up with just lost too much intuition to be satisfactory, so I went back to jquery. The layout isn’t perfect—inputs that should be on the same line sometimes wrap if the user increases the font size— but that’s something I can perfect later.

While creating that dialog, I also created my first jquery plugin. To make the discussion more clear, here’s an image of my original design (design done with Balsamiq Mockups):

You can see that I have several checkboxes here, each of which enables/disables the inputs that go with it. I found a nice plugin called jquery-enable-disable-plugin. This lets you assign one element that will disable or enable other elements. It, as most plugins, operates based on normal jquery selectors. I didn’t want to keep the javascript for this up to date by hand, however, so I wrote a helper plugin called jquery.enabler.groups. It scans the children of the elements matched by the provided selector for a specific custom attribute: data-enabler-group, and assigns an “enabler” to all members of that group. Here’s an example:

<input type="checkbox" data-enabler-for-group="test_group">
<input type="text" data-enabler-group="test_group">
<input type="button" data-enabler-group="test_group">

In the example, the plugin finds the two input elements that have data-enabler-group set. On each of these, it uses the jquery-enable-disable plugin to attach the element that has the matching data-enabler-for-group attribute as their enabler. That way, if the checkbox is toggled, all elements whose data-enabler-group attribute match will toggle their enabled state. Not only that, but it also supports child groups. Take this example:

<input id="main_check_box" type="checkbox" data-enabler-for-group="test_group">
<input type="text" data-enabler-group="test_group">
<input id="subgroup_check_box" type="checkbox" data-enabler-group="test_group"
<input type="text" data-enabler-group="test_sub_group">

Here, if the main checkbox is unchecked, all the elements are disabled, including the test_sub_group members, because their enabler is being disabled. If the main checkbox is checked, the subgroup checkbox is free to enable/disable it’s group members.

That’s going to save me a LOT of very tedious, repetitious coding. After I’ve tried it out for a bit, I might submit the plugin to jquery’s plugin database.

New tools and an update on WSM Calendar

Well, I’m still working on the backend for the WSM calendar.  Every time I think I’m done, I find something else that needs doing.  Steve McConnell was right when he said development was an iterative process.  It’s coming along, though, and I’m learning more every day.

During this project, I’ve recently added two new tools (new to me, not new in existence) to my tool belt.  The first is a new editor.  I had been using Eclipse, which has some really nice features; the problem is the ever-mounting cost to be paid…bloat.  I guess every full-featured editor has it’s share of bloat, but the amount of it in Eclipse is bothering me more and more.  It’s pretty quirky, too—again, common among advanced editors, but it’s really beginning to bug me.  As an alternative, I’m trying NetBeans with it’s PHP plugin.  NetBeans is mainly focused on Java development, but it seems to be working great as a PHP editor.  It has similar features to Eclipse, and it’s quirks don’t seem to bother me much.  In fact, the only one that’s preventing me from doing something I’d like to do is a bug involving it’s Subversion integration.  It doesn’t play nice with gnome keyring (at least in Karmic) but this bug has been acknowledged and is supposed to be fixed in NetBeans 6.9.

NetBeans and Eclipse both have a nice integration feature that I just recently began to use, and this feature brings me to my next new tool: PHPDoc.  It’s a system that allows you to document PHP code in the source itself using special comments.  It’s really quick and easy to learn, and both of these editors are integrated with it such that they can parse/generate the comments for you.  For instance, if you type a function declaration, then go back and start a PHPDoc comment, it generates the skeleton of the function documentation for you.  Very nice!

The only problem I have with PHPDoc is the way it’s generated documentation looks.  The most common way to use it is to specify the HTML template, which turns your comments into static HTML pages.  The thing is, the default theme isn’t very visually appealing.  I couldn’t really find any third-party themes/stylesheets for it (I only searched briefly, though).  Actually, the only thing I’ve found is a template that churns out ExtJS widgets instead of normal HTML elements (at the moment I’m posting this, the website seems to be down).

I’ll eventually play with either the template or the stylesheet and get it to be more readable, but for now I’m just trying to make sure any new classes I code include PHPDoc comments.  Reading nicely formatted documentation is so much easier than opening a source file and skimming for a function just to check out it’s interface.  I don’t know how well this technique would stand up against various ideas about best practice, but I’ve been using the PHPDoc comments as a way to write out a sort of informal, passive version of a contract.  For instance, take the following function for example:

* Given a month (currently only accepts numerics), try
* to return a valid numeric month without leading zeros.
* If a valid month can't be returned, return boolean false.
* @param int $month The month to try to make valid
* @return int|bool
public static function makeNumericMonth($month)
        return false;
    //strtotime allows a month of zero, so we have to test for this manually
    if($month == 0)
        return false;
    if(strtotime("2010-$month-01") === false)
        return false;
    return ltrim($month, "0");

Here I’ve documented the assumptions, restrictions, and behaviors of the function with no “leakage” of the actual implementation.  I realize the danger is that something about the interface of the item being documented may change and the “contract” may not get updated, but that’s always a problem with maintaining documentation.  I figure I’m less likely to forget to update the docs if they’re right there in the code where I can see them.

An online calendar for Winning Side

Well, the smarty project went great.  It’s been done for a while now, but I’ve been too busy/lazy to post recently.  I’ve been grinding pretty hard on my latest project, an online calendar for Winning Side Ministries.

In the ministry, there are several of us preachers involved and we take turns preaching at different events.  There are only two of us that attend every event, and the others come to the events that their personal schedules allow.  This situation creates a bit of confusion and complication when it comes to scheduling.  For the moment we have it all written down on paper, but that’s difficult to keep up with.  It’s also difficult to figure out who’s going to be doing what on a day in the future so you know if you need to make arrangements before you miss an event.

This led me to start the creation of an online calendar system that would run on the website.  Each event would have it’s own schedule, and could be calculated based on a certain date each month, a certain day every week, or a certain numbered week-day of the month (eg, the 3rd Friday of every month).  In addition, “exceptions” can be made to alter a specific occurrence of an event, or to create a one-time special event at any time.

I guess the project’s going OK, but slow.  I have this (unfortunate) hatred for spending large amounts of time designing classes and API’s and such, so I end up doing a lot of flying by the seat of my pants then re-doing things that I’ve done the wrong way.  I have especially been doing this a lot with the messaging system.  Since this will be an interactive part of the website, I need not only to have logging capabilities but also a way of getting errors/warnings to the user.  What I ended up with is a standard message dispatcher type system where any class that wants to receive message simply subscribes as a listener, and the messages are broadcast as soon as they are received.

The way I decided to get messages to the user was to store them in the $_SESSION superglobal.  I chose this because the messages needed to be attached to the session, and what better way to do it?  I couldn’t really justify writing a custom session handler to do something that PHP/HTTP could do natively.  The class that handles this keeps an ID that is passed to the constructor to keep messages from different systems separate, and it stores messages using this ID.  For instance, my calendar’s ID is “calender”, so messages are stored in an array that lives in $_SESSION[‘messageArray’][‘calendar’].

I had a funny quirk when designing this…I originally used $_SESSION[‘messages”], but that exhibited strange behavior.  For one thing, it was constantly getting cleared.  I don’t know if it was due to another random bug in my code or what, but the problems went away when I changed “messages” to “messageArray”.  I searched google to see if that was some special HTTP thing, but the only hits I got were from drupal.

I don’t know, but it works now.  😉

I’ve got some cleaning up to do in the code now that I’ve got the design nailed down (I think) and then it’s off to designing the front-end.  Hurray!

Also, thanks to Balsamiq for a free NPO license for Mockups.  It’s a real help!