1991-2016—25 years of Art & Logic

2014 Review: Day 3

As 2014 winds down, we’ll take an opportunity to look back at some of our most-read posts from this year, in case you missed them the first time. 

 

4319953731_fa8659d820_b

 

Steve Huey took us on a quick tour of a key/value store for iOS that’s built on top of the ubiquitous Sqlite:

(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.

YapDatabase – A Great SQLite-Based Alternative to Core Data

Synchronization and Core Data in Modern iOS Apps

I’m working on an iOS project that synchronizes a lot of data between a web service and an iPad app. We’ve relied on the advice and research in the fantastic issues of objc.io on Core Data and Syncing Data along with performance recommendations from Florian Kugler’s research into Core Data stack configuration and overall the solution is working pretty well for us at this point, but it hasn’t been without its challenges.

4319953731_fa8659d820_bThroughout the project I’ve been trying to follow industry news and research to keep up with best practices, interesting sync experiments, and usage of Core Data in iOS 7. A recurring question in much of this is whether to use Core Data at all, and if not what you give up and what can you possibly gain in the process?

Brent Simmons’ series of Vesper Sync Diary posts (linked to below) cover this design and decision process in incredible detail and are well worth the read, culminating with his Hard Core post where he ultimately decides to go ahead with a SQLite based solution instead of using Core Data. When using SQLite the go to solution for Mac or iOS is Gus Mueller’s excellent fmdb framework, however another SQLite based solution with a higher level API and different approach has emerged that is well worth a look too, called YapDatabase. (more…)

Digging Into the Objective-C Runtime

Digging to China.

image via http://www.flickr.com/photos/martiniglistens/

Greg Parker recently tweeted a link to fantastic site he created, An Illustrated History of objc_msgSend, that provides a trip through history of one of the likely most often called, but unheard of functions in iOS or OS X, objc_msgSend. The function dates back to NeXT and the origins of Mac OS and iOS. It’s interesting to see how it has evolved through the versions of the OS, the transitions between processor architectures, and how priorities in the algorithm have changed as hardware has. It was the underpinning of the Objective-C runtime back on those first PowerPC based Macs and still is today on the latest A7 based iOS devices. Incredible.

If you want to learn more about the Objective-C runtime it’s actually open source and is available from Apple’s open source site at objc4-555.1. To go along with the source Apple provides the Objective-C Runtime Programming Guide and Objective-C Runtime Reference. Definitely read through these and take the time to learn more about how the runtime and your modern Objective-C code are related.

Outside of Apple’s documentation, perhaps the best series of posts on the Objective-C runtime and how you can use it are by Mike Ash. Despite the fact that they date back to 2009 and 2010, they’re still very relevant today.

Finally, if you’re looking to do some hacking on the runtime itself, or experiment with patterns and practices from other languages check out libextobjc by Justin Spahr-Summers, one of the Mac developers at GitHub.

Thanks again to Greg Parker for the retrospective, his time spent hacking away on the runtime, and for the inspiration for this post!