Preferred way to test EditText input in an Android

2019-08-25 07:26发布

问题:

I have an Activity with EditText and Button widgets. Clicking the button prints an error message if the EditText is empty or calls setResult() to send the value back to another Activity which launched this one.

I am writing some simple unit tests to check that this interaction works. I have two different versions of the same test:

@UiThreadTest
public void testOkButtonOnClickWithNumber() {
    this.numberText.setText(Integer.toString(this.testNumber));
    Assert.assertTrue(this.okButton.performClick());
    Assert.assertTrue(this.activity.isFinishing());
}

public void testOkButtonOnClickWithUserInputNumber() throws Throwable {
    this.sendKeys(Integer.toString(this.testNumber));

    this.runTestOnUiThread(new Runnable() {
        @Override
        public void run() {
            Assert.assertTrue(NumberFilterTest.this.okButton.performClick());
        }
    });

    this.getInstrumentation().waitForIdle(new Runnable() {
        @Override
        public void run() {
            Assert.assertTrue(NumberFilterTest.this.activity.isFinishing());
        }
    });
}

As you can see, one test simply calls setText() on the EditText widget. The other uses sendKeys(). Is there a preferred best practice which of these two options to use during testing? Or should I keep both tests?

回答1:

I potentially have a new answer to an old problem, http://developer.android.com/tools/testing/testing_ui.html just released as part of adt21, if you are just starting out on android testing it is certainly worth looking at this.

As for the actual question. Using sendKeys() is closer to what a user actually does and so if you had listeners on editing text or key press for example then they would get actually get fired. Typically this might not be an issue for you as you might not be using this functionality but it could bite you if you didn't realise. Another example like this is how you are clicking your button, you are currently calling a the click method when the preferred way would be to send a touch event over the buttons location because that is actually what a user does.