2010-08-29 31 views
9

Tôi đang cố gắng kiểm tra giao diện người dùng đơn giản với trường hợp kiểm tra sau, Ý tưởng chính là đặt thử nghiệm một số văn bản giao diện người dùng (để bắt chước đầu vào của người dùng) và sau đó chủ động nhấp vào sự kiện .Thử nghiệm với các phần tử giao diện người dùng trong chế độ xem Android

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())); 
    } 

} 

kết quả chạy là ngoại lệ -

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) 

Điều này xảy ra trên từng truy cập vào các thành phần UI và tôi đã không thể tránh nó bằng cách sử dụng tay cầm hoặc công việc async? bất kỳ đề xuất?

Trả lời

30

Đây là một câu hỏi cũ, nhưng tôi vẫn trả lời bạn trong trường hợp ai đó tình cờ gặp nó.

Bạn không được phép thay đổi trạng thái của tiện ích con giao diện người dùng từ mọi nơi trừ chủ đề chính (chuỗi giao diện người dùng). performClick của bạn phải được thực hiện như thế này:

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

Nhưng đó không phải là tất cả, bạn cũng sẽ cần phải đồng bộ thử nghiệm thiết bị đo đạc của bạn với giao diện người dùng, bằng cách thêm dòng sau:

getInstrumentation().waitForIdleSync(); 

Dòng đồng bộ thường được đặt ngay sau mã runOnUiThread().

+0

Tôi đang gặp phải vấn đề như vậy 'waitForIdleSync();' gọi chính nó bị treo trong vòng lặp vô hạn. Gỡ lỗi vấn đề, thấy rằng, thông báo 'emptyRunnable()' được đăng thông qua trình xử lý không bị bắt gặp trong 'MessageQueue'. Có vẻ như một số vấn đề thời gian là hiện tại. Nhưng không chắc chắn, làm thế nào để xác định vị trí vấn đề. – ArunJTS

6

Sự cố là bạn chỉ có thể chạm/thay đổi chế độ xem từ chuỗi giao diện người dùng. Bạn có thể sử dụng một runnable như Rober vạch ra hoặc một chú thích.

Bạn có thể chạy tất cả các phương pháp bên trong một thử nghiệm trên thread UI bằng cách sử dụng @UiThreadTest annotation:

Cập nhật:

@ interface này được tán thành trong mức API 24.
Thay vào đó hãy sử dụng UiThreadTest. Các bài kiểm tra mới nên được viết bằng cách sử dụng Android Testing Support Library.

@UiThreadTest 
public void testSimpleDefaults(){ 
    double status = Double.valueOf(mStatus.getText().toString()); 
    eaten.setText(2); 
    mCount.performClick(); 
    assertEquals((status-2),Double.valueOf(mStatus.getText().toString())); 
} 
Các vấn đề liên quan