21

我的应用程序主要是与服务器通信以获取大部分信息的 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 视图,我期望发现什么?我必须以一种过于有限的方式思考这个问题

所以,洞察力赞赏

4

3 回答 3

28

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

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

这个安全网在业务层重构期间覆盖了您的屁股,这是您从单元测试中获得的主要内容之一(尽管 TDD 可以提供一些不错的额外副作用)。

然而,并不是所有的独角兽和彩虹和单元测试都可能需要花费,有时它们会花费很多。好的单元测试是孤立的(即处理小块代码)。这意味着您必须添加抽象层才能对您的类进行测试。

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

话虽如此 -单元测试的价值与您将在项目中引入的抽象业务逻辑的数量成正比。你也可以这样想——如果在你的架构中添加抽象层是多余的——不要添加单元测试——它们只会让事情变得更复杂(架构和构建明智)。

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

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

现在,Android 是某种特定的平台。它旨在优化性能并允许开发人员快速启动和生产应用程序。这通常意味着您使用了一些“瑞士刀”类\扩展,这通常会加快编写代码的速度,但模拟这些类可能会变成一个真正的地狱。更不用说您必须了解平台如何在后台工作以使这些模拟有用。换句话说,进行这些测试的开销将会很高。

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

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

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

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

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

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

希望这会有所帮助。

于 2013-05-24T19:24:10.327 回答
0

当您使用具有良好架构的某些分层时,Android 中的 UTesting 通常具有相关性。现在最流行的是 Clean Arch,它是关于可维护性和可测试性的。架构的每一部分都有一个目的。我们只需要指定它并检查它是否每次都能真正完成它的工作。

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

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

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

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

于 2020-07-15T04:52:51.283 回答
-1

来自Android.Docs

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

本地测试:仅在本地机器上运行的单元测试。这些测试被编译为在 Java 虚拟机 (JVM) 上本地运行,以最大限度地减少执行时间。使用这种方法来运行不依赖于 Android 框架或具有可以使用模拟对象填充的依赖项的单元测试。

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

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

于 2018-06-25T09:51:16.957 回答