Android JUnit 首选项测试

发布于 2024-11-28 06:45:01 字数 541 浏览 3 评论 0原文

一个相当正常的场景:Android 应用程序有一个首选项活动,从 ListPreference 中选择一个选项会触发代码来更改该 ListPreference 的摘要文本。即:从颜色 ListPreference 中选择“绿色”将通过 onPreferenceChange 回调将 ListPreference 的摘要文本更改为“绿色”。

我希望能够使用 Android JUnit 测试来确认这些摘要更改均已正确执行。然而,关于如何做到这一点的信息似乎很少。

我尝试过在测试线程中和通过 runOnUiThread() 在 ListPreference 上使用 setValue() 的变体,但没有成功 - 这不会触发对onPreferenceChange()。我还在调用 setValue() 后尝试过 getInstrumentation().waitForIdleSync() ,但这也没有成功。

所以,我的问题是:这是如何完成的?

谢谢!

A fairly normal scenario: an Android application has a preferences activity, and selecting an option from a ListPreference triggers code to change that ListPreference's summary text. ie: Selecting "Green" from a color ListPreference would change the ListPreference's summary text to "Green" through a onPreferenceChange callback.

I'd like to be able to use the Android JUnit testing to confirm that these summary changes are all being performed correctly. However, there seems to be very little information out there on how to do this.

I've tried variations of using setValue() on ListPreference, both in the test thread and through runOnUiThread(), with no success - this doesn't trigger the call to onPreferenceChange(). I've also tried getInstrumentation().waitForIdleSync() after calling setValue(), but that's also with no success.

So, my question is: how is this done?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

仙气飘飘 2024-12-05 06:45:01

几个小时的工作产生了这个工作解决方案,但我很好奇是否其他人有更好的解决方案。此代码的灵感来自 这个解决方案针对类似的问题,但这种情况有两点不同:

  1. 它是供 Android JUnit 使用的,这意味着它需要调用ListPreference UI 通过 runOnUiThread() 单击。
  2. 它期望使用偏好类别,这使得查找要单击的位置(相对于整个偏好列表)变得复杂。上述解决方案仅适用于没有偏好类别的情况。

此方法将接受特定 ListPreference 项目的键,以及列表中要单击的项目的位置。然后它将执行该列表项单击,其他代码将执行我正在寻找的检查。

请注意,这需要在 setUp() 方法中调用 getActivity() 之前设置 setActivityInitialTouchMode(true);

private void clickListPreference(String _listPreferenceKey, int _listItemPos){
    final String listPreferenceKey = _listPreferenceKey;
    final int listItemPos = _listItemPos;

    mActivity.runOnUiThread(
            new Runnable() {
                public void run() {
                    // get a handle to the particular ListPreference
                    ListPreference listPreference= (ListPreference) mActivity.findPreference(listPreferenceKey);

                    // bring up the dialog box  
                    mActivity.getPreferenceScreen().onItemClick( null, null, getPreferencePosition(), 0 ); 

                    // click the requested item
                    AlertDialog listDialog = (AlertDialog) listPreference.getDialog();
                    ListView listView = listDialog.getListView();
                    listView.performItemClick(listView, listItemPos, 0);
                }

                /***
                 * Finding a ListPreference is difficult when Preference Categories are involved,
                 * as the category header itself counts as a position in the preferences screen
                 * list.
                 * 
                 * This method iterates over the preference items inside preference categories
                 * to find the ListPreference that is wanted.
                 * 
                 * @return The position of the ListPreference relative to the entire preferences screen list
                 */
                private int getPreferencePosition(){
                    int counter = 0;
                    PreferenceScreen screen = mActivity.getPreferenceScreen();

                     // loop over categories
                    for (int i = 0; i < screen.getPreferenceCount(); i++){
                        PreferenceCategory cat = (PreferenceCategory) screen.getPreference(i);
                        counter++;

                        // loop over category items
                        for (int j = 0; j < cat.getPreferenceCount(); j++){ 
                            if (cat.getPreference(j).getKey().contentEquals(listPreferenceKey)){
                                return counter;
                            }
                            counter++;
                        }
                    }
                    return 0; // did not match
                }
            }
    );

    getInstrumentation().waitForIdleSync();
}

A few more hours of work produced this working solution, but I'm curious if anyone else has a better solution. This code was inspired by this solution to a similar question, but this case is different in two ways:

  1. It's intended for use by Android JUnit, which means it needs to call the ListPreference UI clicks via runOnUiThread().
  2. It expects there to be preference categories in use, which complicate finding the position (relative to the entire preferences list) to click. The above mentioned solution only works in cases without preference categories.

This method will accept the key for a particular ListPreference item, along with the position of the item in the list to be clicked. It will then perform that list item click, and other code would do the checking I'm looking for.

Note that this requires setActivityInitialTouchMode(true); to be set before the getActivity() call in the setUp() method.

private void clickListPreference(String _listPreferenceKey, int _listItemPos){
    final String listPreferenceKey = _listPreferenceKey;
    final int listItemPos = _listItemPos;

    mActivity.runOnUiThread(
            new Runnable() {
                public void run() {
                    // get a handle to the particular ListPreference
                    ListPreference listPreference= (ListPreference) mActivity.findPreference(listPreferenceKey);

                    // bring up the dialog box  
                    mActivity.getPreferenceScreen().onItemClick( null, null, getPreferencePosition(), 0 ); 

                    // click the requested item
                    AlertDialog listDialog = (AlertDialog) listPreference.getDialog();
                    ListView listView = listDialog.getListView();
                    listView.performItemClick(listView, listItemPos, 0);
                }

                /***
                 * Finding a ListPreference is difficult when Preference Categories are involved,
                 * as the category header itself counts as a position in the preferences screen
                 * list.
                 * 
                 * This method iterates over the preference items inside preference categories
                 * to find the ListPreference that is wanted.
                 * 
                 * @return The position of the ListPreference relative to the entire preferences screen list
                 */
                private int getPreferencePosition(){
                    int counter = 0;
                    PreferenceScreen screen = mActivity.getPreferenceScreen();

                     // loop over categories
                    for (int i = 0; i < screen.getPreferenceCount(); i++){
                        PreferenceCategory cat = (PreferenceCategory) screen.getPreference(i);
                        counter++;

                        // loop over category items
                        for (int j = 0; j < cat.getPreferenceCount(); j++){ 
                            if (cat.getPreference(j).getKey().contentEquals(listPreferenceKey)){
                                return counter;
                            }
                            counter++;
                        }
                    }
                    return 0; // did not match
                }
            }
    );

    getInstrumentation().waitForIdleSync();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文