1

Я новичок в тестировании Android, и у меня проблема. Я использую RxJava и проверяю пользовательский интерфейс. Я использую IdlingResource. Пока занят ресурс холостого хода, я не могу проверить интерфейс.Тест UI при работе на холостом ходу занят

Например: У меня есть кнопка. onClick Я делаю запрос. При запросе кнопки отключается. После запроса кнопка находится в разрешенном состоянии. Я хочу проверить следующие 3 шага:

  1. кнопка включена до запроса
  2. Кнопка отключена при запросе (OnClick)
  3. Кнопка активна, когда запрашивающие заканчивается и ответное сообщение возвращает

Я был бы очень рад, если вы сможете мне помочь в этом вопросе ...

Если вам нужна дополнительная информация о моей проблеме, дайте мне знать об этом. Я отредактировал свой пост

ответ

2

Как я понял, вы пытаетесь протестировать свой интерфейс. Если это так, пожалуйста, убедитесь, что вы делаете это правильно:

1). Вы не делаете REAL запрос.

Пожалуйста, поймите, что ваш тест должен всегда иметь такое же поведение в подобных ситуациях. Другими словами, он должен дать тот же результат, вы передаете те же входные параметры.
Входные параметры на данный момент:
1.1). Кнопка включена до запроса
1.2). Кнопка отключена во время запроса
1.3). Кнопки включаются после запроса

Как вы можете видеть из этого списка, вам не нужно делать реальный запрос. Для вас не важно, какой сервер вернет вас (ошибка или успех). Для этого вам даже не нужен сервер. Все, что вам нужно, это просто «что-то», которое ведет себя как настоящий сервер. Другими словами, вы должны издеваться над своим клиентом API.

Я полагаю, что вы используете модификацию. Если нет, вам необходимо создать обертку interface для вашего клиента. Если вы используете модификацию, вам просто нужно высмеять ваш interface.

Предположим, у вас есть следующий interface:

public interface ApiClient{ 
    @GET("/items") 
    Observable<MyResponse> doSomeRequest(); 
} 

Как вы обычно создают ваш клиент API:

Retrofit retrofit = new Retrofit.Builder() 
    .baseUrl("https://api.github.com/") 
    .build(); 

ApiClient service = retrofit.create(ApiClient.class); 

Как вы должны сделать это в тестах:

import static org.mockito.Mockito.*; 

и в методе испытания:

ApiClient apiMock = mock(ApiClient.class); 
when(apiMock.doSomeRequest()) 
       .thenReturn(Observable.just(fakeResponse)); 

или

ApiClient apiMock = mock(ApiClient.class); 
when(apiMock.doSomeRequest()) 
       .thenReturn(Observable.defer(new Func0<Observable<MyResponse>>() { 
         @Override 
         public Observable<MyResponse> call() { 
          try{ 
           Thread.sleep(2 * 1000) //2 seconds 
          }catch(Exception e){ 
           return Observable.error(e); 
          } 
          return Observable.just(fakeResponse); 
         } 
        })); 

P.S. Retrofit добавляет .subscribeOn(Schedulers.io()) ко всем Observable по умолчанию. Этот издевавшийся объект этого не делает. Так что, пожалуйста, не забудьте добавить .subscribeOn(Schedulers.io()) в коде, или применить его к результату Observable.defer(...)
В коде выше она будет выглядеть следующим образом:

when(apiMock.doSomeRequest()) 
    .thenReturn(Observable.defer(...).subscribeOn(Schedulers.io())); 

И вы должны пройти apiMock к Activity/Fragment который вы пытаетесь проверить.
Как это сделать? См. # 2.

2). Использование DI (зависимая инъекция)

Я не буду много писать об этом.
Я просто рекомендую вам прочитать документацию на http://google.github.io/dagger/

И особенно, как организовать проект в пути, когда вы можете использовать реальные implementaions для производства и имитировали реализации для тестирования:

http://google.github.io/dagger/testing.html

Другими словами, когда вы собираетесь создавать приложение для использования, вы предоставляете реальные зависимости (в вашем случае это будет реальная реализация ApiClient), и когда вы собираетесь тестировать некоторый интерфейс или бизнес-логику, вы передаете макет зависимостей , которые имеют поведение, указанное перед тестом.

Это все, что я хотел вам рассказать. Надеюсь, это помогло, и дайте мне знать, если у вас есть другие вопросы.

1

Небольшое дополнение к Alexander's answer. Я бы использовал Subject для «издевательства» api. Это позволяет вам контролировать выполнение.

//setup your test 
Subject<Response,Response> stubResponse = AsyncSubject.create(); 
ApiClient apiMock = mock(ApiClient.class); 
when(apiMock.doSomeRequest()).thenReturn(stubResponse.asObservable()); 
//check first condition that button is enabled before executing action 
//click on button 
//test your second condition that button is disabled while waiting for response 
stubResponse.onNext(fakeResponse); //return fake response 
stubResponse.onCompleted(); 
//test your third condition that button is enabled when you get response back 

Примечание. Никогда не используйте sleep в своем тесте. Это замедлит ваши тесты и добавит flakiness.

+0

спасибо. Это имеет смысл – Alexander

 Смежные вопросы

  • Нет связанных вопросов^_^