What is DexCaches in Android VM

Device test an Android fragment

I struggled with the same question. Especially since most of the code samples are already out of date + Android Studio / SDKs are being improved so that old answers are sometimes no longer relevant.

First things first, you need to determine whether you will Instrumental or simple JUnit - Want to use tests.

The difference between them was suggested by S.D. here; In short: JUnit tests are easier and do not require an emulator. Instrumental - gives you the greatest possible experience with the actual device (sensors, GPS, interaction with other apps, etc.). Also read more about testing in Android.

1. JUnit test of fragments

Let's say you don't need heavy instrumental tests and simple Junit tests are sufficient. I use Nice framework Robolectric for this.

Add in gradle:

Mockito, AsserJ are optional, but I found them very useful so I strongly recommend including them as well.

Then put in Build variantsUnit tests as Test artifact: firmly.

Now it's time to write some real tests :-) Let's take the standard "Empty Activity with Fragment" project as an example.

I added a few lines of code to actually test something:

And great cow:

The Robolectic's test kit would look something like this:

That means we generate activity via Robolectric.setupActivity, a new fragment in setUp () of the test classes. You can optionally start the fragment immediately with setUp () or directly from the test.

NB! I have to didn't spend a lot of time on it but it seems almost impossible to tie it together with Dagger (don't know if it's easier with Dagger2) as you can't set custom test application with mock injections.

2. Instrumental examination of fragments

The complexity of this approach depends a lot on whether you are using dagger / dependency injection in the app you are trying to test.

In Build variants give Android Instrumental Tests as Test artifact: at.

In Gradle I add the following dependencies:

(again, almost all of them are optional, but they can make your life so much easier)

- If you don't have a dagger

This is a happy way. The difference to Robolectric is only in the small details.

Pre-step 1: If you are using Mockito, you need to have it run on the devices and emulators with this hack:

The MainActivityFragment remains as above. So the test set would look like this:

As you can see, the test class is an extension of the class ActivityInstrumentationTestCase2. Also, it is very important on the method startFragment to watch out for, which has changed compared to the JUnit example: by default, tests are not executed on the UI thread and we have to explicitly call the pending FragmentManager execution transactions.

- If you have a dagger

It's getting serious here :-)

First of all we will do the ActivityInstrumentationTestCase2 in favor of ActivityUnitTestCase-Class as the base class for all test classes of the fragment going on.

As usual, it is not that simple and there are several pitfalls (this is one of examples). So we have to ActivityUnitTestCase on ActivityUnitTestCaseOverride pimp.

It's a bit too long to post in full here so I'm uploading the full version of it to github;

Create an abstract AbstractFragmentTest for all of your fragment tests:

Here are some important things.

1) We set the method setActivity ()} override to set the AppCompact theme to the activity. Without that, the test suit will crash.

2) setUpActivityAndFragment () method:

I. creates activity (=> getActivity () starts to return a value not equal to zero in tests and in the app to be tested) 1) onCreate () of the called activity;

2) onStart () of the called activity;

3) onResume () of the called activity;

II. Attaches and begins to fragment with the activity

1) onAttach () of the fragment called;

2) onCreateView () of the fragment called;

3) onStart () of the fragment called;

4) onResume () of the fragment called;

3) createMockApplication () method: As in the non-dagger version, in pre-step 1 we activate mocking on the devices and on the emulators.

Then we replace the normal application with your injections with our custom TestApplication!

MockInjectionRegistration looks like this:

That is, instead of real classes, we provide the fragments with their mocked versions. (This is easy to understand, allows you to configure the results of method calls, etc.).

And the TestApplication is only your user-defined extension of the Application, which should support the setting of modules and initialize the ObjectGraph.

These were the first steps in writing the tests :) Now the easy part, the actual tests:

That's it! You have now activated Instrumental / JUnit tests for your fragments.

I sincerely hope this post helps someone.