如何测试InputMethodService

8
我有一个基本的 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);
}

显然,在这种情况下,我会因为实际上没有任何焦点在的EditText而得到一个NullPointerException。
我该如何让我的测试应用程序启动我的服务,以某种方式聚焦于EditText,然后启动我的测试用例,以便我可以正确地测试我的服务方法?

也许可以像这个帖子中建议的那样使用requestFocus()函数来设置软输入法在Android文本框中的焦点。https://dev59.com/wGsz5IYBdhLWcg3wLEm8 - Robert
我想这样做,但我没有可用的EditText。我的应用程序只是一个没有前端UI的服务。我正在寻找的是在全局控件上使用requestFocus() - 也许通过UI自动化实现? - CodingIntrigue
好的,我在寻找Android testUtil类时进行了一些谷歌搜索,并在GitHub上找到了一个项目,但它们使用了一些自定义导入,我不确定它是否适合您的项目。但是这是它的链接:https://github.com/japgolly/android-test-utils/tree/master/src/main/java/com/github/japgolly/android/test/fest - Robert
1个回答

3
如果您正在对输入法进行单元测试,我建议将测试级别降低到不需要InputConnection的程度。如果您正在进行集成/验收级别的测试,我建议只需编写一个带有编辑文本字段的应用程序,并通过该应用程序进行输入/输出驱动。
但是,实际上,经过2年的尝试,这个级别的测试几乎没有用处。您的问题不会来自默认的编辑文本实现,而是来自数千个子类化EditText或创建自己的EditText类的应用程序,它们的行为略有不同。您无法自动测试,而且您将花费多年的时间修复它们的错误。

经过过去一周的研究,我得出了同样的结论。最终我使用了EasyMock for Android来存根(commitText()和getTextBeforeCursor()两个调用),非常简单,只需要几行代码。感谢您的解释和为什么在这种情况下需要模拟的好例子。 - CodingIntrigue
祝你在键盘上好运。你在做什么新的有趣的事情,还是这只是一个个人项目来看看它是什么样子? - Gabe Sechan
希望有趣,尝试构建一个键盘的原型,它提供了一个大的建议区域,结合键盘手势。如果能够实现将会很有趣 :) - CodingIntrigue
建议区域是一个棘手的问题,特别是在较小的设备上。不是在编码方面,而是在用户界面方面。主要问题是空间——小型设备缺乏垂直空间。虽然一些键盘通过将整个键盘区域转换为手势建议区域来解决这个问题。我们曾经在Swype考虑过这个问题,但从未有时间去实现它——这是我进行单词选择列表重新设计的神话阶段2。我认为手势改进有很大的发展空间,你需要解决的问题是发现性和用户教育。 - Gabe Sechan
完全同意,我的建议区在平板电脑上运行得非常好,但在手机上则不太理想。我编写了一个自定义视图,它位于Android默认的建议/InputView机制之外,因此我可以根据设备的大小加载两种不同的方法 - 我只需要解决小型设备的可用性问题即可。 - CodingIntrigue
是的,之前使用过InputMethodService内置的CandidatesView,我的建议是要避免使用它。重新实现它只需要很少的代码量,而且它会大大降低你的灵活性。它还会在显示/隐藏时强制应用程序调整大小。另外,你可以考虑将你的键盘仅限于平板电脑。虽然有一个跨越两种尺寸的API很好,但有时候尺寸确实很重要。我目前正在开发一个新的键盘,只针对平板电脑 - 我们想要的功能在任何小一点的设备上都没有意义。 - Gabe Sechan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接