2015-08-21 18 views
9

Tôi có một hoạt động được sử dụng một cuộc gọi postDelayed:Espresso và postDelayed

public class SplashActivity extends Activity { 
    private Handler handler = new Handler(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(...); 
     handler.postDelayed(new Runnable() { 
      public void run() { finish(); } 
     }, 3000L); 
    } 
} 

này chạy lúc khởi động ứng dụng, và tôi cần phải điều hướng nó và màn hình đăng nhập của tôi. Tuy nhiên, loopMainThreadUntilIdle của UIController dường như không nhận được MessageQueue bên dưới trong trình xử lý. Như vậy, hành động này kết thúc ngay lập tức trong khi vẫn còn các thư trong hàng đợi.

onView(withId(R.id.splash_screen)).perform(new ViewAction() { 
    @Override 
    public Matcher<View> getConstraints() { 
     return isAssignableFrom(View.class); 
    } 

    @Override 
    public String getDescription() { 
     return ""; 
    } 

    @Override 
    public void perform(final UiController uiController, final View view) { 
     uiController.loopMainThreadUntilIdle(); 
    } 
}); 

Tôi không thể tìm ra cách chặn cho đến khi hàng đợi được thoát. Bản thân Android đang ngăn cản tôi thực hiện rất nhiều thứ mà tôi đã thử (như mở rộng Handler và ghi đè phương thức postDelayed, v.v.)

Bất cứ ai có bất kỳ đề xuất nào về cách xử lý postDelayed?

Tôi muốn tránh uiController.loopMainThreadForAtLeast, mà dường như hacky (giống như một Thread.sleep sẽ)

Trả lời

8

Khi Espresso đợi, nó thực sự tính đến MessageQueue, nhưng theo cách khác với suy nghĩ của bạn. Để là nhàn rỗi, hàng đợi phải trống, hoặccó các tác vụ sẽ chạy trong hơn 15 mili giây từ bây giờ.

Bạn có thể tự kiểm tra mã, đặc biệt là phương pháp loopUntil() trong UiControllerImpl.java và tệp QueueInterrogator.java. Trong tập tin thứ hai, bạn cũng sẽ tìm thấy logic của cách Espresso kiểm tra MessageQueue (phương pháp determineQueueState()).

Bây giờ, cách giải quyết vấn đề của bạn? Có rất nhiều cách:

  1. Sử dụng AsyncTask thay vì Handler, ngủ trên sợi nền và thực hiện hành động onPostExecute(). Điều này thực hiện điều này bởi vì Espresso sẽ đợi AsyncTask để hoàn thành, nhưng bạn có thể không thích chi phí của một chủ đề khác.

  2. Ngủ trong mã thử nghiệm của bạn, nhưng bạn không thích phương pháp đó.

  3. Viết tùy chỉnh IdlingResource: đây là cơ chế chung để cho Espresso biết khi có gì đó không hoạt động để có thể chạy hành động và xác nhận.Đối với phương pháp này bạn có thể:

    • Sử dụng các lớp CountingIdlingResource mà đi kèm với Espresso

    • Gọi increment() khi bạn gửi Runnable của bạn và decrement() bên trong Runnable sau logic của bạn đã chạy

    • đăng ký của bạn IdlingResource trong quá trình thiết lập thử nghiệm và hủy đăng ký trong giọt nước mắt

Xem thêm: docs and sample, another sample

+1

Tôi đang suy nghĩ tôi có thể chỉ trừu tượng ra đẩy của tin nhắn vào hàng đợi, và tiêm một số thực hiện khác hoạt động như một IdlingResource. Tôi sẽ có một cài đặt mặc định trong mã của tôi để xử lý cho trình xử lý và trong mã thử nghiệm, mã này là IdlingResource và các điều chỉnh/giảm giá – Matt

0

Theo như tôi biết không có chờ đợi cho hoạt động để hoàn thành phương pháp trong espresso. Bạn có thể thực hiện phiên bản waitForCondition của riêng mình, một thứ gì đó mà rô bốt có. Bằng cách đó bạn sẽ chỉ chờ đợi miễn là cần thiết và bạn có thể phát hiện các vấn đề với hoạt động của bạn không hoàn thành.

Bạn về cơ bản sẽ thăm dò tình trạng của bạn mỗi x ms, giống như vậy.

while (!conditionIsMet() && currentTime < timeOut){ 
    sleep(100); 
} 

boolean conditionIsMet() { 
    return "espresso check for if your splash view exists"; 
} 
+0

Vấn đề là android cung cấp cho bạn không có cách nào để thực sự nhìn vào hàng đợi thông điệp để xem nếu bất cứ điều gì đang xếp hàng. Nó sẽ phải là một cái gì đó đã bị chặn và thay thế vào thời gian khởi động (mà tôi nghĩ là những gì robotium làm). – Matt

+0

Lớp waitForCondition chỉ là bình chọn như điều kiện bạn tự viết. Đối với robot kiểm tra hàng đợi, tôi không tin như vậy, tôi đã nhìn thấy các vấn đề như bạn đang có với robotium quá. – JohanShogun

+0

Đối với trường hợp sử dụng này, bạn sẽ có thể chờ đợi cho hành động đã diễn ra, thay vì nhìn vào hàng đợi tin nhắn (mà thực sự là thú vị hơn từ một điểm kiểm tra). – JohanShogun

Các vấn đề liên quan