Proofing the App

Image of old Magic Yeast product

I wanted to make calzones for dinner last night.  It was getting late, but in my mind I could already see the ricotta and broccoli filling and smell the melted cheese.  I usually buy a blob of dough from one of the local pizza places, but this time I was going to start from scratch.  The yeast, though, gave me pause: would it rise?

In baking, there’s a concept of proofing the yeast.  A baker is never certain that the yeast is still active, and it’s a sad day to anticipate and work on bread only to find a small hard lump of unrisen dough at the bottom of the bowl.  So before kneading in flour, the yeast is mixed with water and sugar.  If bubbles form, it’s working and you carry on; if it stays flat, you toss it out and avoid heartbreak.

My yeast did foam, but so slowly that I would have been eating my calzones somewhere around midnight.  So instead I shifted gears and made soft buttery pretzels, which don’t need to rise for so long, and they were delicious.

What’s the connection to software development?  App ideas need planning and proofing, too.  There’s little worse than spending large amounts of time and money creating a beautifully finished product only to watch it lie unused.  That expenditure might be avoided with development’s form of sugar and water: requirements, design, prototyping, and a minimum viable product. (more…)

Adding Dynamically Named Methods to Python Classes

Photo by Inbetween Architects on Unsplash

I recently wanted to dynamically add methods to a Python class based on a list of relationships. The model class, Animal, was related to a number of description classes like Color and Sound. For a given animal, I wanted to be able to easily get the values for its descriptions, such as:

elephant.color_values()
# => ['gray', 'silver', 'taupe']

Although I could have simply written non-dynamic methods like color_values, noise_values, etc. in the Animal class, I had already defined a list of the relevant class names and I prefer not repeating code. So instead I dove into Python’s dynamic pool.

(more…)

Upsource: New Code Review Tool

I have a special place in my heart for web apps that make coding management easier.  This week, my crush is Upsource, a new code review tool (and source code repository browser) that’s in a semi-public alpha period.

It looks to have a great interface for:

  • starting ad hoc reviews or requesting reviews
  • looping in other people to discuss or watch the review
  • linking to reviews or multi-line selections
  • adding new code revisions to an ongoing review (more…)

Factories, not Fixtures

Rosie the RiveterFor years, the most common way to provide test data for automated tests has been fixtures – hard-coded values, usually stored in text files.  For example, here’s some YAML-formatted data for a city model object:

- model: city
  fields:
    id: 1
    name: Los Angeles

In an environment like a Django app, this fixture would typically be loaded into a test database, and then accessed like:

la = City.objects.get(id=1)

.

But fixtures and the frameworks that rely on them have several drawbacks:

Their data is brittle, especially when including references like unique IDs.  Changing or adding a property later may break tests.  This drawback also means that they are not easily modifiable, which tends to lead to duplicate fixtures with unwieldy names like

los-angeles-with-an-extra-long-name.yaml

.

They are typically loaded en masse by test frameworks like Django’s.  This can be slow if many unnecessary fixtures are being loaded for each unit test.  It also creates brittle sets of data.  For example, if an automated test is searching for objects with a matching city name and expects to find one instance, but later a new fixture is added that also matches, the test will fail.

Because fixtures are typically automatically loaded into a database by the test framework, it’s not particularly easy or fast to change the properties of an object for a single test case, which also tends to lead to an over-abundance of fixture files.

Factories, not fixtures

Test data factories solve these problems by making data and data loading more dynamic and programmable.  A factory is written in code, and while it can simply mimic a fixture by supplying default values for an object, factory libraries offer many other useful features.  Here’s a simple example factory:

Factory.define('city', City)
  .sequence('id')
  .attr('name', 'Los Angeles')

An instance of this factory could be created on the fly like:

la = Factory.build('city')

.

Following the builder pattern, a factory generates data for all the attributes in its definition, constructs any necessary associated objects, and allows a test case to override these values.  Here’s a slightly more complex example:

Factory.define('city', City)
  .sequence('id')
  .attr('name', 'Los Angeles')
  // Define 'ref' as dependent on the id and name properties
  .attr('ref', ['id', 'name'], function(id, name) {
    return id + '-' + name;
  })

nyc = Factory.build('city', {name: 'NYC'})

Some typical features in factory libraries are:

  • integration with common ORMs;
    Factory.create(...)

    will typically build and save the object to a database

  • factory inheritance, allowing similar factories to share properties; e.g.
    Factory.define('city').extend('Olympic').attr('year', null)
  • lazy attributes; e.g.
    .attr('created_at', function() { return new Date(); })
  • associations to other factories

Factories across languages

Factory libraries have been springing up over the past handful of years.  Ruby’s factory_girl, which has been cloned to many other languages, was first released in 2008.  Several new ones for JavaScript and Objective-C have just appeared this year.

Here’s a list of factory libraries for a variety of common languages:

Test data for unit tests

A note of caution: a one line factory invocation may hide a great deal of complexity and database integration.  That may be fine for integration tests, but should be avoided for unit tests (see the blog post Factories breed complexity for a lengthier discussion).  Prefer to use simpler, non-persisted objects in unit tests.  Factory libraries may help here too by returning just the attributes as a hash or dictionary; e.g. factory_girl’s attributes_for method.

Geopolitical Consequences of SQL Design

Or: the consequences of not using many-to-many relationships.
1024px-1829_Lapie_Map_of_the_Eastern_Mediterranean,_Morocco,_and_the_Barbary_Coast_-_Geographicus_-_Barbarie-lapie-1829

Cuisine menu
Is Moroccan food African or Mediterranean?  We designed a simple hierarchical model of cuisines that grouped them by broad geographic area.  The purpose of the model was solely to populate a configurable, organized list for a select menu, where smaller areas were visually grouped. (more…)