8

I am running my android junit tests using command line or eclipse depending if I am in dev mode or in device testing.

A java application has a Main (String[] args) method and it is easy to pass an argument to it (either with eclipse in the Arguments tab in the run configuration section, or by command line)

for an android junit test it is different, there is no Main method and there is nowhere I can set some arguments.

I have read here and there a solution would be to use a properties file. Is that the only way? If you ave a quick and easy example, it would be very appreciated.

Thanks

>>> Edit <<<

I am using Robotium, and the junit extends ActivityInstrumentationTestCase2 See below the very basic junit test:

import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;

import com.jayway.android.robotium.solo.Solo;

public class Test_arg extends ActivityInstrumentationTestCase2 {    
    private static final String TARGET_PACKAGE_ID                = "com.myapp.test";
    private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME = "com.myapp";
    private static Class        launcherActivityClass;
    private Solo solo;

    static {
        try {
            launcherActivityClass = Class.forName(LAUNCHER_ACTIVITY_FULL_CLASSNAME);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    public Test_arg() throws ClassNotFoundException {
        super(TARGET_PACKAGE_ID, launcherActivityClass);

    }

    @Override
    protected void setUp() throws Exception {
        solo = new Solo(getInstrumentation(), getActivity());
    }

    @Override
    public void tearDown() throws Exception {
        try {
            solo.finishOpenedActivities();
            solo.finalize();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        super.tearDown();
    }

    public void test_01() throws InterruptedException { 
        Log.i("TEST", "test");   
    }    
}

and the android manifest

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

    <instrumentation        
        android:name="android.test.InstrumentationTestRunner"                      
        android:targetPackage="com.slacker.radio" android:functionalTest="true"/>

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <uses-library android:name="android.test.runner" />
    </application>
</manifest>
Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
Franck
  • 512
  • 1
  • 9
  • 16
  • similar questions: http://stackoverflow.com/questions/683764/passing-junit-command-line-parameters-in-eclipse http://stackoverflow.com/questions/2884163/pass-command-line-arguments-to-junit-test-case-being-run-programmatically – Ray Tayek Feb 11 '13 at 20:28
  • it is not good practive to pass arguments to tests from command line. What do you want to pass? Why dont you create different test suites or build arguments inside tests. – Leonidos Feb 11 '13 at 20:46
  • Ray, as mentionned in my question I am aware of the system properties way, I am just looking a straighter way (like command argument). _ Leonidos. I understand it is not the best practice to pass arguments for unit tests. In my case, some changes are made server side, where they switch on and off things. My tests are run by command line automatically, so not having to compile again the tests when the server stuff change would save my time – Franck Feb 13 '13 at 00:52
  • If the goal is to support parameterized Android tests, considering using [Burst](https://github.com/square/burst) for this. – Daniel Lubarov Oct 21 '14 at 18:23

2 Answers2

14

You can extend InstrumentationTestRunner and get the arguments in onCreate:

public class MyTestRunner extends InstrumentationTestRunner {

    private static final String TAG = null;
    private String mArgument;

    /* (non-Javadoc)
     * @see android.test.InstrumentationTestRunner#onCreate(android.os.Bundle)
     */
    @Override
    public void onCreate(Bundle arguments) {
        super.onCreate(arguments);

        if (arguments != null) {
            mArgument = arguments.getString("myarg");
        }
    }

    public String getArgument() {
        return mArgument;
    }

}

Add the instrumentation to AndroidManifest.xml, in your case:

<instrumentation        
        android:name="com.example.my.test.MyTestRunner"                      
        android:targetPackage="com.slacker.radio" android:functionalTest="true"/>

and in your Instrumentation (i.e ActivityInstrumentationTestCase2) tests you can do something like this:

public void testSomething() {
    MyTestRunner myTestRunner = (MyTestRunner)getInstrumentation();
    Log.d(TAG, "argument=" + myTestRunner.getArgument());
}

and get the arguments that you can specify in the command line as

$ adb shell am instrument -e myarg MYARG com.example.my.test/.MyTestRunner -w
Diego Torres Milano
  • 65,697
  • 9
  • 111
  • 134
  • thank you for your response, I have edited my initial question with a code sample, because I am using Robotium and it extends ActivityInstrumentationTestCase2. I don't know how to use your answer in my case – Franck Feb 13 '13 at 00:45
0

In Setup function of the Class that extends ActivityInstrumentationTestCase2, add the following code:

MyTestRunner myTestRunner = (MyTestRunner)getInstrumentation();
String argument = myTestRunner.getArgument();
solo = new Solo(myTestRunner, getActivity()); 

Directory structure should be:

src
  package.x.y.z.test
      MainTest.java
      CustomInstrumentationRunner.java

Then in the AndroidManifest.xml, set

<manifest package="package.x.y.z" ...

<instrumentation
        android:name="package.x.y.z.test.CustomInstrumentationRunner"

Invoke the above package with the command line:

adb shell am instrumentation -w package.x.y.z/package.x.y.z.test.CustomInstrumentationRunner
krasbas
  • 28
  • 3