2016-02-16 7 views
2

Я пытаюсь написать тестовый пример для своей деятельности. У меня есть метод в моей деятельности, который обновляет мой пользовательский интерфейс.Как обновить элементы пользовательского интерфейса с помощью методов тестирования Espresso?

public void setBooking(Booking booking) 
{ 
    if (booking == null) 
    { 
     return; 
    } 

    this.mBooking = booking; 
    this.mBookingExt.updateUI(); 
} 

и это мой тестовый класс:

@RunWith(AndroidJUnit4.class) 
public class LocatingActivityTest 
{ 
    @Rule 
    public ActivityTestRule<BookingActivity> mActivityTestRule = new ActivityTestRule<>(BookingActivity.class); 

    private BookingActivity mBookingActivity; 

    @Before 
    public void setup() 
    { 
     mBookingActivity = mActivityTestRule.getActivity(); 
     mBookingActivity.setBooking(BookingTest.getStandardTaxi()); // << My Fake Booking Object 

     onView(withId(R.id.book_now)).perform(click()); 
    } 

    @Test 
    public void viewsMustBeVisible() 
    { 
     onView(withId(R.id.locating_text)).check(matches(isCompletelyDisplayed())); 
     onView(withId(R.id.sonarView)).check(matches(isCompletelyDisplayed())); 
     onView(withId(R.id.cancel_booking)).check(matches(isCompletelyDisplayed())); 
    } 
} 

Я получаю следующее сообщение об ошибке при выполнении теста:

android.view.ViewRootImpl $ CalledFromWrongThreadException: Только оригинальный поток, создавший иерархию представлений, может коснуться его представлений.

Я думаю, @Before работает на потоке пользовательского интерфейса, поэтому понятия не имею, что это жалуется, откуда происходит! This is my reference (ActivityTestRule распространяется UiThreadTestRule).

Так что я решил немного изменить архитектуру класса. Так setup() и viewsMustBeVisible() не изменилось к этому:

@Before 
    public void setup() 
    { 
     mBookingTaxiActivity = mActivityTestRule.getActivity(); 
    } 

    @UiThreadTest // from android.support.test.annotation.UiThreadTest 
    public void viewsMustBeVisible() 
    { 
     mBookingTaxiActivity.setBooking(BookingTest.getStandardTaxi()); // << My Fake Booking Object 

     onView(withId(R.id.fab_booking)).perform(click()); 
     onView(withId(R.id.booking_book_now)).check(matches(isEnabled())); 
     onView(withId(R.id.booking_book_now)).perform(click()); 

     onView(withId(R.id.locating_text)).check(matches(isCompletelyDisplayed())); 
     onView(withId(R.id.sonarView)).check(matches(isCompletelyDisplayed())); 
     onView(withId(R.id.locating_cancel_booking)).check(matches(isCompletelyDisplayed())); 
    } 

Однако, я получаю следующее сообщение об ошибке это время:

java.lang.Exception: Нет Runnable методы

Наконец я изменил выше метода для проведения теста на резьбу пользовательского интерфейса:

@Test 
    public void viewsMustBeVisible() 
    { 
     mBookingTaxiActivity.runOnUiThread(new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       mBookingTaxiActivity.setBooking(BookingTest.getStandardTaxi()); // << My Fake Booking Object 

       onView(withId(R.id.fab_booking)).perform(click()); 
       onView(withId(R.id.booking_book_now)).check(matches(isEnabled())); 
       onView(withId(R.id.booking_book_now)).perform(click()); 

       onView(withId(R.id.locating_text)).check(matches(isCompletelyDisplayed())); 
       onView(withId(R.id.sonarView)).check(matches(isCompletelyDisplayed())); 
       onView(withId(R.id.locating_cancel_booking)).check(matches(isCompletelyDisplayed())); 
     }); 
    } 

Проблема здесь в тестировании никогда не делается. Я жду 6-7 минут, и индикатор его прогресса все еще вращается и, кажется, никогда не делается.

Я предполагаю, что изучил все способы обновления моего объекта «Бронирование», а также элементы пользовательского интерфейса. Есть ли у вас опыт в этом отношении? Благодарю.

ответ

0

Прохладный, я получил его после многих часов. Я не уверен, в чем разница, но я переместил работу пользовательского интерфейса в Activity. Новый метод испытаний Look любит это:

@Test 
    public void viewsMustBeVisible() 
    { 
     onView(withId(R.id.fab_booking)).perform(click()); 

     mBookingTaxiActivity.setTestBooking(BookingTest.getStandardTaxi()); 

     onView(withId(R.id.booking_book_now)).check(matches(isEnabled())); 
     onView(withId(R.id.booking_book_now)).perform(click()); 

     onView(withId(R.id.locating_text)).check(matches(isCompletelyDisplayed())); 
     onView(withId(R.id.sonarView)).check(matches(isCompletelyDisplayed())); 
     onView(withId(R.id.locating_cancel_booking)).check(matches(isCompletelyDisplayed())); 
    } 

и я создал метод в стороне деятельности, чтобы обновить свой объект:

// Required just for Testing purposes 
    @VisibleForTesting 
    public void setTestBooking(Booking booking) 
    { 
     if (booking == null) 
     { 
      return; 
     } 

     this.mBooking = booking; 

     this.runOnUiThread(new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       BookingActivity.this.mBookingExt.updateUI(); 
       findViewById(R.id.booking_book_now).setEnabled(true); 
      } 
     }); 
    } 

Надеется, что это поможет вам, если у вас есть такие же проблема.