Tuesday, December 29, 2009

FoneMonkey: The Download

Tonight I am releasing FoneMonkey into the wild. Without further ado, here it is:

FoneMonkey.zip

The iPhone does not yet allow installation of user-defined frameworks, so FoneMonkey is disbributed as a static library along with the image files and nibs required by the FoneMonkey user interface. FoneMonkey.zip contians libFoneMonkey.a as well as a bunch of png and xib files.

The zip file does not include the FoneMonkey source code, which we'll be releasing when we officially launch the FoneMonkey open source project in mid-January, 2010 (ie, just a few weeks from now!). At that time we'll be going live with a community forum as well. Until then, please post questions or comments to this blog.

To get started using FoneMonkey, download the zip file and extract the FoneMonkey distribution folder. Then follow the instructions below.

Happy testing! We look forward to your feedback!

Testing an iPhone application with FoneMonkey

In order to test an iPhone application with FoneMonkey, you must first link FoneMonkey with your application as shown in the 2-minute video below. Step-by-step textual instructions are also provided here.

You might need to view the video in a new window.




  1. Open your application's project in xcode.
  2. Duplicate your application's build target by right-clicking on it and selecting Duplicate from the menu. A new target will be created called YourApp copy.
  3. Rename YourApp copy to something like YourAppTest.
  4. Add the downloaded FoneMonkey folder to your project by right-clicking on the project and selecting Add > Existing Files... from the menu. Navigate to the FoneMonkey folder, select it, and click the Add button.
  5. When the dialog box appears, select the Recursively create groups for any added folders option.
  6. In the Add to Targets box, deselect YourApp and select YourAppTest.
  7. Click Add.
  8. Right-click on the YourAppTest build target and select Get Info from the menu.
  9. On the General tab, delete libFoneMonkey.a from the Linked Libraries. You will need to add CoreGraphics.framework and QuartzCore.framework to the Linked Libraries list they aren't already there.
  10. On the Build tab, scroll down to the Linking section and click on the Other Linker Flags setting. When the dialog box appears, enter:

    -ObjC -lFoneMonkey -LFoneMonkey/lib -all_load

  11. Dismiss the project Info window.
  12. Right-click on YourAppTest build target and select Clean from the menu.
  13. Right-click on YourAppTest build target again and select Build and Debug from the menu.
  14. Your application should start in the simulator. Immediately after it displays, the FoneMonkey console should drop down over it.
  15. See this post for more info about recording and playing back tests with FoneMonkey.

Wednesday, December 16, 2009

FoneMonkey: The Movie

In this video, recently smuggled from Gorilla Logic labs deep beneath the surface of the Earth, we see the revolutionary new open source, iPhone application testing tool FoneMonkey recording and playing back interactions with an application that was cobbled together from Apple's UICatalog and GLPaint sample applications (which together are comprised of most of the iPhone SDK UI Components).

The video demonstrates FoneMonkey recording and playing back various actions including button touches, table scrolling and selection, switches, sliders, text entry, tab selection, finger dragging (in this case, painting), and even phone shaking (which is the gesture that causes GLPaint to erase the current painting).

You might need to view this video in a new window.



As you can see, the monkey can really dance. I hope to post the library binary and installation instructions within the next few days.

Sunday, December 13, 2009

FoneMonkey: Open Source, Testing Tool for iPhone Applications

This blog post is the first announcement to the world of FoneMonkey, an open source iPhone testing tool that I've been developing for the last several months. FoneMonkey automates iPhone application testing by recording and playing back user interactions, and verifying the results. FoneMonkey was inspired by FlexMonkey, the open source Flex testing tool I wrote a little more than a year ago, and which has subsequently been significantly enhanced by my colleagues at Gorilla Logic, especially Eric Owens. Today FlexMonkey has more than 4,000 registered users and an active community.

We plan to release FoneMonkey source and binaries (with attendant fanfare) in early January. Here's a sneak preview of what's coming.

Some Technical Background

FoneMonkey has been more challenging than FlexMonkey to create because the iPhone SDK, unlike the Flex SDK, provides no Automation API. Before I could develop FoneMonkey, I had to develop an automation framework. The resulting FoneMonkey API is simple, extensible and initially supports nearly all native iPhone (ie, Cocoa Touch) components.

Like FlexMonkey, FoneMonkey is designed to be used by both programmers and QA testers. Rather than simply recording and playing back low-level events, FoneMonkey records "semantic" events. In other words, FoneMonkey doesn't record that you touched a pixel at coordinate (125, 210), but instead records that you selected table row 5. The resulting scripts are relatively forgiving with respect to cosmetic UI changes. They can also be composed from scratch by directly specifying sequences of commands. (FoneMonkey Command Guide coming soon....).

Each FoneMonkey command is composed of a command name, a component identifier, and a set of command-specific arguments. For example:

Touch UIButton Send (touches the UIButton labeled "Send")
InputText UITextField, your name, Fred (types "Fred" into the UITextField with a field prompt of "your name")

The Flex Automation API provides an AutomatDelegate corresponding to each Flex UIComponent, and a delegate instance is created for each UIComponent instance created at run-time. Automation delegates subscribe to their component counterparts for all UI events, and translate these low-level keyboard and mouse events into high-level component events. FoneMonkey uses a logically similar mechanism, but is instead implemented with Objective-C categories that extend UI component classes with record and playback logic.

While recording, the FoneMonkey framework monitors all UI events and forwards them to the FoneMonkey category methods that provide recording for each component class. During playback, FoneMonkey sends each command to the playback methods also provided by the class's FoneMonkey extension category.

The FoneMonkey framework provides categories that record and play back events for instances of the UIView class and all UIView subclasses. It is straightforward to create a category for any custom UI class that requires custom recording and playback logic, or to further enhance the recording and playback logic provided out of the box by the FoneMonkey framework. (FoneMonkey Extension Guide coming soon....)

Using FoneMonkey

To test an application, you simply statically link it with the FoneMonkey library. (FoneMonkey Setup Guide coming soon....) Upon starting your application, the FoneMonkey Console "drops down" over your application window, displaying the recording and playback controls at the bottom of the screen.


The Elements application



The Elements application with FoneMonkey controls (at the bottom).


The video below shows FoneMonkey being used to test Apple's "The Elements" sample application.

In the video, we touch the record button to hide the FoneMonkey Console and begin recording our interactions with "The Elements" application. FoneMonkey monitors for periods of inactivity and drops back down over the application if we stop interacting with it for more than the current inactivity timeout setting (by default, 2.5 seconds). Touching the play button replays the recorded script.

You might need to view this video in a new window.


FoneMonkey provides the ability to edit scripts and save them for later replaying.


The FoneMonkey script editor

You can add Verify commands to a script to test the values UI component properties or the values of associated object properties (ie, you can use a key-value encoded key path) . In The Elements sample application, a custom class called AtomicElementView is used to display data for the currently selected element. The AtomicElementView has a property called element that references an instance of the AtomicElement class, which in turn as a property called name. In the Verify command below, we test that the current AtomicElementView's element.name has a value of "Lead".

Adding a Verify command to a script

Script results with failed Verify (in red)

The next video shows how to edit a script, add a verify command, save the modified script, and then replay it.

You might need to view this video in a new window.



Over the next several weeks I'll be continuing to update the doc in preparation for our putative January launch. Stay tuned.