Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call Button.performClick in Android JUnit test case?

I'm new to Android Testing stuff. I'd like to test if clicking a button will open up a corresponding activity or not. I did some research and found out that I will need to use ActivityManager to do the checking.

Problem is, I can't get the "clicking" part working. I'm trying to use Button.performClick().

Initially I just called this function, and got an error saying that I can't do this in the current thread. After some googling I found out that I need to call it in the UI thread, and came across runOnUiThread(Runnable r) method.

The button I'm trying to click is _helloButton_. This is obtained in the _setUp()_ method. I did _assertNotNull_ check on this to make sure it's there.

Within a test method, I call

mActivity.runOnUiThread(new Runnable() {
        public void run() {
            helloButton.requestFocus();
        }
    });
helloButton.performClick();

and I get a NPE at the line calling requestFocus().

Next I tried

mActivity.runOnUiThread(new Runnable() {
        public void run() {
            helloButton.performClick();
        }
    });

and still get the same null pointer exception.

On the JUnit perspective, I get this message

Test failed to run to completion. Reason: 'Instrumentation run failed due to 'java.lang.NullPointerException''. Check device logcat for details

And the stackTrace look like this.

    08-05 19:03:11.922: ERROR/AndroidRuntime(578): Uncaught handler: thread main exiting due to uncaught exception
08-05 19:03:11.922: ERROR/AndroidRuntime(578): java.lang.NullPointerException
08-05 19:03:11.922: ERROR/AndroidRuntime(578):     at com.example.helloworldmk2.test.HelloWorldMK2Test$1.run(HelloWorldMK2Test.java:57)
08-05 19:03:11.922: ERROR/AndroidRuntime(578):     at android.os.Handler.handleCallback(Handler.java:587)
08-05 19:03:11.922: ERROR/AndroidRuntime(578):     at android.os.Handler.dispatchMessage(Handler.java:92)
08-05 19:03:11.922: ERROR/AndroidRuntime(578):     at android.os.Looper.loop(Looper.java:123)
08-05 19:03:11.922: ERROR/AndroidRuntime(578):     at android.app.ActivityThread.main(ActivityThread.java:4363)
08-05 19:03:11.922: ERROR/AndroidRuntime(578):     at java.lang.reflect.Method.invokeNative(Native Method)
08-05 19:03:11.922: ERROR/AndroidRuntime(578):     at java.lang.reflect.Method.invoke(Method.java:521)
08-05 19:03:11.922: ERROR/AndroidRuntime(578):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
08-05 19:03:11.922: ERROR/AndroidRuntime(578):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
08-05 19:03:11.922: ERROR/AndroidRuntime(578):     at dalvik.system.NativeStart.main(Native Method)

Line 57 is where I'm calling the helloButton.performClick().

I'm not sure why I'm getting NPE; assertNotNull passes without problem. If you can help me with this issue, I'd really appreciate it. Thanks in advance.

EDIT: I'm subclassing ActivityInstrumentationTestCase2 for this particular test class.

EDIT2: Logcat spews out some errors before NPE happens.

I see

08-05 20:08:54.702: ERROR/AndroidRuntime(754): ERROR: thread attach failed

and

08-05 20:08:58.642: ERROR/gralloc(52): [unregister] handle 0x3e1b28 still locked (state=40000001)

like image 403
Don Spike Avatar asked Aug 05 '11 19:08

Don Spike


1 Answers

You can annotate your test to run on UI thread:

@UiThreadTest
public void testNoErrorInCapitalization() {
    final String msg = "this is a sample";
    mMessage.setText(msg);
    mCapitalize.performClick();
    final String actual = mMessage.getText().toString();
    final String notExpectedRegexp = "(?i:ERROR)";
    assertNotContainsRegex("Capitalization found error:",
        notExpectedRegexp, actual);
}

This is an example taken from Android Application Testing Guide.

like image 179
Diego Torres Milano Avatar answered Nov 17 '22 17:11

Diego Torres Milano