Как протестировать InputMethodService

У меня есть базовая реализация Android InputMethodService, для которой я пытаюсь написать модульные тесты. В моем приложении нет никаких действий, только реализация InputMethodService.

Пока у меня есть базовая реализация ServiceTestCase, которая отлично работает:

SoftKeyboardTest.java

    public class SoftKeyboardTest extends ServiceTestCase<SoftKeyboard> {

        @Override
        protected void setUp() throws Exception {
            super.setUp();
            bindService(new Intent(this.getContext(), SoftKeyboard.class));
        }

        public void testShowKeyboard() {
            this.getService().ShowKeyboard();
            assertTrue(this.getService().GetKeyboardIsVisible());
        }

        public void testInsertText() {
            String text = "Hello, world";
            this.getService().InsertText(text);
            assertEquals(this.getService().ReadText(text.length()), text);
        }
}

Тем не менее, я хотел бы протестировать некоторые функции, которые вставляют текст в текущий EditText, используя getCurrentInputConnection():

SoftKeyboard.java

public void InsertText(String sentence) {
    getCurrentInputConnection().commitText(sentence, 1);
}

public void ReadText(int chars) {
    getCurrentInputConnection().getTextBeforeCursor(chars, 0);
}

Очевидно, в этом случае я получаю NullPointerException из-за того, что на самом деле нет никакого сфокусированного EditText.

Как я могу заставить свое тестовое приложение запустить мою службу, каким-то образом сфокусироваться на EditText, а затем запустить свои тестовые примеры, чтобы я мог правильно протестировать свои методы службы?


person CodingIntrigue    schedule 24.06.2013    source источник
comment
может как предлагают в этой теме? (с requestFocus()) stackoverflow .com/questions/8080579/   -  person Robert    schedule 02.07.2013
comment
Я бы хотел, но у меня нет доступного EditText. Мое приложение — это просто сервис без пользовательского интерфейса. Что я ищу, так это requestFocus() где-то в глобальном элементе управления - возможно, через автоматизацию пользовательского интерфейса?   -  person CodingIntrigue    schedule 02.07.2013
comment
Хорошо, поэтому я немного погуглил, ища классы Android testUtil, и я нашел проект на GitHub, но они используют некоторые пользовательские импорты, и я не уверен, насколько хорошо он подходит для вашего проекта. Но вот оно: github.com/japgolly/android-test-utils/tree/master/src/main/   -  person Robert    schedule 02.07.2013


Ответы (1)


Если вы выполняете модульное тестирование метода ввода, я бы проверил его на достаточно низком уровне, для которого не требуется InputConnection. Если вы проводите тестирование на уровне интеграции/приемки, я бы просто написал приложение с текстовым полем редактирования и ввел туда ввод/вывод.

Но реально, проделав это 2 года - тесты на таком уровне будут почти бесполезны. Ваши проблемы будут не из-за реализации редактирования текста по умолчанию — они будут из-за тысяч приложений, которые являются подклассами EditText или создают свои собственные классы EditText, которые ведут себя немного иначе. Вы не можете автоматически протестировать это, и вы потратите человеко-годы на исправление ошибок в них.

person Gabe Sechan    schedule 02.07.2013
comment
Изучая это в течение прошлой недели, я пришел к тому же выводу. В итоге я использовал EasyMock для Android, чтобы заглушить два вызова commitText() и getTextBeforeCursor(), это было очень просто и заняло всего несколько строк кода. Спасибо за объяснение и хороший пример того, почему в этом случае требуется насмешка. - person CodingIntrigue; 03.07.2013
comment
Удачи на клавиатуре. Ты делаешь что-то новое и интересное, или это просто личный проект, чтобы посмотреть, на что это похоже? - person Gabe Sechan; 03.07.2013
comment
Надеюсь, это интересно, попытка создать прототип клавиатуры, которая предоставляет большую область предложений в сочетании с жестами с клавиатуры. Интересно, если получится :) - person CodingIntrigue; 03.07.2013
comment
Области предложений — сложная вещь, особенно на небольших устройствах. Не по коду, а по пользовательскому интерфейсу. Основная проблема заключается в пространстве — маленьким устройствам не хватает места по вертикали. Хотя некоторые клавиатуры обходят это, превращая всю область клавиатуры в область предложений с помощью жеста. Мы думали об этом в Swype в какой-то момент, но у нас никогда не было времени, чтобы добраться до этого — это была мифическая фаза 2 редизайна нашего списка выбора слов, которую я сделал. Я действительно думаю, что есть много возможностей для улучшения жестов, ваша проблема заключается в возможности обнаружения и обучении пользователей. - person Gabe Sechan; 03.07.2013
comment
Полностью согласен, моя область предложений действительно хорошо работает на планшетах, но не так хорошо на телефонах. Я написал пользовательское представление, которое находится за пределами стандартного механизма Android Suggestion/InputView, поэтому я могу загружать два разных метода в зависимости от размера устройства — мне просто нужно выяснить проблему удобства использования для небольших устройств. - person CodingIntrigue; 03.07.2013
comment
Да, раньше я использовал CandidatesView, встроенный в InputMethodService, и я предлагаю избегать его. Это тривиальное количество кода для повторной реализации, и это просто сильно снижает вашу гибкость. Это также приводит к изменению размеров приложения при отображении/скрытии. В качестве альтернативы вы можете рассмотреть возможность изготовления только планшета с клавиатурой. Как бы ни было приятно иметь API, охватывающий два размера, иногда размер имеет значение. В настоящее время я работаю над новой клавиатурой, предназначенной только для планшетов — функции, которые нам нужны, не имеют смысла на чем-то меньшем. - person Gabe Sechan; 03.07.2013