Тестирование с элементами пользовательского интерфейса в представлении Android - PullRequest
9 голосов
/ 30 августа 2010

Я пытаюсь протестировать простой пользовательский интерфейс со следующим тестовым примером. Основная идея состоит в том, чтобы установить в тесте некоторый текст пользовательского интерфейса (чтобы имитировать пользовательский ввод), а затем активно щелкнуть событие.

public class StackTestCase 
extends ActivityInstrumentationTestCase2<Stack> 
{
private StackDemo mActivity;

private EditText eaten;
    public StuckTestCase() {
         super("com.crocodil.software.stack", Stack.class);


    }
    public StuckTestCase(Class<Stack> activityClass) {
         super("com.crocodil.software.stack", activityClass);

    }
    protected void setUp() throws Exception {
        super.setUp();
        mActivity = this.getActivity();
        mCount = (Button) mActivity.findViewById(com.crocodil.software.stack.R.id.action);
        eaten = (EditText) mActivity.findViewById(com.crocodil.software.stack.R.id.eaten);

    }

    public void testPreconditions() {
        assertNotNull(mStatus);
      }

    public void testSimpleDefaults(){
        double status = Double.valueOf(mStatus.getText().toString());
        eaten.setText(2);
        mCount.performClick();
        assertEquals((status-2),Double.valueOf(mStatus.getText().toString()));
    }

}

результат выполнения - исключение -

android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRoot.checkThread(ViewRoot.java:2802)
at android.view.ViewRoot.playSoundEffect(ViewRoot.java:2581)
at android.view.View.playSoundEffect(View.java:8516)
at android.view.View.performClick(View.java:2407)
at com.crocodil.software.stack.test.StackTestCase.testSimpleDefaults(StackTestCase.java:46)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:204)
at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:194)
at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:186)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:520)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447)

Это происходит при каждом доступе к элементам пользовательского интерфейса, и мне не удалось избежать этого с помощью дескрипторов или асинхронной задачи?какие-либо предложения?

Ответы [ 2 ]

30 голосов
/ 12 февраля 2011

Это старый вопрос, но я все равно даю вам ответ, если кто-то наткнется на него.

Вы не можете изменять состояния виджетов пользовательского интерфейса из любой точки, кроме основного потока (пользовательского интерфейса).нить).Ваш executeClick должен быть выполнен следующим образом:

mActivity.runOnUiThread(new Runnable() {
  @Override
  public void run() {
    mCount.performClick();
  }
});

Но это еще не все, вам также нужно будет синхронизировать тестирование инструментов с пользовательским интерфейсом, добавив следующую строку:

getInstrumentation().waitForIdleSync();

Синхронизирующая строка обычно помещается сразу после кода runOnUiThread ().

6 голосов
/ 16 июля 2013

Проблема в том, что вы можете только касаться / изменять представления из потока пользовательского интерфейса. Вы можете использовать runnable, как обрисовал в общих чертах Робер, или аннотацию.

Вы можете запустить все методы внутри теста в потоке пользовательского интерфейса, используя аннотацию @UiThreadTest :

Обновление:

Этот @interface устарел на уровне API 24 .
Используйте взамен UiThreadTest . Новые тесты должны быть написаны с использованием библиотеки поддержки тестирования Android .

@UiThreadTest
public void testSimpleDefaults(){
     double status = Double.valueOf(mStatus.getText().toString());
     eaten.setText(2);
     mCount.performClick();
     assertEquals((status-2),Double.valueOf(mStatus.getText().toString()));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...