I am attempting to test simple UI with the following test case, The main idea is to set in the test some of the UI text (to mimic user input) and then actively click an event.
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()));
}
}
the running result is the exception -
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)
This happens on each access to the UI elements and i was unable to avoid it by using handles or async task ? any suggestions?
This is an old question, but I'm giving you an answer anyway, in case someone stumbles upon it.
You are not allowed to change states of UI widgets from anywhere but the main thread (UI thread). Your performClick must be done like this:
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
mCount.performClick();
}
});
But that is not all, you will also need to sync your instrumentation test with the ui, by adding the following line:
getInstrumentation().waitForIdleSync();
The sync line is usually placed immediately after the runOnUiThread() code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With