在Android应用中,哪些内容需要进行单元测试?

23

我的应用程序大多数是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视图,我预计会发现什么?我一定是从一个过于有限的角度来思考这个问题了

所以,欢迎提供见解


我也一直在想这个问题,因为你查看的所有教程都建议检查某些特定的方法,但是当你有一个基于表单的应用程序将提交数据并从服务器获取相关数据时,到底应该在单元测试中编写什么。 - Rajen Raiyarela
3个回答

30

您的问题有很多方面,但在我看来,您可能不需要在项目中使用单元测试。

当您需要将大量业务逻辑添加到项目中时,单元测试确实非常出色。在这种情况下,您可能希望将应用程序分成多个层(例如三层架构),以便在其他方面为业务逻辑层添加一些自然隔离,并用单元测试的安全网进行覆盖。

这个安全网可以在重构业务层时保护你,这是你从单元测试中想要的主要内容之一(尽管TDD可以提供一些不错的额外副作用)。

然而,单元测试并不是完美的解决方案,它们可能会造成成本,有时代价很高。好的单元测试是隔离的(即处理小代码块)。这意味着您必须添加抽象层次结构,以便将类放入测试中。

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

话虽如此 - 单元测试的价值与您要引入的抽象业务逻辑量成比例。您也可以这样考虑 - 如果在架构中添加抽象层次结构是过度的,那么不要添加单元测试 - 它们只会增加事情变得更加复杂(从架构和构建方面考虑)。

根据您的描述 - 您的典型应用程序往往非常类似于外部服务器端的展示层。它除了在Android手持设备上显示信息并将用户操作转换为服务端命令来控制主要业务逻辑外,并没有太多作用。

使用这种方法,您可能编写的大部分代码都与“如何显示这个和那个”或“如何在这种情况下向服务器发送信号”相关。这种代码显然高度依赖于平台,这意味着如果您确实想对其进行测试,则必须模拟大量Android特定的代码/行为。

现在,Android是一个比较特殊的平台。它被设计成既能够优化性能又能够让开发人员快速启动和制作应用程序。通常这意味着你必须使用/扩展一些“瑞士军刀”类来加速编写代码,但是对这些类进行模拟可能会变得非常困难。更不用说你必须了解平台在底层的工作方式才能使这些模拟有用。换句话说,制作这些测试的开销将会很大。

还有一件事情就是测试呈现层存在的问题,即它们比业务层更加动态地改变。当然这意味着你将不得不重构这些测试,从而增加更多的开销。

不过,我必须谈到各种实用/助手类。即使这些类属于呈现层并且依赖于Android代码,但如果它们执行某些相当复杂的逻辑,并且易于模拟并编写单元测试,则实际上这可能是个好主意。但是,如果你有很多这样的代码,这可能表明你没有设计好你的架构/分层,需要重新考虑你正在做什么。

最后,要回答你的问题,你首先要回答以下问题:

将抽象层添加到应用程序(在你的情况下似乎是这样)是否会过度设计?如果是,不要使用单元测试,它们只会拖慢你的速度。如果不是,请使用它们。

你将进行大量重构吗?如果这是一个有很多代码需要维护的大型项目 - 你可能会,因此需要投资于分层和单元测试(但是初步看来,这似乎不是你的情况)。如果不是你的情况,请不要费心单元测试,快进。

你需要经常模拟平台以编写单元测试吗?如果是(似乎是你的情况),不要编写单元测试 - 它们不值得这个努力。

希望这可以帮助到你。


0

在 Android 中进行单元测试通常与良好的架构和分层有关。现在最流行的是 Clean Arch,它关注可维护性和可测试性。架构的每个部分都有一个明确的目的。我们只需要指定它并检查它是否每次都能完成其工作。

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

除了任何良好的模块化和解耦设计之外,架构中包含业务逻辑的函数和类,如果这些遵循单一职责原则(它们应该这样做),那么很可能应该进行测试。

在编码之前和编码过程中考虑测试。这样,您可以编写可测试和解耦的代码。将测试用作类规范,如果可能,请在编写代码之前编写测试。

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


-1

来自 Android.Docs

为了测试Android应用程序,您通常会创建以下类型的自动化单元测试:

本地测试:仅在本地机器上运行的单元测试。这些测试被编译为在Java虚拟机(JVM)上本地运行,以最小化执行时间。使用此方法来运行没有依赖于Android框架或可以使用模拟对象填充其依赖关系的单元测试。

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

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


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