16

My question is: How do I create an Android stand-alone test project for an Android library?

I've got my Android library (which is marked as "Library" in the project settings) and an Android project containing my JUnit test classes. The test project correctly references the Android library (in the project settings under "Android").

My library source code is located in the package com.mayastudios. All my test cases are also located in the same package (but in a different project). So basically I have something like this:

+- MyLibraryProject
   +- src
      +- com/mayastudios/MyClass.java
   +- AndroidManifest.xml
   +- ...
+- MyTestProject (references MyLibraryProject)
   +- test
      +- com/mayastudios/MyClassTests.java
   +- AndroidManifest.xml
   +- ...

Here's the Android manifest for the test project:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.spatialite.test"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />

    <instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="com.mayastudios" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <application android:label="Spatialite-NewApi-UnitTests">
        <uses-library android:name="android.test.runner" />
    </application>

</manifest>

However, when I run the test project (from Eclipse with ADT, using "Run As -> Android JUnit Test") I get the following error:

Unable to find instrumentation target package: com.mayastudios

Here's the complete Console log:

[2012-04-24 17:24:20 - spatialite-test] Android Launch!
[2012-04-24 17:24:20 - spatialite-test] adb is running normally.
[2012-04-24 17:24:20 - spatialite-test] Performing android.test.InstrumentationTestRunner JUnit launch
[2012-04-24 17:24:20 - spatialite-test] Automatic Target Mode: using device '3732FBC2711300EC'
[2012-04-24 17:24:20 - spatialite-test] Uploading spatialite-test.apk onto device '3732FBC2711300EC'
[2012-04-24 17:24:20 - spatialite-test] Installing spatialite-test.apk...
[2012-04-24 17:24:22 - spatialite-test] Success!
[2012-04-24 17:24:22 - spatialite-test] Launching instrumentation android.test.InstrumentationTestRunner on device 3732FBC2711300EC
[2012-04-24 17:24:22 - spatialite-test] Collecting test information
[2012-04-24 17:24:23 - spatialite-test] Test run failed: Unable to find instrumentation target package: com.mayastudios

I tried to remove the <instrumentation> tag from the manifest which didn't work.

The only way I got this working so far was to create a default Android project (with an Activity), reference it from my test project and use the package name of this default Android project as targetPackage under <instrumentation>. But that's not what I want. I want a stand-alone test project.

Any suggestions?

Sebastian Krysmanski
  • 8,114
  • 10
  • 49
  • 91
  • 1
    InstrumentationTestRunner must targeting on a concrete apk, whereas library project itself dones't allow to export as apk. I have explained this in more details at [here](http://stackoverflow.com/questions/10172636/unable-to-find-instrumentation-target-package-com-xyz/10173034#10173034). – yorkw Apr 24 '12 at 23:36
  • Yes, I got that. I just thought that the test.apk could run on its own since it's installed on the device. – Sebastian Krysmanski Apr 25 '12 at 05:42
  • It does work as I expected it. See my answer below. – Sebastian Krysmanski Apr 25 '12 at 06:03

1 Answers1

25

Ah, the answer is so simple. The error is in the Android manifest of the test project in line 3: Here the wrong package is mentioned. So the corrected manifest looks like this:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mayastudios"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />

    <instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="com.mayastudios" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <application android:label="Spatialite-NewApi-UnitTests">
        <uses-library android:name="android.test.runner" />
    </application>

</manifest>

And to all who say that you need three projects (library, project-under-test, test project): They're wrong. A library project and a test project are enough. The test project doesn't even need to contain an Activity.

Sebastian Krysmanski
  • 8,114
  • 10
  • 49
  • 91
  • I suppose `com.mayastudios` is your Test project. A Test project can target on itself, check out my answer [here](http://stackoverflow.com/questions/9518514/is-it-possible-to-define-activity-inside-android-test-project-and-run-a-test-aga/9525354#9525354). What you actually did is simply make test.apk runnable and target to itself (**you are not target to your library code**). It has been clearly stated in the official dev guide that you need an Application Project to indirectly test Library project. – yorkw Apr 25 '12 at 07:15
  • @yorkw: Actually, assuming `com.mayastudios` links to the Android library project desired to be tested, this pattern fits [the second bullet of the page you linked to in your comment on my now-deleted answer](http://developer.android.com/guide/developing/projects/index.html#testing). – CommonsWare Apr 25 '12 at 10:50
  • @CommonsWare, Ahhhhh, I see now. Sebastian, Yes, you are correct. Never use this pattern myself before, worth to know. – yorkw Apr 25 '12 at 10:55
  • Glad, I could provide some new insight :) – Sebastian Krysmanski Apr 25 '12 at 11:13
  • 3
    This is now broken in ADT 22. It works on command line with gradle and maven but doesn't work any more on ADT as long as library project is marked as library. If not, then everything is working. But when the project is marked as library, then you will get an error message saying the apk under test can't be found. – Snicolas Sep 04 '13 at 13:38
  • I fixed my problem with code like – Sydwell May 22 '14 at 12:35