Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending upper case letters to a TextEdit during instrumented tests

I am writing a JUnit test case for my Android app. The test class extends ActivityInstrumentationTestCase2 and calls sendKeys() to emulate user input for TextEdit widgets. However, all of the alphabetic keycodes (e.g. KeyEvent.KEYCODE_G) only send lower case letters to the TextEdit. I tried sending KeyEvent.KEYCODE_SHIFT_LEFT before sending an alphabetic keycode, but that didn't seem to work. So how do I simulate the user typing an upper-case letter?

Edit:

I can enter upper case letters manually. In fact, the EditText is defined as

    <EditText android:id="@id/brand_text"
              android:singleLine="true"
              android:capitalize="words"
              android:hint="@string/brand_hint"
    />

The android:capitalize="words" attribute forces the onscreen keyboard into uppercase mode in the emulator. (I assume it will do the same on a device but don't have one to test it on.) Since the emulator which comes with the SDK doesn't emulate the hardware keyboard, I have been unable to test how my UI works using hard keys.

I also tried

EditText brandText = this.activity.findViewById(R.id.brand_text);
brandText.setText(someString);

However, the test failed when I did this. I axed all that code, so I don't have the details here at the moment. I will try to recreate it and edit this question with those details.

like image 860
Code-Apprentice Avatar asked Nov 07 '12 23:11

Code-Apprentice


2 Answers

I didn't mention in my OP that I was writing a method to send the characters of a String to a text box. I tried using setText() as @PaulHarris suggested but couldn't get it to work; my tests still failed some assertions.

After some digging, finally found Instrumentation.sendStringSync() which works for my purposes. (You can get an Instrumentation object by calling getInstrumentation() in your test class.)

like image 102
Code-Apprentice Avatar answered Nov 15 '22 13:11

Code-Apprentice


If you want to do something like:

EditText brandText = this.activity.findViewById(R.id.brand_text);
brandText.setText(someString);

What you actually need to do is:

EditText brandText = this.activity.findViewById(R.id.brand_text);
instrumentation.runOnMainSync(new Runnable() {
    @Override
    public void run() {
        brandText.setText(someString);
    }
}); 

This is because you need to do any interaction with the gui on the UI Thread (or main thread whatever name you prefer).

A method such as this:

public void setText(EditText editText, final String textToSet){
    instrumentation.runOnMainSync(new Runnable() {
        @Override
        public void run() {
            brandText.setText(textToSet);
        }
    }); 
}

should work for you just fine.

like image 29
Paul Harris Avatar answered Nov 15 '22 15:11

Paul Harris