【问题标题】:Android JUnit testing of Preferences首选项的 Android JUnit 测试
【发布时间】:2011-08-03 20:07:09
【问题描述】:

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

我希望能够使用 Android JUnit 测试来确认这些摘要更改都正确执行。但是,关于如何执行此操作的信息似乎很少。

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

所以,我的问题是:这是怎么做到的?

谢谢!

【问题讨论】:

    标签: android unit-testing junit android-preferences


    【解决方案1】:

    几个小时的工作产生了这个可行的解决方案,但我很好奇是否有其他人有更好的解决方案。这段代码的灵感来自this solution 的一个类似问题,但这种情况在两个方面有所不同:

    1. 它是供Android JUnit使用的,这意味着它需要通过runOnUiThread()调用ListPreference UI点击。
    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();
    }
    

    【讨论】:

    • 此代码似乎不适用于现代基于片段的偏好活动,因为 findPreference() 方法已被弃用。您是否尝试过将代码迁移到新的偏好架构。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-07
    • 2012-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多