1

I am using espresso for instrumentation test cases. I have structure similar to the image below for my production source code:

enter image description here

What i would like to know is should the androidTest (instrumentation tests packages) follow the same hierarchy ? What would be the benefits ? if i dont follow the same hierachy for instrumentation tests will it lead to any scalability issues or issues in general ? Right now i have created instrumentation tests folder that is nothing like the production source code and everything works but i saw blogs where developers keep the packages aligned, why ? and to be clear, for unit testing i would keep them to same as it makes sense to match packages but im not so sure about for instrumentation tests .

j2emanue
  • 60,549
  • 65
  • 286
  • 456
  • So you want to wright a test for MyClass and you want to use a different structure for your test and while you are at it will name the test "theTest" and when things get complicated you will remember theTest test MyClass. The spec will eventually change, it always does and the next sucker will know what test test what class. It helps to organize things and keep the same structure append "test" to the test class for example use MyClassTest to test MyClass. Google "Abbot and Costello Who's on first" – Pomagranite Dec 15 '17 at 04:29
  • my project is a white labeled project. so it changes into at least 3 different projects. so for some customers its a blue project, for other customers its a red project and for another custom its a orange project. the project changes based on location. this is why its hard for me to give structure as i need to test different variations. what do yo suggest ? – j2emanue Dec 16 '17 at 06:18
  • Sounds like gradle flavors would solve this kind of problem if I understand you https://stackoverflow.com/questions/16737006/using-build-flavors-structuring-source-folders-and-build-gradle-correctly You can build a paid version and free version or location based flavors. I recomend keping directory structure consistant and Class names maybe append "test" or "unitTest" example MyClassTest – Pomagranite Dec 16 '17 at 15:06

1 Answers1

3

Instrumentation Tests are about testing different app components working together to achieve a certain functionality such as, in the app provided, logging in. Since this is a high level overview it would make things easy to find tests for certain high level feature which would definitely contain more granular tests regarding that feature such as entering an invalid email format in the email field and so on. So personally I would think of the instrumentation tests structured as such:

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...)

That way the tests can be easily understood and built upon or changed as the code changes.

With unit tests, testing is made on a single (hence so-called unit) component of the app such as the LoginPresenter. Usually the test would mock up all needed dependencies for the component (probably using Mockito or other kind of mock injection) and verify that the component is behaving properly as per logic. Note that for best practices, unit tests don't need a device/emulator or activity related dependency like Context and hence the reason why an architecture like in your example MVP is needed to be able to carry out unit testing on your local machine (PC or laptop). But this does not stop you from creating unit tests within the androidTest folder, specifically in cases where you're testing a component that needs a device or emulator for hardware related component testing like NFC or GPS, etc...

So in that case I would personally end up with something like this:

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...)

With regards to different variants that your app consists of, the Android Gradle Plugin provides you with a command to figure out where to place variant dependent tests. Simply run gradlew :app:sourceSets in your project root directory and you'll get for every variant (whether its for test, androidTest or none) the directory structure for it. Check out this link for more info: Configure Build Variants. Also don't forget to checkout @Rule in JUnit while building your tests.

As a final wrap up, a link to a good Codelab example to illustrate most of the above: Android Testing Codelab

Zoe
  • 27,060
  • 21
  • 118
  • 148
ahasbini
  • 6,761
  • 2
  • 29
  • 45