什么单元测试,在Android应用程序中

时间:2013-05-22 15:57:45

标签: android unit-testing junit robotium android-testing

我的应用程序主要是GUI,它们可以与服务器进行大部分信息通信。如果出现任何问题,通常会在网络调用中或对JSON对象做出错误的假设。

单元测试不适合这些与网络相关的任务和与i / o相关的任务,否则它们不会被称为单元测试。

所以我试图在我的案例中收集单元测试的要点。为什么我会测试Android按钮是否可以单击或EditText可以看到我键入的内容?我只是不明白实施这些乏味的测试的效用

private void initElements(){
    placeButton = (Button) findViewById(R.id.currplace);
    placeButton.setText(MainActivity.this.getString(R.string.findingLocation));
    placeButton.setEnabled(false);
    selectplaceLayout = (LinearLayout)findViewById(R.id.selectplaceLayout);
    selectplaceLayout.setVisibility(View.GONE);
    splash = (RelativeLayout)findViewById(R.id.splashbg);
    infoLayout = (LinearLayout)findViewById(R.id.infoLayout);
}

如果以上方法通过,我的所有活动都在onCreate中运行,那么我知道应用程序有效。对此进行单元测试将是一个冗余耗时的事情。耗时,因为我不熟悉jUnit和Android测试框架中的所有方法。

所以,长话短说,重点是什么?有什么特别的方法我应该考虑这些测试吗?到目前为止,我所看到的所有示例和教程仅仅讨论了最简单的示例,为了简洁起见,但我无法想到在主要的客户端 - 服务器应用程序中进行单元测试的任何实际用途。

通过访问我已经知道并声明并初始化的android视图,我期望发现什么?我必须以过于有限的方式思考这个问题

所以,洞察力赞赏

3 个答案:

答案 0 :(得分:20)

您的问题有很多方面,但我认为 - 您可能不需要在项目中进行单元测试。

当您需要为项目提供大量业务逻辑时,单元测试才能真正发挥作用。在这种情况下,您可能希望将应用程序划分为多个层(例如,3层架构),以便为业务逻辑层添加一些自然隔离,并使用单元测试的安全网覆盖它。

这个安全网涵盖了业务层的重构,这是你从单元测试中得到的主要内容之一(TDD可以提供一些不错的额外副作用)。

然而,并非所有的独角兽和彩虹以及单位测试都可能会花费成本,有时它们会花费很多。良好的单元测试是隔离的(即处理小块代码)。这意味着您必须添加抽象层才能将您的类置于测试之下。

这可能会对您的系统或负面影响产生积极影响。分层使您的系统更加灵活,增加了复杂性。

说明了 - 单元测试的价值与您将在项目中引入的抽象业务逻辑的数量成正比。您也可以这样考虑它 - 如果在您的体系结构中添加抽象层是过度的 - 不要添加单元测试 - 它们只会使事情变得更复杂(架构和构建明智)。

根据您的描述 - 您的典型应用程序往往是一些外部服务器端的表示层。除了在Android手机上显示信息并将用户操作转换为服务器端的主要业务逻辑完成(控制)之外,它并没有那么多。

使用这种方法,您可能编写的大多数代码都与“如何显示此内容”或“如何在此情况下发送服务器信号”相关。这种代码显然在很大程度上依赖于平台,这意味着如果你想要将它置于测试中,你将不得不模拟许多Android特定的代码\行为。

现在,Android是一个特定的平台。它旨在进行性能优化,并允许开发人员快速启动和生成应用程序。通常这意味着你使用了一些“swiss-knife”类\ extend并且通常这会加速编写代码,但是嘲笑这些类可能会成为一个真正的地狱。更不用说你必须了解平台如何工作以使这些模拟有用。换句话说,进行这些测试的开销会很高。

测试表示层的另一个问题是它们比业务层更容易动态变化。当然,这意味着你必须重构这些测试,这会增加更多的开销。

我不得不说一些关于各种实用程序/辅助类的事情。即使这些类属于表示层并且确实依赖于Android代码,但做一些非常简单的逻辑,很容易为它们模拟和编写单元测试,它实际上可能是一个好主意去做这个。但是,如果你确实有很多这样的代码 - 这可能是你没有很好地设计你的架构/分层的信号,需要重新考虑你在做什么。

最后要回答你的问题,你必须先回答这些问题:

是否过度设计将与平台分离的抽象层添加到您的应用程序中(在您的情况下似乎会如此)?如果是 - 不要使用单元测试 - 它们只会慢下来如果不是 - 请使用它们。

你要重构很多吗?如果这是一个包含大量代码并因此维护的大型项目 - 你可能会这样做,所以投资分层和单元测试(但是,一目了然,它似乎这不是你的情况)。如果那不是你的情况 - 不要打扰单位测试并快速行动。

您是否需要大量模拟平台来编写单元测试?如果是(似乎是您的情况) - 不要编写单元测试 - 它们不值得付出努力。

希望这会有所帮助。

答案 1 :(得分:0)

来自Android.Docs

要测试Android应用,通常需要创建以下类型的自动化单元测试:

本地测试:仅在本地计算机上运行的单元测试。这些测试被编译为在Java虚拟机(JVM)上本地运行,以最大程度地缩短执行时间。使用这种方法可以运行不依赖于Android框架或可以通过使用模拟对象填充的依赖项的单元测试。

仪器测试:在Android设备或模拟器上运行的单元测试。这些测试可以访问检测信息,例如被测应用的上下文。使用这种方法来运行具有Android依赖项的单元测试,而使用模拟对象无法轻松填充这些依赖项。

注意:单元测试不适用于测试复杂的UI交互事件。相反,您应该使用UI测试框架,如自动化UI测试中所述。

答案 2 :(得分:0)

当您使用具有良好架构的分层时,通常在Android中具有相关性。如今最流行的是Clean Arch,它主要涉及可维护性和可测试性。架构的每个部分都有唯一的目的。我们只需要指定它,并每次都检查它是否确实在工作即可。

  • 在测试用例时,我们应该测试用例在存储库中调用正确的方法或执行其他用例。我们还应该测试用例是否返回正确的回调。
  • 在测试存储库时,应安排DAO –让它们返回或接收一些虚拟数据,并检查存储库是否以正确的方式处理了数据。
  • 在测试映射器(转换器)时,请指定映射器的输入,以及您期望从映射器获得的准确输出,然后断言它们是相等的。对服务,解析器等执行相同的操作。

除了任何良好的模块化和解耦设计之外,保留体系结构将在功能和类中包含业务逻辑,并且如果这些逻辑遵循单一职责原则(应该),则应该进行测试。

考虑在编码之前和编码期间进行测试。这样,您就可以编写可测试和解耦的代码。将您的测试用作类规范,并在可能的情况下在代码之前编写它们。

示例和扩展信息:https://five.agency/android-architecture-part-5-test-clean-architecture/