首选项的 Android JUnit 测试

标签 android unit-testing junit android-preferences

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

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

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

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

谢谢!

最佳答案

几个小时的工作产生了这个可行的解决方案,但我很好奇是否还有其他人有更好的解决方案。此代码的灵感来自 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();
}

关于首选项的 Android JUnit 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6932608/

相关文章:

unit-testing - 如何处理非回归测试?

spring-mvc - 在 Spring 安全中启用 CSRF 保护的单元测试 Controller

android - 表情符号在键盘按键标签和 textView 上看起来不同

android - 使用 Android 中非 Activity 类的内部存储

c# - 如何在 Visual Studio 2010 中调试 Nunit 测试

Django 测试提示缺少表

Java:如何测试调用 System.exit() 的方法?

java - 在 Cucumber java 中找不到步骤定义

android - 什么时候应该使用 `@+id` 而不是 `@id` ?

android - 如何将扫描的二维码图像保存到 Android 中的 ImageView 中?