【问题标题】:Accessing view using Robotium - CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views使用 Robotium 访问视图 - CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触摸其视图
【发布时间】:2023-03-05 06:42:01
【问题描述】:

我正在尝试使用 id 访问我的应用程序的搜索栏,然后输入搜索文本并提交,但是当我尝试获取视图时,我的测试用例失败并抛出异常:

添加完整日志

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:5932)
at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:873)
at android.view.ViewGroup.invalidateChild(ViewGroup.java:4253)
at android.view.View.invalidate(View.java:10663)
at android.widget.TextView.invalidateRegion(TextView.java:4609)
at android.widget.TextView.invalidateCursor(TextView.java:4552)
at android.widget.TextView.spanChange(TextView.java:7434)
at android.widget.TextView$ChangeWatcher.onSpanAdded(TextView.java:9130)
at android.text.SpannableStringBuilder.sendSpanAdded(SpannableStringBuilder.java:979)
at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:688)
at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:588)
at android.text.Selection.setSelection(Selection.java:76)
at android.text.Selection.setSelection(Selection.java:87)
at android.text.method.ArrowKeyMovementMethod.initialize(ArrowKeyMovementMethod.java:302)
at android.widget.TextView.setText(TextView.java:3777)
at android.widget.TextView.setText(TextView.java:3647)
at android.widget.EditText.setText(EditText.java:80)
at android.widget.TextView.setText(TextView.java:3622)
at com.expedia.search.test.SearchActivityTester.testAllCountries(SearchActivityTester.java:48)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:192)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)

下面是我的代码:

View searchBar = solo.getView("search_edit_text"); //get the element
searchBar.performClick(); //click on search bar
solo.sendKeys("My Search Query"); //enter my query
solo.sendKey(KeyEvent.KEYCODE_SEARCH);  //hit search on softkeyboard

我是 Android 自动化测试的新手,所以不知道。请建议。 另外,我使用的上述方法是否足以胜任这项工作?

这是我的测试课

public class SearchActivityTester extends ActivityInstrumentationTestCase2 {

private static final String LAUNCH_ACTIVITY_NAME = "com.my.aut.activity.SearchActivity";

private Solo solo;

private static Class<?> splashActivityClass;
static {
    try {
        splashActivityClass = Class.forName(LAUNCH_ACTIVITY_NAME);
    }
    catch (ClassNotFoundException e) {
        throw new RuntimeException(e);
    }
}

public SearchActivityTester() throws ClassNotFoundException {
    super(splashActivityClass);
}

@Override
protected void setUp() throws Exception {
    solo = new Solo(getInstrumentation(), getActivity());
}

public void testAllCountries() {
        solo.sleep(7000);
        solo.clickOnText("Countries");
        Log.d("clicked", "clicked on hotels");
        solo.sleep(2000);
        View searchBar = solo.getView("search_edit_text"); //get the element
           searchBar.performClick(); //click on search bar
           solo.sendKeys("My Search Query"); //enter my query
           solo.sendKey(KeyEvent.KEYCODE_SEARCH);  //hit search on softkeyboard


        List<ListView> list = solo.getCurrentViews(ListView.class);
        Log.d("****************", list.get(1).getId()+"");

        solo.sleep(3000);
}


@Override
public void tearDown() throws Exception {
    solo.finishOpenedActivities();

}

 }

【问题讨论】:

  • 通常,当您尝试从 Thread 代码访问 View 项目时会出现此错误。
  • 我无法得到这个“线程代码”,为什么会出错?显然,当我启动我的测试用例时会运行一个线程,因此最终视图仅从线程中获取。那么如何解决呢?
  • 另外,当我更改代码以访问 EditText 而不是 View 时,它显示它找不到带有 ID 的 EditText。代码是EditView searchBar = solo.getEditText("com.my.aut.R.id.search_bar_id")

标签: android automation robotium black-box-testing


【解决方案1】:

尝试将此代码集成到您的代码中:

private StackDemo mActivity;

public SearchActivityTester() throws ClassNotFoundException {
    super(splashActivityClass);
}

@Override
protected void setUp() throws Exception {
    solo = new Solo(getInstrumentation(), getActivity());
    mActivity = this.getActivity();
}

public void testAllCountries() {
    solo.sleep(7000);
    solo.clickOnText("Countries");
    Log.d("clicked", "clicked on hotels");
    solo.sleep(2000);

    mActivity.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            View searchBar = solo.getView("search_edit_text"); //get the element
            searchBar.performClick(); //click on search bar
        }
    });



    solo.sendKeys("My Search Query"); //enter my query
    solo.sendKey(KeyEvent.KEYCODE_SEARCH);  //hit search on softkeyboard


    List<ListView> list = solo.getCurrentViews(ListView.class);
    Log.d("****************", list.get(1).getId()+"");

    solo.sleep(3000);
}


@Override
public void tearDown() throws Exception {
    solo.finishOpenedActivities();

}

}

【讨论】:

  • 正如我所说,它的黑盒和我没有 AUT 的源代码,因此无法导入它的 MainActivity 类。
  • 在设置中你使用这个 mActivity = this.getActivity();所以你得到了 mainActivity
  • 但是编译时错误呢?比如“创建类 StackDemo”
  • 你能告诉我完整的java代码和错误日志吗?
  • 我只有一个测试类,我已经在问题中了。由于编译时错误,它不允许我创建任何 mActivity 实例。而且我想问题中也有日志。
【解决方案2】:

根据您为单元测试扩展的类(通常是ActivityInstrumentationTestCase2),您应该能够调用

getActivity() 

在返回的对象上,您可以调用 runOnUiThread 来更改 UI。

你可能想看看it

【讨论】:

  • ActivityInstrumentationTestCase2 是超类。我正在尝试找到一种访问搜索栏的方法,它只不过是 EditView,并且能够填写我的搜索查询并点击搜索键。
  • 如果它是超类,这意味着你正在扩展它。这意味着您可以调用 getActivity
  • 其实就是黑盒测试。我没有源代码,所以我无法导入我的 AUT 的 MainActivity 类
  • 你能发布你的测试课程吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-21
  • 1970-01-01
  • 2011-03-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多