Tuesday, November 30, 2010

Using Boost in Ubuntu with Eclipse

Boost is an open source library of extremely useful and carefully designed C++ classes and methods ranging from graph algorithms, to regular expressions matching, to multi-threading.
Part of the Boost library was also integrated into the C++ standard as the TR1 set of libraries.
You can learn more about Boost here.
Using it with Eclipse in Ubuntu is definitely possible, but not straightforward; so I decided to post this simple tip here, to help folk spare some of the grief.
The first step in using Boost in your code is to download the header (.hpp) files and (optionally) source code - the latest release is 1.45 and is available from Boost's website.
In theory, you could compile it, and build the libraries' binaries yourself: by all means, go ahead and do it, but there is an easier way, if you can live with a slightly 'older' version.

Ubuntu 9.10 (Karmic Koala) comes with Boost 1.34 pre-configured (I think, this is, at any rate, the version that I had on my system):
$ ls /usr/lib/libboost*
/usr/lib/libboost_date_time-gcc41-1_34_1.so.1.34.1
/usr/lib/libboost_date_time-gcc41-mt-1_34_1.so.1.34.1
/usr/lib/libboost_date_time-gcc42-1_34_1.so.1.34.1
/usr/lib/libboost_date_time-gcc42-mt-1_34_1.so.1.34.1
/usr/lib/libboost_filesystem-gcc41-1_34_1.so.1.34.1
/usr/lib/libboost_filesystem-gcc41-mt-1_34_1.so.1.34.1
/usr/lib/libboost_filesystem-gcc42-1_34_1.so.1.34.1
/usr/lib/libboost_filesystem-gcc42-mt-1_34_1.so.1.34.1
/usr/lib/libboost_iostreams-gcc41-1_34_1.so.1.34.1
/usr/lib/libboost_iostreams-gcc41-mt-1_34_1.so.1.34.1
/usr/lib/libboost_iostreams-gcc42-1_34_1.so.1.34.1
/usr/lib/libboost_iostreams-gcc42-mt-1_34_1.so.1.34.1
/usr/lib/libboost_regex-gcc41-1_34_1.so.1.34.1
/usr/lib/libboost_regex-gcc41-mt-1_34_1.so.1.34.1
/usr/lib/libboost_regex-gcc42-1_34_1.so.1.34.1
/usr/lib/libboost_regex-gcc42-mt-1_34_1.so.1.34.1
/usr/lib/libboost_signals-gcc41-1_34_1.so.1.34.1
/usr/lib/libboost_signals-gcc41-mt-1_34_1.so.1.34.1
/usr/lib/libboost_signals-gcc42-1_34_1.so.1.34.1
/usr/lib/libboost_signals-gcc42-mt-1_34_1.so.1.34.1
/usr/lib/libboost_thread-gcc41-mt-1_34_1.so.1.34.1
/usr/lib/libboost_thread-gcc42-mt-1_34_1.so.1.34.1

However, by using Synaptic, you can actually install the more recent 1.40.0 version:


This will install a bunch of libboost_*.so.1.40.0 files into /usr/lib: in order to match the libraries with the header files (and avoid introducing incomprehensible compilation errors at best, and subtle bugs at worst) you should download the matching boost_1_40_0.tar.bz2 from Boost download archives.

We would be almost there, were it not for the fact that the soname does not really comply with the -l gcc linker option.

In gcc the -L option specifies a 'search directory' (this would not be needed, as /usr/lib is searched for libraries by default) and the -l specifies additional dynamic (.so) or static (.a) libraries: you specify the file to include during the link step by omitting the `lib` prefix and the .so or .a extension.
In other words, if your HelloBoost source uses code from Boost Regex (libboost_regex.so) you would specify it like thus:
$ gcc -Wall hello_boost.cc -o HelloBoost -lboost_regex

You can see where I'm heading with all this: the last step will be to add symbolic links that do away with the soname suffixes of Boost libraries, and all will be well:
$ ln -s /usr/lib/libboost_regex.so.1.40.0 /usr/lib/libboost_regex.so

Given that there are in total 24 files for the whole of Boost 1.40, I've done a bit of find & replace magic, and have come up with the following shell file (the other advantage being that, when a later version becomes available for Ubuntu, I will not have to change any of my Eclipse projects setting, but just change the VERSION value in the script):
#!/bin/bash
#
# Simple script to enable Boost with simple -l gcc option
# Use: gcc -Wall hello_world.cc -o HelloWorld -lboost_regex
#
# Created by M. Massenzio, 2010-11-30

VERSION=1.40.0

for libname in libboost_date_time \
            libboost_filesystem \
            libboost_graph_parallel  \
            libboost_graph      \
            libboost_iostreams  \
            libboost_math_c99f  \
            libboost_math_c99l  \
            libboost_math_c99   \
            libboost_math_tr1f  \
            libboost_math_tr1l  \
            libboost_math_tr1   \
            libboost_mpi        \
            libboost_prg_exec_monitor \
            libboost_program_options  \
            libboost_python-py25      \
            libboost_python-py26      \
            libboost_regex            \
            libboost_serialization    \
            libboost_signals          \
            libboost_system           \
            libboost_thread           \
            libboost_unit_test_framework \
            libboost_wave \
            libboost_wserialization 
do
  ln -s /usr/lib/$libname.so.$VERSION /usr/local/lib/$libname.so
done


The last and final step is to tell Eclipse what to look for when building your binary: right-click on your project's folder (in the C++ Perspective, Project Explorer) then Properties > C/C++ Build > Settings, select GCC C++ Linker > Libraries and add the 'stripped' library names in the option list:


Note for the curious: the additional libraries listed there are for Google C++ Unit testing framework, GUnit, available here - you will have to build it, but that's pretty straightforward, resulting in the two libgtest.a and libgtest_main.a libraries - be careful to add those only to your 'Test' configuration and exclude your unit tests from build in your Release/Debug configurations.

Tuesday, November 23, 2010

Using the same model classes in Android, GWT and JPA

These days, it is rather common to have a mobile-enabled web service or application, where you essentially enable your users to access the service both via a browser-enable desktop application, as well as from their mobiles whilst on the go.


It's usually the case that the main business logic, as well as the business Model, are shared between the browser components and your mobile app: however, it is not obvious how to re-use code (or even use the same source code) when you are essentially using two completely separate SDKs, and even different JREs!


In fact, if you are using Google Web Toolkit on the front-end, there's not even a JRE involved: as your classes will be compiled in JavaScript.


This short video shows how you can actually use the very same source files in all three layers, so that when you make changes (fix bugs, add functionality) the improvements are immediately reflected everywhere - and even better, you avoid subtle bugs that may be caused by inadvertently the code going "out-of-sync" in one of the layer.


The example is based on my Android Receipts application, which can also be freely downloaded in Android Market.



Please let me know what you think, and whether you are finding the videos useful - or you prefer the written word!


Update    Someone commented on the low resolution of the video (480p) as making it difficult to follow: I understand, and, in fact, the original video was at a higher res (720x576, 25 fps): unfortunately, uploading to YouTube the resolution gets dropped during the transcoding.
Disappointing, I know, but hardly something I can do anything about.


I would suggest instead to see also Part II of this tutorial, which further elaborates on the topic, and provides some code samples.

Saturday, November 20, 2010

Dump CPU temperature data to a file in Ubuntu

Update: I've figured out that it makes a lot more sense to have a reading of the CPU load to correlate with the temperature reading, so I've added that too using /usr/bin/uptime.

Thursday, November 11, 2010

Changing the value returned by getModuleName

When refactoring the name of the GWT module (which typically involves changing the name of the Module.gwt.xml file, see this post) you also have to change the returned value from getModuleName() in every GWTTestCase:


This is way I usually factor the name of the module out into a utility class, and reference a static constant from every test case: saves a lot of pain and effort following some heavy refactoring.

If you do want to watch the video, here's a few tips:

  • if your connection is fast enough, choose 720p as the resolution, or the various menu items and text in general, will be very blurry;
  • this is best viewed full-screen;
  • a description as to how to create a reusable GWT Module can be found here

Change a GWT Module name

This is really a trivial how-to, but wanted to try out how easy it was to capture Eclipse's window using xvidcap, and then upload to Youtube and embed the video here.


This was all relatively simple (from having the idea, to blog posted and tested, took around 15 minutes) so I plan to do a few more.

If you do want to see the video, here's a few tips:

  • if your connection is fast enough, choose 720p as the resolution, or the various menu items and text in general, will be very blurry;
  • this is best viewed full-screen;
  • do remember if you follow along, and you have unit tests, to change the module name there too (or see this video);

Sunday, November 7, 2010

Implementing a Remote Service in Android - Part I

When I decided that a particular idea of mine could be best implemented as an Android Service, running in the background, I found that there is not much information available on the web, beyond some very basic examples, android.com's API Demo sample, and the AIDL tutorial page.

However, those are rather "sparse" guidelines, and several gaps are left for oneself to fill out by trial and error: so I decided to post this brief how-to, along with the code itself.

As noted in the Android Developer's guide:

A service doesn't have a visual user interface, but rather runs in the background for an indefinite period of time. For example, a service might play background music as the user attends to other matters, or it might fetch data over the network or calculate something and provide the result to activities that need it. Each service extends the Service base class.

There are actually two ways of implementing a service: one is to just extend the Service class, implement the onBind() method and then implement the Binder interface in your service implementation class (this is the approach described here); the other is to use AIDL (Android Interface Description Language), followed by the API Demo sample (and further described in Part II of this blog - coming soon).

So, here we go: let's assume that we want to implement a simple service, which enables developers to add a simple UI element to their app to allow delighted users to make donations, but freeing them from having to implement all the machinery: our service will take a Developer Key and an Amount value ($ cents), and will credit the amount to the developer's account (we assume that the user's credentials can be retrieved from the system - how to do that is outside the scope of this blog); the app developer herself will only have to implement a simple UI (or a fancy complicated one: that's up to her) and connect to our service.

The service class definition is pretty trivial:
public class DonateService extends Service {
  @Override
  public IBinder onBind(Intent intent) {
    return new DonateServiceImpl(getResources());
  }
}

The service implementation itself is rather simple too:
public class DonateServiceImpl extends Binder { ... }
with all the 'action' being in its onTransact() method:
@Override
  protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
    if (code != res.getInteger(R.id.SERVICE_CODE)) {
      Log.e(getClass().getSimpleName(), "Transaction code should be " +
          res.getInteger(R.id.SERVICE_CODE) + ";" + " received instead " + code);
      return false;
    }
    Bundle values = data.readBundle();
    String devKey = values.getString(res.getString(R.string.DEV_KEY));
    int amountInCents = values.getInt(res.getString(R.string.AMT));
    Log.i(getClass().getSimpleName(), getUser() + " wants to donate " +
        amountInCents + " to " + devKey);
    if (amountInCents <= 0) {
      Log.e(getClass().getSimpleName(), "Amount should be a positive integer (" +
          amountInCents + " is not).");
      return false;
    }
    Log.d(getClass().getSimpleName(), "Sending request to server");
    // This is where we would implement our HTTPS connection service, most likely to
    // some RESTful service
    
    return true;
  }

And this is pretty much all there is to it, as far as it concerns to handling a service call (please do read the description on the Service class, as well as the notes about a service's lifecycle: similar to an Activity, there is an onCreate(), onDestroy() etc.) and retrieving the data marshalled by the system, from the calling Activity.

If you now try to 'test' it by using the Android Instrumentation framework from a 'sibling' test project (you create one typically at the same time as you create a new Android project in Eclipse), your code should look something like this:
public void testServiceRuns() {
    Resources myRes = getContext().getResources();
    assertNotNull("The test case resources are null", myRes);
    
    Intent i = new Intent(ACTION);
    IBinder binder = bindService(i);
    assertNotNull(binder);
    
    Bundle values = new Bundle();
    values.putString(myRes.getString(R.string.DEV_KEY), "12345ABCDE");
    values.putInt(myRes.getString(R.string.AMT), 99);
    Parcel data = Parcel.obtain();
    data.writeBundle(values);
    
    try {
      int serviceCode = myRes.getInteger(R.id.SERVICE_CODE);
      assertTrue(binder.transact(serviceCode, data, null, 0));
      Log.i("test", "Service executed successfully");
    } catch (Exception ex) {
      Log.e("test", "Could not transact service: " + ex.getLocalizedMessage(), ex);
      fail(ex.getLocalizedMessage());
    };
  }

Funnily enough, this will work even if you mistype the name of the service's implementation class in the Android Manifest (AndroidManifest.xml):
<application android:label="@string/service_label" 
                     android:icon="@drawable/app_icon">
   <service android:exported="true" 
            android:name=".DonateService"
            android:process=":remote">
      <intent-filter>
         <action android:name="@string/ACTION_DONATE" />
      </intent-filter>
   </service>
</application>

(try changing .DonateService to .blah and this will still work) -- all this to say: the mechanics of Android unit testing are different from a remote invocation, and may succeed even though your service may be unavailable to other applications.

Notice in particular android:process=":remote" - this is what tells Android application manager to lookup your service's intent-filter too, when looking for possible targets, when another process invokes startService(Intent).

Finally, your test case should extends ServiceTestCase - but make sure you change the constructor, from Eclipse's auto-generated one to something like this:

public DonateServiceBinderTest(String name) {
    super(DonateService.class);
    setName(name);
  }
as explained elsewhere.

The <intent-filter> is the trick that does all the magic here: when matched against the Intent's 'action' will cause your service to be invoked.
Which brings us to the next topic: how do we invoke the service from a separately developed, completely independent application?

I have created a very simple Activity (download service_example_usage-0.2_beta from our site) that does exactly that.

In the following, I will largely ignore the niceties of building an Android UI, as these are widely explained elsewhere and are largely outside the scope of this post, and will focus instead on the specifics of calling a Service.

As a general rule, when invoking a Service, you must do it outside of your primary UI thread: for starters, you have no idea how long will it take to complete and, secondly, you want to give the users the ability to terminate it, should it take too long.

Hence:

Rule #1 - execute a service invocation from within a Runnable that executes outside your main UI thread, and set up the service call, so that it has a callback handler;

Which neatly leads to

Rule #2 - to handle the service outcome where this needs to influence changes in the UI (and it most likely will, even for the trivial task of notifying the user that the call succeeded/failed, whatever...) use a Handler, or your app will crash unceremoniously.

Let us dissect the code in SimpleApplication.java (activateService(final int amt)) one step at a time:

1. Visually notify the user that we're engaging in something that will take time to complete, and we aren't quite sure how long:
LinearLayout panel = (LinearLayout) findViewById(R.id.ProgressPanel);
    panel.setVisibility(View.VISIBLE);

the progress bar has been defined in the layout/main.xml file as 'indeterminate' and as a spinning wheel:
<ProgressBar android:id="@+id/ProgressBar" android:layout_height="wrap_content" 
                android:layout_marginLeft="15px" android:layout_width="wrap_content"
                android:indeterminate="true" android:indeterminateBehavior="repeat" 
                android:visibility="visible"/>

2. Create an intent, whose action will match the service's action's intent-filter (see note below[*] regarding sharing common strings between the service and its intended users):
Intent i = new Intent(getResources().getString(R.string.ACTION_DONATE));

3. Using this Activity's Context, bind it to a service that can service this Intent, by providing an implementation of a ConnectionService interface:
boolean isConnected = bindService(i, new ServiceConnection() {
     @Override
     public void onServiceConnected(ComponentName name, IBinder service) {
       Bundle values = new Bundle();
       values.putString(getResources().getString(R.string.DEV_KEY),
           getResources().getString(R.string.DEVELOPER_KEY_VALUE));
       values.putInt(getResources().getString(R.string.AMT), amt);
       Parcel data = Parcel.obtain();
       data.writeBundle(values);
       boolean res = false;
       try {
         res = service.transact(serviceCode, data, null, 0);
       } catch (RemoteException ex) {
         Log.e("onServiceConnected", "Remote exception when calling service", ex);
         res = false;
       }
       Message msg = Message.obtain(h, serviceCode, amt, (res ? 1 : -1));
       msg.sendToTarget();
     }

     @Override
     public void onServiceDisconnected(ComponentName name) {
     }
   }, Context.BIND_AUTO_CREATE);

4. Wrap the above into a Runnable, and then kick the Thread alive:
Thread serviceThread = new Thread(new Runnable() {
     @Override
     public void run() { //... }
   });
   serviceThread.start();

5. To enable this newly created thread to 'callback' your activity and carry out tasks inside the UI thread, you need to implement a Handler class, create a Message to wrap your returned results and then configure your handler as the message's target:
// outside the Runnable:
  final Handler h = new ServiceCompleteHandler(result, panel, ctx);
// this will be invoked inside the UI thread when called
// at the end of onServiceConnected, in the service activation thread
  Message msg = Message.obtain(h, serviceCode, amt, (res ? 1 : -1));
  msg.sendToTarget();

Your Handler needs to override the default handleMessage() method (that does nothing otherwise) and will be run by the System inside your UI thread (and will thus have access to your Activity's widgets, without causing a RuntimeException):
public static class ServiceCompleteHandler extends Handler {
  @Override
  public void handleMessage(Message msg) {
    int amt = msg.arg1;
    boolean outcome = msg.arg2 > 0;
    serviceComplete(amt, outcome);
  }

  void serviceComplete(int amt, boolean outcome) {
    panel.setVisibility(View.INVISIBLE);
    Rect r = new Rect(0, 0, 48, 48);
    Drawable icon;
    if (outcome) {
      icon = getResources().getDrawable(R.drawable.accepted_48);
    } else {
      icon = getResources().getDrawable(R.drawable.cancel_48);
    }
    icon.setBounds(r);
    result.setCompoundDrawables(icon, null, null, null);
    int dollars = amt / 100;
    int cents = amt % 100;
    result.setText(getResources().getString(outcome ? 
        R.string.thanks : R.string.sorry) + dollars +
        "." + cents + "\n" + getResources().getString(R.string.promo));
    result.setVisibility(View.VISIBLE);
  }
}

And this is pretty much all there is to it: sure, it's a bit more convoluted than just invoking a method in class, but we're talking here inter-process communication (IPC) and remote invocation (RMI) and they ain't pretty in any of the other frameworks either (think J5EE or, God forbid, CORBA).

In a subsequent post, I will show how to use AIDL to make invoking the service a more painless experience for the clients, but at the cost of having a slightly more convoluted development process on the service implementation's side.
---
[*]A note about re-using common strings (see the file res/values/donate_service_strings.xml): it is good practice not to use hard-coded strings in your service calls and data maps, and even better to have them in a commonly shared file (instead of duplicated everywhere in each applications strings.xml file).

Ideally, if you publish a service, you should make such a file freely available to your service users (eg, downloadable from your API docs site's pages); equally, if you use a service, either use the available strings file (hopefully made available from your provider -- if they don't, question your desire to use their service...) or partition those service-specific strings in its ownd dedicated file.

Eclipse users: while developing your service, you will certainly want to test it out with a simple app (very much like I describe here). The obvious way to heed the above advice would then be to add the 'strings' file as a "link" in Eclipse Package Explorer, so that any changes made during the service development, would be automatically picked up the 'testing' app.

This won't work (Android's plug-in does not pick linked .xml files in the res/... tree, to generate the R.java file). A simple workaround would be to create a soft link to the one file in the res/values/ directory:
$ ln -s ../DonateService/res/values/donate_service_strings.xml res/values/service_defs.xml
(you can give whatever name you wish to the link).
In the downloadable code, I've added a physical copy to the file in each package, to avoid people having troubles when re-using it: if you do use both to follow along and/or make changes, I recommend removing one copy and making a link as suggested here.

Sunday, June 6, 2010

Unit testing Android Activity


This blog is now hosted on codetrips.com (WordPress) 



This post is best read there (with any updates, as I will add to it)

------------------
As I mentioned earlier, testing on Android is not for the faint-hearted (or the man-in-a-hurry) - documentation is very thin on the ground (although I've recently seen appear a few testing-related articles in the Developer documentation for the latest SDK - haven't checked them out yet, though) and the API is cumbersome at the best of times (and outright misleading, at the worst).

The "master class" to test an Activity class MyActivity, is ActivityInstrumentationTestCase2<MyActivity> that instruments and initializes it.

Its documentation is marginally better than that for android.test package:

A framework for writing Android test cases and suites.

but, hey, we haven't set the bar too high here.

Here are a few 'top tips' as how to avoid some of the grief, that I've discovered whilst developing unit tests for my AndroidReceipts application:

Do not use the 'default' constructor, but the one that uses ActivityUnitTest(String)
In Eclipse, you can right-click on a class in the project explores and then select New/Other... to create a new JUnit TestCase: in the ensuing dialog box, then select ActivityInstrumentationTestCase2 as the 'super' class, the plugin will helpfully auto-generate the full class with the following constructor:
// DON'T DO THIS - it won't compile
public MyActivityTest(String name) {
  super(name);
}
Here, Eclipse will (correctly) complain that there is no such thing as a ActivityInstrumentationTestCase2(String name) and you will quickly figure out that a (possible) super call may be something like this:
// DON'T DO THIS - it won't work
public MyActivityTest(String name) {
  super(PKG_NAME, MyActivity.class);
}
This will, sadly, cause the test runner (android.test.InstrumentationTestRunner) to happily ignore your test class:

[2010-06-06 22:33:20 - PolarisTest] Test run failed: Test run incomplete. Expected 51 tests, received 4

the trick is to add a call to setName(name) so that the test runner will find your tests (name, incidentally, is the name of the method being run).
// Do this instead:
public ScanActivityTest(String name) {
  // NOTE -- API Level 8 have deprecated this constructor, and replaced with one that simply takes the Class<T> argument
  super(PKG_NAME, MyActivity.class);
  setName(name);
}
If you are using the SDK 2.2 (L8) version, then there appears to be a new constructor that only takes the name of the Activity's Class under test (while the constructor shown above is deprecated): I have not tried it out, and targetting L8 devices, at the moment, rather severely restricts your target market.

Beware of Eclipse (ADB) missing a change in project source
The typical cycle is to write some code, run the tests, make changes, run the tests again.

This generally works, but, from time to time (I've been unable to discern a pattern) ADB misses a change in your source code and just re-runs the same tests as before.
As this typically happens when you make changes to the 'main' project (as opposed to the 'test' one) I suspect this happens when you do not save the modified source file, this in turn does not trigger a re-build of the APK, which change would have been picked up by the deployer of the 'test' project.

Be that as it may, keep an eye on the Console view and check that the a new version of the APK for the 'main' or 'test' (or both) projects gets installed on the emulator.

If you 'remove' the app manually, you also must 'clean' the project
On the same token, at times it turns out that the only way to get ADT out of its own hole, is just to go into the Emulator's Settings/Applications/Manage Applications and just remove either or both of the installed projects.

This will make the test runner deeply unhappy, and it will manifest its unhappiness by refusing to deploy the APKs and giving out an

[2010-06-06 19:28:31 - PolarisTest] Application already deployed. No need to reinstall.

The one way to quickly 'fix' this is to go into Project/Clean... and clean one or both of the projects.

The default tearDown() calls on onPause() (but not onStop() and even less onDestroy())
Well, I was surprised to find that out - it would have been reasonable to expect the test fix to run through the whole Activity lifecycle, and shut it down "gracefully.

In case you have some 'session management' (and who doesn't these days, in a serious Android app? you want to preserve state so that the user can come back to your app and find it exactly the way she left it) this may cause some surprising results when testing.

Considering that, in the Android process management system, there is no guarantee of a 'graceful shutdown' (essentially the scheduler wants to feel free to kill your proces without having to wait for your app to get itself sorted out -- and quite rightly so: we don't want a "Windows Experience" where some poorly-paid and even less-trained programmer can bring the whole system to its knees by sheer incompetence) this is just as well: in fact, the more I look into it, the more I find myself doing state management in the onPause / onCreate / onRestart lifecycle methods, and essentially ignoring the onStop and onDestroy (in particular the latter, I wonder sometimes why it's there at all)

Whatever, words to the wise: your Activity's onStop/onDestroy won't be called, unless you do it yourself.

Unit test run concurrently, but, apparently, @UiThreadTest prevents this for the UI thread
I must confess I'm not entirely clear about the full implications of using the @UiThreadTest annotation (apart from ensuring that the tests will run sequentially in the UI thread, thus avoiding a predictable chaos if they were all allowed to try to access UI resources concurrently) but one fundamental implication of this is that sendKeys cannot be called from within a test that is annotated with the @UiThreadTest.

Despite the documentation being conspicuosly silent about this minor detail, it turns that it must not be run in the UI thread; all we know about this method is that  "Sends a series of key events through instrumentation and waits for idle." - whatever that means, the bottom line is that it does not return and your test will eventually fail with a timeout exception.

From my limited experimentation, the only workaround is to either use it only in tests thare are annotated with something such as @SmallTest or similar (but not @UiThreadTest) or to make it run in a separate thread (just create a Runnable that will execute once you are sure the UI elements have been initialized - critically, the layout has been 'inflated').

And, on this topic...

Activity.findViewById(id) - only use after you have 'inflated' the View (typically, by calling the setContentView() on an R.layout.my_layout resource)

Nothing much to add here, really, just be careful about how you sequence your asserts, if you need to verify conditions on UI elements (typically, Widgets) as the findViewById will invariably return null until the view is 'inflated' from the XML (if this is, indeed, the way you build your View).

On a similar note, I've found the Window.getCurrentFocus() (and similarly, Activity.getCurrentFocus()) pretty much useless: naively, I thought that, once the Layout had been inflated, the 'focused window' would have been the main container (or some random widget therein: that would have worked for my tests): in fact, this call most invariably returns null (unless, I presume, you sendKeys to move the focus where you want it to be: this is rather cumbersome, in my opinion, and makes the tests rather brittle and too tightly coupled with the UI layout, which, in my book anyway, is A Bad Thing).

So, here is what I do instead:
 @UiThreadTest
 public void testOnDisplayReceipts() {
     Receipt r = new Receipt();
   instance.accept(r);
   instance.onDisplayReceipts();
   assertNotNull(instance.mGallery);

   // verifies that the Gallery view has been 'inflated'
   View gallery = instance.findViewById(R.id.gallery_layout);
   assertNotNull(gallery);
 }

Ok, it's not pretty, I'll give you that, but it works (and is rather independent of what I do in my Gallery view, what widgets are there and how they are arranged).


Beware of super.tearDown()
Worth to feature in one of Bloch's Puzzlers, what does this code do, when run with an InstrumentationTestRunner?
You may also want to know that the test passes, and, upon exiting from testOnCreateSQLiteDatabase the stub field contains a valid
reference to the SQLiteDatabase just created and opened in its db package-visible field.
public class ReceiptsDbOpenHelperTest extends ActivityInstrumentationTestCase2 {

  public ReceiptsDbOpenHelperTest(String name) {
    super("com.google.android.applications.receiptscan", ScanActivity.class);
    setName(name);
  }

  public static final String DB_NAME = "test_db";
  ReceiptsDbOpenHelperStub stub;

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

  protected void tearDown() throws Exception {
    super.tearDown();
    if (stub != null) {
      String path = stub.db.getPath();
      Log.d("test", "Cleaning up " + path);
      if (path != null) {
 File dbFile = new File(path);
 boolean wasDeleted = dbFile.delete();
 Log.d("test", "Database was " + (wasDeleted ? "" : "not ") + "deleted");
      }
    }
  }

  /**
   * Ignore the details, but this does "work as intended," opens the database and returns a reference
   * to it in the db variable.
   * The {@code stub} is a class derived from {@link ReceiptsDbOpenHelper} and simply gives us access to
   * some protected / private fields
   */
  public void testOnCreateSQLiteDatabase() {
    stub = new ReceiptsDbOpenHelperStub(getActivity(), DB_NAME, null, 1);
    SQLiteDatabase db = stub.getReadableDatabase();
    assertNotNull(db);
    assertTrue(stub.wasCreated);
    assertEquals(stub.db, db);
  }
}

Well, you'll be surprised to know that, our tearDown() does absolutely nothing: after the call to super.tearDown(), stub is null (one can check it out using a debugger session; at least, that's what I did: upon entering ReceiptsDbOpenHelperTest.tearDown() stub is a perfectly valid reference, just after the call to super.tearDown() it's a null: apparently a call to super.tearDown() on an ActivityInstrumentationTestCase2<MyActivity> wipes out all the 'context-related' instance variables.

Yes, I was too.

The fix is, obviously, trivial: move the call to super.tearDown() to the bottom of your tearDown() (luckily, this is not a constructor, so there's no reason why not to).

Summary
There seems to be light at the end of the tunnel: some "official" documentation is starting to appear on Android.com, the SDK is (slowly) moving to be (marginally) more user-friendly, and writing (and running) unit tests is no longer as painful as it used to be in version 1.0.

However, one would have wished that it wouldn't have taken until release 2.2 of the SDK (and version 8 of the API) to get where we are now: for one thing, it's rather likely that Android will be the first (or main) programming platform that many kids will take up when starting to explore computing and software development - and whilst programming in Android is fun, productive and gives an immediate sense of accomplishment, I am concerned that, having given testing (and unit testing, in particular) such a back seat, the wrong lesson may be learnt by young computer scientists: namely, that testing (and coding for testing) is something that can be done another day, when we'll get on the next release...

It isn't - writing unit tests is vital to write bug-free, solid and portable code; it also encourages the design of clean APIs: there's nothing like writing a few tests to figure out that one's just written a cumbersome API that needs fixing: and the sooner one finds out, the better!
Blogged with the Flock Browser