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 🙂

 

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 ?

base64_decode for image

In the blog post about using base64_encode for encoding an image , I talked about how to encode the image using base64 encode method of php.

In this post let us look at base 64 decoding function.

If you want to send an image using Ajax or from any other system, one of the ways is first encoding the image in base 64 mime type. This encoding can be done in any language ( php, javascript or java ) but it should result in the same string.

The data you would receive would start with

 

 

 

Using base_64encode for images

The primary problem of a developer is

How to send image from the front end to the back end server which is running on PHP.

So the process goes like this

1> Create a form in HTML to allow user to add an image


<form action ="imageLoader.php" method="post" encType ="multipart/form-data">

<input type ="file" name="myImage" />

<input type="submit" name="submit" />

</form>

The requirement is to display the file in another script.

In PHP script imageLoader.php

$_FILES will provide the file name which can be copied to another location and then read using file_get_contents()


$content = file_get_contents("myfile.png");

$base64String = base64_encode($content);

Based on the type type add

Then the base64String can be re-sent to the server using a script like this


header('Content-Type: application/json');

echo json_encode($base64String);

die();

Don’t forget to include die(); otherwise anything after the script will be sent as well

Breaking out of a loop

A loop can be defined as

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

for($i = 1; $i&lt;10;$i++){

// Do something

}

Let us consider that application logic dictates that when we $i ==5 , then we exit the loop


for($i = 1; $i<10;$i++){

// Do something

if($i == 5)

break;

}

We can apply the same thing in while


while($i<10)

{

if($i == 5)

break;

$i++;

}

It is better to put the break condition as

if(5==$i) because many a developers have been ruined by this

if ($i=5) ( missing “=” )

isset() vs empty()

isset() usage

Example 1:


$post['var'] = 100;

isset($post[‘var’]) will return true

Example 2:

isset($name) will return false if $name has not been declared

Example 3:

$post['v1'] = 100;

isset($post[‘v2’]) will return false

since isset is not assigned

empty()

It essentially means

!isset($var) || $var == false.

So it is either is not set or it is set but its value is false

Example 1


$post['v1'] = 100;

empty($post[‘v1’]) is false

Example 2


$post['v2'] = false

empty($post[‘v2’])  is true

Example 3

empty($post[‘v3’]) is true because $post[‘v3] has not been declared