Android 仪器测试 - 包结构的最佳实践

Android instrumentation tests - best practice for package structure

我正在使用 espresso 进行仪器测试用例。我的生产源代码的结构类似于下图:

我想知道的是androidTest(仪器测试包)应该遵循相同的层次结构吗?会有什么好处?如果我不遵循相同的仪器测试层次结构,它会导致任何可扩展性问题或一般问题吗?现在我已经创建了仪器测试文件夹,它与生产源代码完全不同并且一切正常但我看到开发人员保持包对齐的博客,为什么?需要明确的是,对于单元测试,我会让它们保持相同,因为匹配包是有意义的,但我不太确定对于仪器测试。

仪器测试是关于测试不同的应用程序组件一起工作以实现特定功能,例如在提供的应用程序中登录。由于这是一个高级概述,因此可以很容易地找到某些高级测试功能肯定会包含有关该功能的更精细测试,例如在电子邮件字段中输入无效的电子邮件格式等。所以我个人会想到这样构造的仪器测试:

androidTest
\--- java
     \--- com.example.myapp
          +--- login
          |    +--- LoginTest (Class, Scenario 1 of high level feature, ex: already signed up login)
          |    |    +--- valid_email_login (method)
          |    |    +--- invalid_email_login (method)
          |    |    \--- no_internet_connection (method)
          |    \--- AnotherLoginTest (Class, Scenario 2 of high level feature, ex: create new account login)
          |         \--- test_for_scenario_2 (method)
          \--- another_high_level_feature (and so on...)

这样可以很容易地理解和构建测试,或者随着代码的变化而改变测试。

对于单元测试,测试是在应用程序的单个(因此称为单元)组件上进行的,例如 LoginPresenter。通常测试会为组件模拟所有需要的依赖项(可能使用 Mockito 或其他类型的模拟注入)并验证组件是否按照逻辑正确运行。请注意,对于最佳实践,单元测试不需要像 Context 这样的 device/emulator 或 activity 相关依赖项,因此需要像您的示例 MVP 这样的架构才能能够在本地机器(PC 或笔记本电脑)上执行单元测试。但这不会阻止您在 androidTest 文件夹中创建单元测试,特别是在您测试需要设备或模拟器进行硬件相关组件测试(如 NFC 或 GPS 等)的组件时...

所以在那种情况下,我个人会得到这样的结果:

src
+--- androidTest
|     |--- java
|          \--- com.example.myapp
|               +--- unit
|                    \--- (unit\component related tests that need device\emulator go here)
|               \--- instrumentation (components working together related tests go here)
|                    +--- login
|                    |    +--- LoginTest (Class, Scenario 1 of high level feature, ex: already signed up login)
|                    |    |    +--- valid_email_login (method)
|                    |    |    +--- invalid_email_login (method)
|                    |    |    \--- no_internet_connection (method)
|                    |    \--- AnotherLoginTest (Class, Scenario 2 of high level feature, ex: create new account login)
|                    |         \--- test_for_scenario_2 (method)
|                    \--- another_high_level_feature (and so on...)
\--- test
     |--- java
          \--- com.example.myapp (unit\component related tests that don't need device\emulator go under here)
               +--- presenters
               |    +--- LoginPresenterTest
               |    |    +--- view_loading (method)
               |    |    +--- disable_views_when_loading (method)
               |    |    \--- another_unit_test (method)
               |    \--- AnotherPresenterTest
               \--- models (and so on...)

关于您的应用程序包含的不同变体,Android Gradle 插件为您提供了一个命令来确定在何处放置变体相关测试。只需在您的项目根目录中 运行 gradlew :app:sourceSets ,您将获得每个变体(无论是 testandroidTest 还是 none)的目录结构它。查看此 link 了解更多信息:Configure Build Variants。也不要忘记在构建测试时在 JUnit 中检查 @Rule

作为最后的总结,link 一个很好的 Codelab 示例来说明以上大部分内容:Android Testing Codelab