June, 2006

Flock Me! Flock releases OSX beta of cool new Web 2.0 Browser

Thursday, June 15th, 2006

Flock has released their first public beta of their browser, now available for Mac, Linux and Windows. It can be downloaded here. Flock is a Firefox-based browser that offers a “social browsing” experience that involves heavy interaction with the web rather than just passive browsing.

Flock has a slew of features but the ones that do it for me are easy photo sharing (Flickr and other services) including drag and drop upload, searchable bookmarks (good del.icio.us integration) and blogging. I’m composing this with the Flock WYSIWYG blogger tool now. It seems to be solid, useful and fun. I think it is about to become my default browser!

Blogged with Flock

Musings on Managing Static Resources in WebObjects Applications

Saturday, June 10th, 2006

When we refer to “Static Resources” in dynamic web-based applications, we are referring to publicly visible content files that are not dynamically generated or produced by the software. Usually these are image, CSS , or stand-alone HTML files. There are several approaches to handling static resources in WebObjects, each with its own advantages and drawbacks. The three approaches discussed below are probably the most straightforward.

First Approach: Add Resources to your Xcode Project’s Application Server Build Target

This is perhaps the easiest approach. Adding one or more resources is accomplished in Xcode by using the ‘Project’ drop-down menu and clicking on ‘Add To Project’. Select the images or other files you wish to add on the first pop-up sheet. On the second pop-up sheet, under ‘Add To Targets’ check Application Server. Check the ‘Copy items…’ checkbox if the resources do not yet currently reside inside the project folder.

Once the project contains the resources and is aware of them, you can simply refer to them by name when doing bindings in WOBuilder. At the time of deployment the resource files are included inside the application “.woa” bundle which is installed in /Library/WebObjects/Applications. Inside the bundle the resources are in /Contents/Resources. Since the files are not in the webserver documents area, Apache (or another webserver) cannot vend them directly. The URL calls the WO application and the WOResourceManager finds the image (or other resource) and returns it.

Although this approach is easy, the WebObjects application is involved in generating each image URL and is also required to make a response for every image displayed. Also, in certain circumstances, the ability for the webserver to cache images is disabled (since the URL can change each time).


Second Approach: Add Resources to your Xcode Project’s Web Server Build Target

Adding resources is just as easy as the first approach - under ‘Add To Targets’ you just check Web Server.

WOResourceManager is still consulted when doing page generation to create the full path, since the WO template contains only the file name.

This second approach is Apple’s recommended default solution, though there are some issues I will discuss.

Where do the files go when you deploy? You have to do some special tricks when deploying to manage this (Called a “split install”). A special bundle is created, called the same as your application (i.e. “MyApp.woa”), that contains all the webserver resources but none of the executable code, and this goes in the WebServer Documents directory, in a directory called WebObjects. The resource files now have a static location that is publicly visible.

What do URLs look like?
“/WebObjects/MyApp.woa/Contents/Resources/header.jpg”

The main advantage of this approach is that the webserver serves images directly and the images can be locally cached. On the other hand, doing split installs takes some extra work and needs to be done carefully. Moreover, URLs are long (adding size to HTML files). Lastly, images are ‘filed’ in directories that correspond to a particular application and are more difficult to share (yes, you can create a framework to be loaded by multiple applications. But if any of the resources are used by non-WO content this gets unwieldy).

Third Approach: Store Resources Externally to your Project

In this approach, all images and other resources are kept external to the project and are not ‘managed’ by Xcode. They are stored in a subdirectory of the the webserver document root and are always accessed via the webserver.

On the up side, this approach results in the best performance of the three and it scales well. When the number of distinct image files becomes very large, you can further ensure good performance by creating a directory tree and distributing images across the tree. Images (and resources generally) can be shared between applications and with static html pages. Finally, when outside graphic designers are involved in a project they can manipulate image files directly without the need for someone to rebuild application bundles.

On the other hand, this third approach requires a bit more effort from developers. Unlike the other two approaches, the names of the resources do not show up WOBuilder. Potential problems can arise as developers enter image file names in component bindings, sometimes misspelling them. However, if the images are installed locally in the webserver document root, WOBuilder will render them immediately, so you get feedback right away if you make a typo.

The trick I use for this is to create a Static Resources directory adjacent to my project directory and create a symbolic link to it from the webserver document root. This allows me to do an update or commit to my source code control system from the directory containing the project and the resource directories to update or commit them both at the same time. Once the link is in place I can forget (on my development machine anyway) about updating the webserver content.

Summary

My personal favorite is approach number three. CodeFab’s development projects almost always get large and complex enough that there are resources that need to be shared beyond what a WO framework provides. Additionally we often end up with static HTML pages, CSS files, JavaScript files, etc. that do not really belong inside the project. Your personal mileage may vary.

All three of the approaches discussed here are in wide use. Based on the requirements of a particular application, we recommend that you chose one of them and stick with it. Especially on projects with multiple developers it is a good idea to make this system architecture decision early and make sure everyone understands it.

WOUnitTest: Refactor Without Fear

Monday, June 5th, 2006

Abstract

Test-Driven Development (TDD), a core Extreme Programming (XP) practice, creates fluid, clear code with fewer bugs. JUnit is great for testing non-WO Java code, but for WebObjects applications you need WOUnitTest, which allows you to easily test enterprise objects.

Refactor Without Fear

by Apoorva Muralidhara

In early 2000, as I was joining Codefab, I read Martin Fowler’s Refactoring: Improving the Design of Existing Code and Kent Beck’s Extreme Programming Explained: Embrace Change. I was captivated by the idea of reworking code in small steps while preserving behavior, instead of throwing it away and rewriting it from scratch. Fowler and
Beck explained that refactoring necessitated automated unit tests. So I decided to try test-first programming (now called Test-Driven Development (TDD)), merciless refactoring, and pair programming. Over the past six years, I’ve found that TDD does indeed create code that’s better designed and more maintainable, with higher quality.

Automated unit tests set up objects, call methods, and make assertions that pass or fail. Many test GUI’s use a green bar to indicate that all tests pass, and a red bar to show that at least one test has failed. “Keep the bar green to keep the code clean,” as the JUnit site says–all test must pass at all times in the committed version of the code.

The TDD coding cycle is “red-green-refactor”:

Red: Write an automated unit test, and watch it fail, because the functionality has not been implemented. Writing the test first checks that the desired new behavior isn’t already there, and that you’re actually testing it. It also means that the code you’re about to write already has a client that exercises it, and which documents its intended use. And it forces you to do the thinking about this method’s interface and expected behavior before writing it–you decide what needs to be done before deciding how to do it. When I first heard of “test first,” it sounded very strange–but after just a few days the idea of writing the test after the code started to sound strange. Note that in a static language like Java, you’ll have to write stub versions of methods just to get the code to compile so that the test fails.

Green: Write just enough code to make the test pass. Here’s one advantage of writing the test first–the change from red to green means something important. It shows that your production code actually does what you asserted it should do. All tests should now be green, so you can integrate your changes with the repository head and commit it. One XP practice is Continuous Integration–commit as often as possible, and avoid “integration hell.”

Refactor: All tests pass. Refactor to remove what Martin Fowler calls “code smells,” including Long Method and Duplicated Code smells. After each small modification, following the patterns in Fowler’s Refactoring, rerun the tests to ensure you haven’t broken anything. You can commit whenever the test bar is green, so commit often. I highly recommend Fowler’s book, which you can read like a novel (or short story collection), but which will transform your thinking about the actual process of coding.

Keep the code clear with explanatory method and variable names. Good design emerges incrementally, sans overengineering–because you refactor mercilessly, but only implement what you need at the moment. Your unit tests allow you to refactor without fear. Your code is no longer static, brittle because you’re afraid to break anything by touching it. It’s dynamic, fluid, adapting to new requirements and better design.

WO-friendly Unit Testing

In 2000, my pair programming partner and I used JUnit as best as we could to test our WebObjects applications. JUnit is a great tool for testing ordinary Java code, but WebObjects applications have, for example, editing contexts, applications, and sessions, which JUnit, in its innocence, knows nothing about. So we tested WO apps from the outside by firing direct actions.

But the closer your tests are to the code they test, and the less dependent they are on other code, the more effectively they isolate and catch bugs. We needed a way to test smaller pieces of code, from the inside of a WebObjects application.

Most WebObjects applications use a database, but it’s best not to do so in your tests. The database round trip slows down your tests: if each test takes half a second to run, then six hundred tests–not high for a TDD project–will take five minutes, destroying agility. If you
*must* connect to the database, use an empty test copy with no rows, and populate and clear it at the beginning and end of each test run, so its state is predictable, and the setup code makes it clear what data your test needs. Unfortunately, we didn’t know that six years ago. So our tests ran against the “real” (development) database, and often broke when the data changed.

Then two Codefab developers, Christian Pekeler and Shin Ogino, created WOUnitTest, which Christian has maintained and greatly enhanced over the last few years.

WOUnitTest extends JUnit to make it more WebObjects-friendly. Instead of subclassing JUnit’s TestCase, you subclass WOUTTestCase.

You can test an EO’s validation without saving it with one of the following methods:

    assertValidForDelete()
    assertValidForInsert()
    assertValidForSave()
    assertValidForUpdate()

    assertInvalidForDelete()
    assertInvalidForInsert()
    assertInvalidForSave()
    assertInvalidForUpdate()

But what if you’re writing a method that creates or fetches EO’s? How do you test this code without using a database? To solve this problem of external dependencies, Tim Mackinnon, Steve Freeman, and Philip Craig developed Mock Objects, introduced in their paper at XP2000, Endo-Testing: Unit Testing with Mock Objects[PDF]. Like Lewis Carroll’s Mock Turtle, which is no longer a real turtle, a mock object pretends to be an object in the production code, but it fakes the functionality which depends on an external system–in this case the database.

We WO developers are fortunate–we use a well-designed object layer, EOF, to hit the database. (Try testing without a database in PHP!) WOUTTestCase gives you a mock object, MockEditingContext, that subclasses EOEditingContext, but doesn’t actually access the database. MockEditingContext has a createSavedObject() method which inserts an object into the receiver with a non-temporary global id, as if it’s been saved. It has an objectsWithFetchSpecification() method that “fetches” from its registeredObjects() instead of hitting the database. To get the provided mock editing context from a WOUTTestCase subclass, just call mockEditingContext(). And if you must hit the database, use editingContext() will give you a real editing context.

WOUTTestCase is aware of WebObjects in other ways–for example, If you need a WOComponent instance, just call pageWithName().

If you expect your production code to return an NSArray of objects, with order irrelevant, you could use JUnit’s assertEquals(), adjusting the expected value’s order so the test passes. But this risks spurious test failures when something changes that affects order, which you don’t care about anyway. Or, you could sort the array your production method returns, so that the order is predictable. But this causes you to sort objects whose order you don’t really care about. The best solution is to use an assert method that doesn’t care about order, and Christian provides these in WOUTTestCase:

    assertArraysEqualAsBags()
    assertArraysNotEqualAsBags()

OstrichWorld: An Example

Suppose an ostrich farm needs a WebObjects application so they can vend their flightless birds to the online masses as convenient household pets. Your EOModel will include a Ostrich entity with a name attribute, and you need a Ostrich.createOstrich() method.

In OstrichTest.java, don’t hit the database–just use mockEditingContext():

import com.webobjects.foundation.*;
import com.webobjects.eocontrol.*;
import com.webobjects.eoaccess.*;

import com.ostrichworld.eo.*;

public class OstrichTest extends WOUTTestCase {

    public void testCreateOstrichCreatesOstrichWithNewName() {
      String newName = "Brunella";
      assertEquals(0, EOUtilities.objectsMatchingKeyAndValue(mockEditingContext(), "Ostrich", "name", newName).count());
      Ostrich newOstrich = Ostrich.createOstrich(mockEditingContext(), newName);
      assertEquals(1, EOUtilities.objectsMatchingKeyAndValue(mockEditingContext(), "Ostrich", "name", newName).count());
    }
}

Then you can implement Ostrich.createOstrich() as follows. I hope you’re using EOGenerator to separate your auto-generated EOF Java files from your custom EOF subclasses:

package com.ostrichworld.eo;

import com.webobjects.foundation.*;
import com.webobjects.eocontrol.*;
import com.webobjects.eoaccess.*;

import com.codefab.wounittest.*;

public class Ostrich extends _Ostrich {

    public static Ostrich createOstrich(EOEditingContext editingContext, String name) {
        Ostrich ostrich = (Ostrich)EOUtilities.createAndInsertInstance(editingContext, "Ostrich");
        ostrich.setName(name);

        return ostrich;
    }
}

Should an ostrich have a null name? Of course not! You could enforce this by setting the “allows null” flag to false on the Ostrich.name attribute in the EOModel. Or you could check this is in a validation method on Ostrich.

If you want to do this in validateForSave(), you can use assertValidForSave() and assertInvalidForSave():

String name;
Ostrich ostrich;

protected void setUp() throws Exception {
    super.setUp();

    ostrich = (Ostrich)mockEditingContext().createSavedObject("Ostrich");
    name = "Bartholomew";
}

public void testValidateNameForSave() {
    ostrich.setName(null);
    assertInvalidForSave(ostrich);

    ostrich.setName(name);
    assertValidForSave(ostrich);
}

To do this in validateName(), you can use the same setUp(), but unfortunately there’s no assert method that calls validateValueForKey() for you–you’ll have to do it yourself. I’d use two tests for this:

public void testNullNameIsInvalid() {
    try {
        ostrich.validateValueForKey(null, "name");
        fail("Null name was valid!");
    } catch (NSValidation.ValidationException exception) {
        assertTrue(true);
    }
}

public void testNonNullNameIsValid() {
    ostrich.validateValueForKey(name, "name");
}

Yes, I know the second test doesn’t contain an assert. What it’s implicitly asserting is that calling validateValueForKey() doesn’t throw an exception.

These are extremely simple examples, but you can set up many different objects with mockEditingContext().createSavedObject(), link them with addObjectToBothSidesOfRelationshipWithKey(), and assert many things with WOUTTestCase’s methods.

Getting WOUnitTest

Once you have JUnit, download WOUnitTest from Sourceforge and unarchive it.

The WOUnitTest directory you’ve downloaded includes a README.txt, which explains how to build and install the WOUnitTest framework. Then you just add the WOUnitTestFramework and you’re ready to write subclasses of WOUTTestCase, as in the examples above.

Run your WebObjects application, and fire the direct action “ut” (”unit test”) to bring up a Web interface for running your tests, or “uta” (”unit test all”) to run all tests. Live by the green bar; die by the red bar.

Conclusion

WOUnitTest makes it easier to do test-driven development of WebObjects applications, leading to more maintainable code with fewer bugs. The most important thing it gives you that plain JUnit doesn’t is an easy way–actually several easy ways–to test EO’s without accessing the database. Go forth and develop–test-first!