Code coverage in Android Studio

Code coverage in Android Studio

Code coverage is a metrics that helps you understand how much % of your source code has been tested in unit/integration tests that you have written in any language.

In Android studio it is pretty easy to get the code coverage and also know the lines that were covered and lines that were not covered in testing.

To get simple code coverage( assuming you have default studio settings). Just go to the class and click on the test/class containing the test and choose to run with code coverage option.

Run Code coverage from the class
Run Code coverage from the class

Then just have a look at the folder list.

Next to the class you will have code coverage percentage.

Next if you want to know Coverage of all your test cases, just goto Java folder in testing, right click and run test with coverage. That would help you to determine coverage for all test cases.

However it is not still easy to tell that if code coverage < 100%, what portion of code we missed.

However it is quite easy thanks to Android Studio. Just goto your configuration, that you have created for testing and choose tracing radio button and check “Track per test coverage”

 

Code Coverage in Android Studio
Code Coverage

Run the coverage

Run Code Coverage
Run Code Coverage

You see this window

You see the coverage

Code Coverage in %
Code Coverage in %

You can now see lines not covered in red and covered in green . Lines in red needs test cases to be exercised upon them.

Lines not covered
Lines not covered

If the colors are too light for your eyes you can always darken them by clicking on the red bar

Configure code coverage indicators
Configure code coverage indicators

And then choosing colors of your likening

Change Colors of code coverage
Change Colors of code coverage

 

Using Daggger to mock SubComponent – Part 2

In the last tutorial we created a SubComponent to insert NetworkApi into an activity

Now if we use a UI testing frameworks for e.g. espresso, we know that we

Dagger-Courtsey pixabay.com
Dagger

need to mock a lot of things that interact with external system.

NetworkApi is one of the call that needs to be mocked because we cannot make actual network call in Api when doing just UI testing.

Mocking SubComponent is slightly more difficult than mocking Components.

Let’s see how to do that.

First we create a test , where we will call espresso methods to check the inputs etc.

&amp;amp;amp;amp;lt;br data-mce-bogus="1"&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;pre&amp;amp;amp;amp;gt;/**
 * Created by AKS on 10/18/2017.
 */
@RunWith(AndroidJUnit4.class)
@CustomScope
public class MockActivityTest {

    @Inject
    NetworkApi networkApi;
    @Rule
    public ActivityTestRule&amp;amp;amp;amp;amp;lt;MainActivity&amp;amp;amp;amp;amp;gt; activityRule = new ActivityTestRule&amp;amp;amp;amp;amp;lt;&amp;amp;amp;amp;amp;gt;(
            MainActivity.class,
            true,     // initialTouchMode
            false);   // launchActivity. False so we can customize the intent per test method

    @Before
    public void setUp() {

        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
        CustomApplication app
                = (CustomApplication) instrumentation.getTargetContext().getApplicationContext();
        MockSubAppComponent component = (MockSubAppComponent) app.getAppSubComponent();
        component.inject(this);

    }

    @Test
    public void testThis(){
        activityRule.launchActivity(new Intent());
    }
}&amp;amp;amp;amp;lt;/pre&amp;amp;amp;amp;gt;

 

There are a few important points . We need to inject the mock into our test class

@Inject
NetworkApi networkApi;

Next, we create a rule where we do not start activity automatically


@Rule
public ActivityTestRule<MainActivity> activityRule = new ActivityTestRule<>(
MainActivity.class,
true, // initialTouchMode
false); // launchActivity. False so we can customize the intent per test method

And we leave out the setup for now .

Let us instead focus on module that will be used to provide mock NetworkApi


@Module
public class MockNetworkApiModule {

@CustomScope
@Provides
NetworkApi provideNetworkApi(){

return mock(NetworkApi.class);
}
}

The MockAppComponent will subclass AppComponent because where ever we can inject base class, we can safely inject subclass too


@Component
public interface MockAppComponent extends AppComponent {
MockSubAppComponent.Builder mockSubComponentBuilder();
}

The MockComponent looks similar to AppComponent

Then we have the MockSubComponent which extends SubComponent


@CustomScope
@Subcomponent(modules = {MockNetworkApiModule.class})
public interface MockSubAppComponent extends AppSubComponent{

public void inject(MockActivityTest mainActivity);

@Subcomponent.Builder
public interface Builder{

MockSubAppComponent subComponent();
}
}

We create the MockApplication class which subclasses CustomApplication class


public class MockApplication extends CustomApplication {

&nbsp;

@Override
protected MockSubAppComponent createSubComponent() {
return DaggerMockAppComponent
.builder()
.build()
.mockSubComponentBuilder()
.subComponent();
}
}

and here you can see how I built the mock subcomponent ( actually not very different than SubComponent construction.

Back to activity test method


@Before
public void setUp() {

Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
CustomApplication app
= (CustomApplication) instrumentation.getTargetContext().getApplicationContext();
MockSubAppComponent component = (MockSubAppComponent) app.getAppSubComponent();
component.inject(this);

}

We just get the MockApplication ( we will see how ) and then we use it to get subcomponent

Now how do we get MockApplication instead of CustomApplication. We create an object called as MockTestRunner.


public class MockTestRunner extends AndroidJUnitRunner {
@Override
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return super.newApplication(cl, MockApplication.class.getName(), context);
}
}

This runner class will provide us with MockApplication class .

But how do we cause Android to use this runner for testing.

Open build.gradle and

change the parameter for runner as follows


defaultConfig {
applicationId "com.instanect.testdaggersubcomponent"
minSdkVersion 15
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "com.instanect.testdaggersubcomponent.MockTestRunner"
}

make sure that you use the right package name .

That’s it !!

Delete any original configuration you have created because it does not pick up our runner. Run with new configuration.

Don’t forget to use same @CustomScope wherever relevant otherwise you will receive different objects in mocking and in actual activity.

Now write your espresso code knowing that you have successfully mocked Dagger SubComponent in your work 🙂

 

Using Dagger to mock subcomponent – Part 1

Dagger-Courtsey pixabay.com
Dagger

Dagger is a library that makes testing of code much possible. But Dagger can be hard to learn and difficult to wrap around your head even if the concept of Dagger revolves around Builder pattern and dependency injection.

This tutorial is not for learning Dagger but making a testable system ( for e.g. testing of UI with espresso) where you can inject mocks using Subcomponents.

What are subcomponents ?

Subcomponents are those components that are created to append modules to object graph created by main component using which we inject our activity with variables that we need to perform operations as well as mock with.

So if we need a variable that is needed application wide , we can put that in main component. But if need a few parameters that are only specific to an activity we can extend the object graph by declaring a Subcomponent and making sure that scope of that SubComponent is restricted the activity.

This post heavily borrows from and is inspired by Dagger 2 + Espresso 2 + Mockito 

This post shows how to create SubComponents , inject parameters from them into Activity and mock them in Instrumentation testing.

To start with we create a basic activity and create a parameter network Api to it


@CustomScope
public class MainActivity extends AppCompatActivity {

@Inject
NetworkApi networkApi;

Using @Inject we are telling Dagger that we want this variable to be set when activity is started. Maybe we will use it to make network calls during the lifecycle of activity

Now to fill it we have three pieces in our puzzle

An Application object that is available to all activities upon creation

A Module to provide real values to this variable when activity is started

and a component that takes data from the module and passes it to activity

( Dagger to that extent is quite simple 😉 )

So we create a Custom Application Object


public class CustomApplication extends Application {

Now we need to somehow tell the Android app to use this Custom Application when the app is started.

We can easily tell that by adding the line in AndroidManifest.xml


<application
 android:name=".CustomApplication"

Now the CustomApplication Object will be used in place of standard Application Object

Next

Creating a module

We know that we need to get the actual object for networkApi parameter to be instantiated somewhere. We do so in a class called as NetworkApiModule and to let Dagger know that it needs to use this module to provide the value we annotate it with @Module annotation


@Module
 public class NetworkApiModule {

@Provides
 NetworkApi provideNetworkApi(){

return new NetworkApi();
 }
 }

The implementation details are kept at minimum

Now to make passage of this variable to activity

Add component


@Component
 public interface AppComponent {

AppSubComponent.Builder subComponentBuilder();

}

But this component is slightly different when you compare it with other examples of Dagger. The AppComponent uses a builder to inject the networkApi using a subcomponent because probably we do not need networkApi at global level ( for e.g. because we make calls in only certain actvities and not all ) .

We saw that there is a subcomponent class which is being used by AppComponet , we create it like this


@Subcomponent(modules = {NetworkApiModule.class})
 public interface AppSubComponent {

public void inject(MainActivity mainActivity);

@Subcomponent.Builder
 public interface Builder{

AppSubComponent subComponent();
 }
 }

A few points to note here.

The subcomponent class is annotated with @SubComponent annotation

It uses NetworkApiModule to get NetworkApi instance

We inject that into our activity

And since we know that we can only inject if we create a connection from AppComponent into SubComponent, we create a builder interface.

We annotate the interface with @Subcomponent.Builder. These annotations are instruction to dagger to help it connect with main component.

We know that it is not the AppComponent but SubComponent that provides that value , we need to connect AppComponent to SubComponent and that is thru the method AppSubComponent subComponent();

Once we get the SubComponent, we know we now can provide network Api object to our Activity.

You can annotate provides method with Singleton if the object that you are supplying to the activity does not need to be recreated every time.

But if that is not the case , we can use something called as Scope.

Now Scope can be used to determine what can and cannot be used for an activity. So if an activity does not need networkApi then it should not be injectible at all. So by using scope we restrict what can be provided to object we are injecting into.

So we create a custom scope ( you can have any name )


@Scope
 @Retention(RetentionPolicy.RUNTIME)
 public @interface CustomScope {
 }

And assign this scope to the activity



@CustomScope
 public class MainActivity extends AppCompatActivity {

@Inject
 NetworkApi networkApi;

@Override
 protected void onCreate(Bundle savedInstanceState) {

<br data-mce-bogus="1">

And also to subcomponent


@CustomScope
 @Subcomponent(modules = {NetworkApiModule.class})
 public interface AppSubComponent {

<br data-mce-bogus=”1″>

Now we have completed the connection (except for actual injection into activity)&nbsp; . Let us compile the program ( Build -&gt; Rebuild Project) .

If you look up at what has been created you can see that a Dagger Helper is created

DaggerAppComponent . IF you open the source code you will see that all the dependencies you created are part of the code .

Now we add a few things to CustomApplication and Activity classes to help inject the instantiated object into Activity.


public class CustomApplication extends Application {

AppSubComponent appSubComponent = createSubComponent();

protected AppSubComponent createSubComponent() {
 return DaggerAppComponent.builder().build().subComponentBuilder().subComponent();
 }

@Override
 public void onCreate() {
 super.onCreate();

}

public AppSubComponent getAppSubComponent() {
 return appSubComponent;
 }
 }

There are two important points

Create Subcomopnent only once and return it

Use generated DaggerAppComponent and build the subcomponent. The last call will chain with inject.

And in activity inject this like


@CustomScope
 public class MainActivity extends AppCompatActivity {

@Inject
 NetworkApi networkApi;

@Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);

((CustomApplication)getApplication()).getAppSubComponent().inject(this);

}
 }

The network api object will now be injected into activity successfully.

In the next part of this tutorial, let us mock the subcomponent

Making mocks easier to write

Though my association with Java is quite long back ( since 1999), I recently stated working on creating Android Applications .

One of the important part of software development is that the code should be testable in Unit. That means mock out whatever is external to the code and just check whether the call to methods behaves in expected ways .

In Mockito I used to mock the members with a method


NetworkApi networkApiMock = Mockito.mock(NetworkApi.class);


when you import static mock method mock by doing this



import static org.mockito.Mockito.mock;

Yet better way is when you can do things like


@Mock
 NetworkApi networkApiMock;

This will work when the class under test is annotated with


@RunWith(MockitoJUnitRunner.class)
 Class ClassUnderTest{

@Mock
 NetworkApi networkApiMock;

@Test
 public void testCase(){

when(networkApiMock.getUri()).thenReturn();

}

 

Quite handy and saves time 🙂

Keep your build.gradle updated by using this handy plugin

It is quite time consuming to search each library that we use in our build.gradle ( app ) file, for changes in version whenever author makes a change

There is a very handy plugin to help us out with it.

Though not very great in UI , it does perform its job. Just copy contents of build.gradle file and then paste in the left hand pane

Press that long ugly button at the bottom “Version Check”

And then check the magic

First this ,

Then this ,

Now you have the latest versions of all these libraries, go ahead and change them in build.gradle and re-compile.

Reminds me , I have to update my project build.gradle. See you bye

 

Disable Android studio plugins that you don’t use

I have found some performance improvements ( not measured though) in Android studio,  when I disable Android Studio Plugins that my project does not need .

Disable Android plugins
Disable plugins

For e.g. if you project does not need CVS integration, you can just goto File-> Settings->plugin and remove the checkbox from the CVS integration. That should definitely ease up load on Android studio .

Not saying that this will work for you as well, but what’s harm in trying it 🙂

 

The dreaded document.ready() function of jQuery

If you are like me , you would have learned a little bit of Javascript and then moved on to jQuery in order to complete your project.

jQuery does make life easy for person who does not want to be get bogged down in nuances of javascript and worry about cross-platform implementation and correctness but quickly want to start working on their web projects.

The first statement that one sees ( especially when one is not from javascript background ) is

$(document).ready(function() { } );

It is intimidating to the coders who like me were just getting into jQuery. Having never worked on front end coding, even the }); was like nightmare

But actually looking back it is quite simple to understand.

$ is for telling the browser that $(document) is the version of document object of javascript that is now decorated with many functions from jQuery.

ready function is one of them which tells the browser to execute the code contained in it. Ready tells when the HTML elements in documents are all loaded from the server.

so $(document).ready() is a function called on document jquery object.

Now anything that is to be done is inside it .


$(document).ready(function(){});

and inside the function, you can do whatever you want to


$(document).ready(function(){

alert("Document is ready");

});

You can also name the function as


var fn = function(){

alert("Document is ready");

};

and then call


$(document).ready(fn);

Doesn’t look intimidating now , is it ?