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
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
Run the coverage
Run Code Coverage
You see this window
You see the coverage
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
If the colors are too light for your eyes you can always darken them by clicking on the red bar
Now if we use a UI testing frameworks for e.g. espresso, we know that we
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;lt;br data-mce-bogus="1"&amp;amp;amp;gt;
&amp;amp;amp;lt;pre&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;lt;MainActivity&amp;amp;amp;amp;gt; activityRule = new ActivityTestRule&amp;amp;amp;amp;lt;&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;lt;/pre&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 {
@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.
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 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) . Let us compile the program ( Build -> 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.
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();
}
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 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 ๐
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");
};